1 2 /** 3 * Tencent is pleased to support the open source community by making MSEC available. 4 * 5 * Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved. 6 * 7 * Licensed under the GNU General Public License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. You may 9 * obtain a copy of the License at 10 * 11 * https://opensource.org/licenses/GPL-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software distributed under the 14 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 15 * either express or implied. See the License for the specific language governing permissions 16 * and limitations under the License. 17 */ 18 19 20 /** 21 * @filename heap.h 22 * @info ������ɾ���Ķ�, �����û�����ɾ������, ������std::make_heap 23 * @time 2013-06-11 24 */ 25 26 #ifndef __HEAP_ENTRY_FILE__ 27 #define __HEAP_ENTRY_FILE__ 28 29 #include <stdlib.h> 30 #include <stdio.h> 31 #include <string.h> 32 #include <assert.h> 33 34 #define heap_assert(statement) 35 //#define heap_assert(statement) assert(statement) 36 37 namespace NS_MICRO_THREAD { 38 39 class HeapEntry; // ��Ԫ����, �̳�ʵ����չ 40 class HeapList; // �ѹ�����, ͨ�� 41 42 /** 43 * @brief ��С�ѵĶ�Ԫ�ض���, ���ڹ���ͨ�õĶ�, �̳и�Ԫ�ؼ�����չ 44 */ 45 class HeapEntry 46 { 47 private: 48 int _index; ///< ��Ԫ���±�, ���ڿ�������ɾ������ 49 50 public: 51 friend class HeapList; 52 53 /** 54 * @brief ���������������� 55 */ 56 HeapEntry():_index(0){}; 57 virtual ~HeapEntry(){}; 58 59 /** 60 * @brief ��Ԫ��ȡֵ����, ���ڷ���ֵ�Ƚ�, ���Ӻ���ʵ��, ����Ĭ������ 61 * @return ��Ԫ��ӳ���ֵ 62 */ 63 virtual unsigned long long HeapValue() = 0; 64 65 66 /** 67 * @brief �ѱ����ӿ�, ���ڵ���, �ڱ���ÿ��Ԫ��ʱ������, ��ѡʵ�� 68 */ 69 virtual void HeapIterate() { 70 return; 71 }; 72 73 /** 74 * @brief ��Ԫ�ز������ 75 * @param list ��ָ�� 76 * @return 0 �ɹ�; ����ʧ�� -1 ����; -2 �ظ����� 77 */ 78 inline int InsertIntoHeap(HeapList* list); 79 80 /** 81 * @brief ��Ԫ�شӶ���ɾ�� 82 * @param list ��ָ�� 83 * @return 0 �ɹ�; ����ʧ�� -1 �ѿ�; -2 �ظ�ɾ���������� 84 */ 85 inline int DeleteFromHeap(HeapList* list); 86 87 88 /** 89 * @brief ��Ԫ���±���Ϣ��ȡ, �ڲ�����ʹ�� 90 * @return ��Ԫ���ڶ����±���Ϣ 91 */ 92 inline int GetIndex() { 93 return _index; 94 }; 95 96 private: 97 98 inline int HeapValueCmp(HeapEntry* rhs) { 99 if (this->HeapValue() == rhs->HeapValue()) { 100 return 0; 101 } else if (this->HeapValue() > rhs->HeapValue()) { 102 return 1; 103 } else { 104 return -1; 105 } 106 }; 107 108 inline void SetIndex(int index) { 109 _index = index; 110 }; 111 112 113 }; 114 115 116 /** 117 * @brief ��С�Ѷ�����, ͨ���� 118 */ 119 class HeapList 120 { 121 private: 122 HeapEntry** _list; // ��Ԫ�ص�ָ������, Ŀǰ���� 123 int _max; // �ѿɹ������Ԫ�ظ��� 124 int _count; // ���Ѿ������Ԫ�ظ��� 125 126 public: 127 128 /** 129 * @brief ���캯������������ 130 */ 131 explicit HeapList(int max = 100000) { 132 _max = (max > 0) ? max : 100000; 133 _list = (HeapEntry**)malloc (sizeof(HeapEntry*) * (_max+1)); 134 heap_assert(_list); 135 memset(_list, 0, sizeof(HeapEntry*) * (_max+1)); 136 _count = 0; 137 }; 138 virtual ~HeapList() { 139 if (_list) { 140 free(_list); 141 _list = NULL; 142 } 143 _max = 0; 144 _count = 0; 145 }; 146 147 /** 148 * @brief ��չheap�Ĵ�С, ��С����� 149 * @param size �µĶ�Ԫ�ظ��� 150 * @return 0 �ɹ�; -1 ʧ�� 151 */ 152 int HeapResize(int size) { 153 if (_max >= size) { 154 return 0; 155 } 156 157 HeapEntry** new_list = (HeapEntry**)malloc(sizeof(HeapEntry*) * (size+1)); 158 if (NULL == new_list) { 159 return -1; 160 } 161 memset(new_list, 0, sizeof(HeapEntry*) * (size+1)); 162 memcpy(new_list, _list, sizeof(HeapEntry*) * (_max+1)); 163 free(_list); 164 _list = new_list; 165 _max = size; 166 167 return 0; 168 }; 169 170 171 /** 172 * @brief �����Ԫ�� 173 * @param entry ��Ԫ��ָ�� 174 * @return 0 �ɹ�; ����ʧ�� -1 ����; -2 �ظ����� 175 */ 176 int HeapPush(HeapEntry* entry); 177 178 /** 179 * @brief ȡ�Ѷ�Ԫ��, ���Ƴ���Ԫ�� 180 * @return �Ѷ�Ԫ��ָ��, NULL ��ʾ��Ϊ�� 181 */ 182 HeapEntry* HeapPop(); 183 184 /** 185 * @brief �Ƴ������Ԫ�� 186 * @param entry ��Ԫ��ָ�� 187 * @return 0 �ɹ�; ����ʧ�� -1 �ѿ�; -2 �ظ�ɾ���������� 188 */ 189 int HeapDelete(HeapEntry* entry); 190 191 /** 192 * @brief ���Խӿ�, ��2��ѷ�ʽ��ӡԪ��, ͬʱ����ÿԪ�صĵ����ӿ� 193 */ 194 void HeapForeach(); 195 196 /** 197 * @brief ��ȡ�ѵ�Ԫ�ظ��� 198 * @return ��Ԫ��ʵ����Ŀ 199 */ 200 int HeapSize() { 201 return _count; 202 }; 203 204 /** 205 * @brief ȡ�Ѷ�Ԫ��, ���Ƴ���Ԫ�� 206 * @return �Ѷ�Ԫ��ָ��, NULL ��ʾ��Ϊ�� 207 */ 208 HeapEntry* HeapTop() { 209 return (_count > 0) ? _list[1] : NULL; 210 }; 211 212 private: 213 214 /** 215 * @brief �ж����Ƿ��� 216 * @return true �� 217 */ 218 bool HeapFull() { 219 return (_count >= _max); 220 }; 221 222 /** 223 * @brief �ж����Ƿ�� 224 * @return true �� 225 */ 226 bool HeapEmpty() { 227 return (_count == 0); 228 }; 229 230 /** 231 * @brief ���ȽϺ���, �������Ŷ�Ԫ�� 232 */ 233 void HeapUp(); 234 235 /** 236 * @brief ���ȽϺ���, �������Ŷ�Ԫ�� 237 */ 238 void HeapDown(int index); 239 240 }; 241 242 /** 243 * @brief ���ȽϺ���, �������Ŷ�Ԫ�� 244 */ 245 inline void HeapList::HeapUp() 246 { 247 for (int pos = _count; pos > 0; pos = pos/2) 248 { 249 if (pos/2 < 1) // pos == 1 �Ѿ�����, 0 ���ڱ��� 250 { 251 break; 252 } 253 254 if (_list[pos]->HeapValueCmp(_list[pos/2]) < 0) 255 { 256 HeapEntry* tmp = _list[pos/2]; 257 _list[pos/2] = _list[pos]; 258 _list[pos] = tmp; 259 260 _list[pos]->SetIndex(pos); 261 _list[pos/2]->SetIndex(pos/2); 262 } 263 else 264 { 265 break; 266 } 267 } 268 } 269 270 271 /** 272 * @brief ���ȽϺ���, �������Ŷ�Ԫ�� 273 * @param index �Ӹ�λ�ÿ�ʼ���� 274 */ 275 inline void HeapList::HeapDown(int index) 276 { 277 int min_son; 278 for (int pos = index; pos <= _count; pos = min_son) 279 { 280 if (pos*2 > _count) // pos��Ҷ�ӽڵ��� 281 { 282 break; 283 } 284 else if (pos*2 == _count) 285 { 286 min_son = pos*2; 287 } 288 else 289 { 290 if (_list[pos*2+1]->HeapValueCmp(_list[pos*2]) < 0) 291 { 292 min_son = pos*2+1; 293 } 294 else 295 { 296 min_son = pos*2; 297 } 298 } 299 300 if (_list[pos]->HeapValueCmp(_list[min_son]) > 0) 301 { 302 HeapEntry* tmp = _list[min_son]; 303 _list[min_son] = _list[pos]; 304 _list[pos] = tmp; 305 306 _list[pos]->SetIndex(pos); 307 _list[min_son]->SetIndex(min_son); 308 } 309 else 310 { 311 break; 312 } 313 } 314 } 315 316 317 /** 318 * @brief �����Ԫ�� 319 * @param entry ��Ԫ��ָ�� 320 * @return 0 �ɹ�; ����ʧ�� -1 ����; -2 �ظ����� 321 */ 322 inline int HeapList::HeapPush(HeapEntry* item) 323 { 324 if (HeapFull()) { 325 heap_assert(0); // ��, �������ǿ��ܵ�, ʵ�����в�̫���ܹ�10W 326 return -1; 327 } 328 329 if (item->GetIndex() != 0) { 330 heap_assert(0); // �ظ����� 331 return -2; 332 } 333 334 _count++; 335 _list[_count] = item; 336 item->SetIndex(_count); 337 338 HeapUp(); 339 340 return 0; 341 } 342 343 344 /** 345 * @brief ȡ�Ѷ�Ԫ��, ���Ƴ���Ԫ�� 346 * @return �Ѷ�Ԫ��ָ��, NULL ��ʾ��Ϊ�� 347 */ 348 inline HeapEntry* HeapList::HeapPop() 349 { 350 if (HeapEmpty()) { 351 return NULL; 352 } 353 354 HeapEntry* top = _list[1]; // 0 ���� 355 356 _list[1] = _list[_count]; 357 _list[1]->SetIndex(1); 358 _list[_count] = 0; 359 360 _count--; 361 HeapDown(1); 362 363 heap_assert(top->GetIndex() == 1); 364 top->SetIndex(0); 365 return top; 366 } 367 368 /** 369 * @brief �Ƴ������Ԫ�� 370 * @param entry ��Ԫ��ָ�� 371 * @return 0 �ɹ�; ����ʧ�� -1 �ѿ�; -2 �ظ�ɾ���������� 372 */ 373 inline int HeapList::HeapDelete(HeapEntry* item) 374 { 375 if (HeapEmpty()) { 376 return -1; 377 } 378 379 int pos = item->GetIndex() ; 380 if ((pos > _count) ||(pos <= 0)) 381 { 382 heap_assert(0); // �Ƿ����ݻ��ظ�ɾ�� 383 return -2; 384 } 385 386 HeapEntry* del = _list[pos]; 387 _list[pos] = _list[_count]; 388 _list[pos]->SetIndex(pos); 389 390 _list[_count] = 0; 391 _count--; 392 393 HeapDown(pos); 394 heap_assert(pos == del->GetIndex()); 395 del->SetIndex(0); 396 return 0; 397 } 398 399 400 /** 401 * @brief ���Խӿ�, ��2��ѷ�ʽ��ӡԪ��, ͬʱ����ÿԪ�صĵ����ӿ� 402 */ 403 inline void HeapList::HeapForeach() 404 { 405 int per = 1; 406 for (int i = 1; i <= _count; i++) 407 { 408 if (i >= per*2) 409 { 410 printf("\n"); 411 per *=2; 412 } 413 printf("%llu ", _list[i]->HeapValue()); 414 415 _list[i]->HeapIterate(); 416 } 417 } 418 419 /** 420 * @brief ��Ԫ�ز������ 421 * @param list ��ָ�� 422 * @return 0 �ɹ�; ����ʧ�� -1 ����; -2 �ظ����� 423 */ 424 inline int HeapEntry::InsertIntoHeap(HeapList* list) { 425 return list->HeapPush(this); 426 }; 427 428 /** 429 * @brief ��Ԫ�شӶ���ɾ�� 430 * @param list ��ָ�� 431 * @return 0 �ɹ�; ����ʧ�� -1 �ѿ�; -2 �ظ�ɾ���������� 432 */ 433 inline int HeapEntry::DeleteFromHeap(HeapList* list) { 434 return list->HeapDelete(this); 435 }; 436 437 } // namespace end 438 439 #endif 440 441 442