|  | 
				
					
	
		
			
 			Posted on 2010-05-02 20:39 Current  阅读(1509) 评论(0)  编辑 收藏 引用   所属分类: Wild Magic 引擎解析   最大堆和最小堆是二叉堆的两种形式。 
    最大堆:根结点的键值是所有堆结点键值中最大者的堆。
    最小堆:根结点的键值是所有堆结点键值中最小者的堆。  而最大-最小堆集结了最大堆和最小堆的优点,这也是其名字的由来。 最大-最小堆是最大层和最小层交替出现的二叉树,即最大层结点的儿子属于最小层,最小层结点的儿子属于最大层。 以最大(小)层结n点为根结点的子树保有最大(小)堆性质:根结点的键值为该子树结点键值中最大(小)项。 
最大堆:   最小堆:  最小堆实现:
  1 #ifndef _TMINHEAP_HPP_ 2
  #define _TMINHEAP_HPP_ 3
  4
  #include "System.hpp" 5
  6
  namespace PX2 7
    { 8
   /**//// 最小堆 9
   /**//* 10
  *  应用二叉树实现最小堆 11
  */ 12
  template <typename Generator, typename Real> class TMinHeap; 13
  14
  template <typename Generator, typename Real> 15
  class TMinHeapRecord 16
     { 17
  public: 18
  TMinHeapRecord (); 19
  ~TMinHeapRecord (); 20
  21
  Generator GetGenerator () const; 22
  Real GetValue () const; 23
  24
  private: 25
  friend class TMinHeap<Generator, Real>; 26
   27
  Generator m_tGenerator; 28
  Real m_fValue; 29
  int m_iIndex; 30
  }; 31
  32
  template <typename Generator, typename Real> 33
  class TMinHeap 34
     { 35
  TMinHeap ( int iMaxQuantity, int iGrowBy ); 36
  ~TMinHeap (); 37
  38
  int GetMaxQuantity () const; 39
  int GetGrowBy () const; 40
  int GetQuantity () const; 41
  const TMinHeapRecord<Generator,Real>* GetRecord ( int i ) const; 42
  43
  const TMinHeapRecord<Generator,Real>* Insert (Generator tGenerator, 44
  Real fValue); 45
  46
  void Remove (Generator& rtGenerator, Real& rfValue); 47
  48
  void Update (const TMinHeapRecord<Generator,Real>* pkConstRecord, 49
  Real fValue); 50
  51
  bool IsValid (int iStart, int iFinal); 52
  bool IsValid (); 53
  void Print (const char* acFilename); 54
  55
  private: 56
  int m_iMaxQuantity, m_iGrowBy, m_iQuantity; 57
  TMinHeapRecord<Generator,Real>* m_akRecords; 58
  59
  TMinHeapRecord<Generator,Real>** m_apkRecords; 60
  }; 61
  62
  #include "TMinHeap.inl" 63
  } 64
  #endif//_TMINHEAP_HPP_   1 //---------------------------------------------------------------------------- 2
  template <typename Generator, typename Real> 3
  TMinHeapRecord<Generator,Real> ::TMinHeapRecord () 4
    { 5
  } 6
  //---------------------------------------------------------------------------- 7
  template <typename Generator, typename Real> 8
  TMinHeapRecord<Generator,Real> ::~TMinHeapRecord () 9
    { 10
  } 11
  //---------------------------------------------------------------------------- 12
  template <typename Generator, typename Real> 13
  Generator TMinHeapRecord<Generator,Real> ::GetGenerator () const 14
    { 15
  return m_tGenerator; 16
  } 17
  //---------------------------------------------------------------------------- 18
  template <typename Generator, typename Real> 19
  Real TMinHeapRecord<Generator,Real> ::GetValue () const 20
    { 21
  return m_fValue; 22
  } 23
  //---------------------------------------------------------------------------- 24
  //------------------------------------------------------------------------------- 25
  template <typename Generator, typename Real> 26
  TMinHeap<Generator, Real> ::TMinHeap( int iMaxQuantity, int iGrowBy ) 27
    { 28
  assert( iMaxQuantity > 0 && iGrowBy > 0); 29
  m_iMaxQuantity = iMaxQuantity; 30
  m_iGrowBy = iGrowBy; 31
  m_iQuantity = 0; 32
  m_akRecords = NEW TMinHeapRecord<Generator, Real>[m_iMaxQuantity]; 33
  m_apkRecords = NEW TMinHeapRecord<Generator, Real>*[m_iMaxQuantity]; 34
  35
  for (int i = 0; i < m_iMaxQuantity; ++i) 36
     { 37
  m_apkRecords[i] = &m_akRecords[i]; 38
  m_apkRecords[i]->m_iIndex = i; 39
  } 40
  } 41
  //------------------------------------------------------------------------------- 42
  template <typename Generator, typename Real> 43
  TMinHeap<Generator, Real> ::~TMinHeap() 44
    { 45
  DELETE [] m_akRecords; 46
  DELETE [] m_apkRecords; 47
  } 48
  //------------------------------------------------------------------------------- 49
  template <typename Generator, typename Real> 50
  int TMinHeap<Generator, Real> ::GetMaxQuantity() const 51
    { 52
  return m_iMaxQuantity; 53
  } 54
  //------------------------------------------------------------------------------- 55
  template <typename Generator, typename Real> 56
  int TMinHeap<Generator, Real> ::GetGrowBy() const 57
    { 58
  return m_iGrowBy; 59
  } 60
  //------------------------------------------------------------------------------- 61
  template <typename Generator, typename Real> 62
  int TMinHeap<Generator, Real> ::GetQuantity() 63
    { 64
  return m_iQuantity; 65
  } 66
  //------------------------------------------------------------------------------- 67
  template <typename Generator, typename Real> 68
  const TMinHeapRecord<Generator, Real>* TMinHeap<Generator, Real> 69
  ::GetRecord ( int i ) const 70
    { 71
  if ( 0 <= i && i < m_iQuantity ) 72
     { 73
  return m_apkRecords[i]; 74
  } 75
  76
  return 0; 77
  } 78
  //------------------------------------------------------------------------------- 79
  template <typename Generator, typename Real> 80
  const TMinHeapRecord<Generator,Real>* TMinHeap<Generator,Real> 81
  ::Insert ( Generator tGenerator, Real fValue ) 82
    { 83
  if ( m_iQuantity == m_iMaxQuantity ) 84
     { 85
  int iNewQuantity = m_iMaxQuantity + m_iGrowBy; 86
  87
  TMinHeapRecord<Generator,Real>* akNewRecords = 88
  NEW TMinHeapRecord<Generator,Real>[iNewQuantity]; 89
  90
  TMinHeapRecord<Generator,Real>** apkNewRecords = 91
  NEW TMinHeapRecord<Generator,Real>*[iNewQuantity]; 92
  93
  size_t uiSize = m_iMaxQuantity*sizeof(TMinHeapRecord<Generator,Real>); 94
  memcpy(akNewRecords, m_akRecords, uiSize); 95
  96
  int i; 97
  for (i = 0; i < m_iMaxQuantity; i++) 98
     { 99
  int iByteOffset = (int)(m_apkRecords[i] - m_akRecords); 100
  apkNewRecords[i] = (TMinHeapRecord<Generator,Real>*) 101
  ( ((char*)akNewRecords) + iByteOffset); 102
  apkNewRecords[i]->m_iIndex = i; 103
  } 104
  105
  for (i = m_iMaxQuantity; i < iNewQuantity; i++) 106
     { 107
  apkNewRecords[i] = &akNewRecords[i]; 108
  apkNewRecords[i]->m_iIndex = i; 109
  } 110
  111
  DELETE[] m_akRecords; 112
  DELETE[] m_apkRecords; 113
  m_iMaxQuantity = iNewQuantity; 114
  m_akRecords = akNewRecords; 115
  m_apkRecords = apkNewRecords; 116
  } 117
  118
  int iChild = m_iQuantity++; 119
  TMinHeapRecord<Generator, Real>* pkRecord = m_apkRecords[iChild]; 120
  pkRecord->m_tGenerator = tGenerator; 121
  pkRecord.m_fValue = fValue; 122
  123
  while (iChild > 0) 124
     { 125
  int iParent = ( iChild - 1) / 2; 126
  if (m_apkRecords[iParent].m_fValue <= fValue) 127
     { 128
  break; 129
  } 130
  131
  m_apkRecords[iChild] = m_apkRecords[iParent]; 132
  m_apkRecords[iChild].m_iIndex = iChild; 133
  134
  m_apkRecords[iParent] = pkRecord; 135
  m_apkRecords[iParent].m_iIndex = iParent; 136
  137
  iChild = iParent; 138
  } 139
  140
  return m_apkRecords[iChild]; 141
  } 142
  //------------------------------------------------------------------------------- 143
  template <typename Generator, typename Real> 144
  void TMinHeap<Generator, Real> ::Remove(Generator& rtGenerator, Real& rfValue) 145
    { 146
  TMinHeapRecord<Generator, Real>* pkRoot = m_apkRecords[0]; 147
  rtGenerator = pkRoot->m_tGenerator; 148
  rfValue = pkRoot->m_fValue; 149
  150
  int iLast = --m_iQuantity; 151
  TMinHeapRecord<Generator, Real>* pkRecord = m_apkRecords[iLast]; 152
  int iParent = 0, iChild = 1; 153
  while (iChild <= iLast ) 154
     { 155
  if (iChild < iLast ) 156
     { 157
  int iChildP1 = iChild + 1; 158
  if (m_apkRecords[iChild]->m_fValue > 159
  m_apkRecords[iChildP1]->m_fValue) 160
     { 161
  iChild = iChildP1; 162
  } 163
  } 164
  165
  if (m_apkRecords[iChild]->m_fValue >= pkRecord->m_fValue) 166
     { 167
  break; 168
  } 169
  170
  m_apkRecords[iParent] = m_apkRecords[iChild]; 171
  m_apkRecords[iParent]->m_iIndex = iParent; 172
  173
  iParent = iChild; 174
  iChild = 2*iChild + 1; 175
  } 176
  m_apkRecords[iParent] = pkRecord; 177
  m_apkRecords[iParent]->m_iIndex = iParent; 178
  179
  m_apkRecords[iLast] = pkRoot; 180
  m_apkRecords[iLast]->m_iIndex = iLast; 181
  } 182
  //------------------------------------------------------------------------------- 183
  template <typename Generator, typename Real> 184
  void TMinHeap<Generator, Real> ::Update( 185
  const TMinHeapRecord<Generator,Real>* pkConstRecord, Real fValue) 186
  187
    { 188
  TMinHeapRecord<Generator, Real>* pkRecord = 189
  (TMinHeapRecord<Generator, Real>*) pkConstRecord; 190
  191
  int iParent, iChild, iChildp1, iMaxChild; 192
  193
  if (fValue > pkRecord->m_fValue ) 194
     { 195
  pkRecord->m_fValue = fValue; 196
  197
  iParent = pkRecord->m_iIndex; 198
  iChild = 2* iParent + 1; 199
  while( iChild < m_iQuantity) 200
     { 201
  if (iChild < m_iQuantity -1) 202
     { 203
  iChildp1 = iChild + 1; 204
  if (m_apkRecords[iChild]->m_fValue <= 205
  m_apkRecords[iChildp1]->m_fValue ) 206
     { 207
  iMaxChild = iChild; 208
  } 209
  else 210
     { 211
  iMaxChild = iChildp1; 212
  } 213
  } 214
  else 215
     { 216
  iMaxChild = iChild; 217
  } 218
  219
  if (m_apkRecords[iMaxChild]->m_fValue >= fValue ) 220
     { 221
  break; 222
  } 223
  224
  m_apkRecords[iParent] = m_apkRecords[iMaxChild]; 225
  m_apkRecords[iParent]->m_iIndex = iParent; 226
  227
  m_apkRecords[iMaxChild] = pkRecord; 228
  m_apkRecords[iMaxChild]->m_iIndex = iMaxChild; 229
  230
  iParent = iMaxChild; 231
  232
  iChild = 2* iParent + 1; 233
  } 234
  } 235
  else  if (fValue < pkRecord->m_fValue) 236
     { 237
  pkRecord->m_fValue = fValue; 238
  239
  iChild = pkRecord->m_iIndex; 240
  241
  while( iChild > 0) 242
     { 243
  iParent = (iChild -1) /2; 244
  if (m_apkRecords[iParent]->m_fValue <= fValue) 245
     { 246
  break; 247
  } 248
  249
  m_apkRecords[iChild] = m_apkRecords[iParent]; 250
  m_apkRecords[iChild]->m_iIndex = iChild; 251
  252
  m_apkRecords[iParent] = pkRecord; 253
  m_apkRecords[iParent]->m_iIndex = iParent; 254
  255
  iChild = iParent; 256
  } 257
  } 258
  } 259
  //------------------------------------------------------------------------------- 260
  template <typename Generator, typename Real> 261
  bool TMinHeap<Generator, Real> ::IsValid( int iStart, int iFinal) 262
    { 263
  for ( int iChild = iStart; iChild <= iFinal; ++iChild) 264
     { 265
  int iParent = (iChild - 1)/2; 266
  if (iParent > iStart) 267
     { 268
  if (m_apkRecords[iParent]->m_fValue > 269
  m_apkRecords[iChild]->m_fValue ) 270
     { 271
  return false; 272
  } 273
  274
  if (m_apkRecords[iParent]->m_iIndex != iParent) 275
     { 276
  return false; 277
  } 278
  } 279
  } 280
  281
  return true; 282
  } 283
  //------------------------------------------------------------------------------- 284
  template <typename Generator, typename Real> 285
  bool TMinHeap<Generator,Real> ::IsValid () 286
    { 287
  return IsValid(0, m_iQuantity-1); 288
  } 289
  //------------------------------------------------------------------------------- 290
  template <typename Generator, typename Real> 291
  void TMinHeap<Generator,Real> ::Print (const char* acFilename) 292
    { 293
  std::ofstream kOStr(acFilename); 294
  for (int i = 0; i < m_iQuantity; i++) 295
     { 296
  TMinHeapRecord<Generator,Real>* pkRecord = m_apkRecords[i]; 297
  kOStr << pkRecord->m_iIndex << ": gen = " << pkRecord->m_tGenerator 298
  << " , val = " << pkRecord->m_fValue << std::endl; 299
  } 300
  kOStr.close(); 301
  } 302
  //---------------------------------------------------------------------------- 303
  304
  // end 
	    
    
 |