資料結構與演算法——堆 特點與演算法實現(二)
阿新 • • 發佈:2020-10-20
1. 堆的演算法實現
堆資料結構的定義
1 #define DEFAULT_CAPCITY 128 2 3 typedef struct _Heap 4 { 5 int *arr; //儲存堆元素的陣列 6 int size; //當前已儲存的元素個數 7 int capacity; //當前儲存的容量 8 }Heap;
建(最大)堆
1 bool initHeap(Heap &heap, int *orginal, int size); 2 static void buildHeap(Heap &heap); 3 static void adjustDown(Heap &heap, intindex); 4 5 /*初始化堆*/ 6 bool initHeap(Heap &heap, int *orginal, int size) 7 { 8 int capacity = DEFAULT_CAPCITY>size? DEFAULT_CAPCITY:size; 9 10 heap.arr = new int[capacity]; 11 if(!heap.arr) return false; 12 13 heap.capacity = capacity; 14 heap.size = 0; 15 16 //如果存在原始資料則構建堆17 if(size>0) 18 { 19 memcpy(heap.arr, orginal, size*sizeof(int)); 20 heap.size = size; 21 buildHeap(heap); 22 } 23 else 24 { 25 heap.size = 0; 26 } 27 return true; 28 } 29 30 /*將當前的節點和子節點調整成最大堆*/ 31 void adjustDown(Heap &heap, int index)32 { 33 int cur=heap.arr[index]; //當前待調整的節點 34 int parent,child; 35 36 /*判斷否存在大於當前節點子節點,如果不存在 ,則堆本身是平衡的,不需要調整; 37 如果存在,則將最大的子節點與之交換,交換後,如果這個子節點還有子節點, 38 則要繼續按照同樣的步驟對這個子節點進行調整*/ 39 for(parent=index; (parent*2+1)<heap.size; parent=child) 40 { 41 child=parent*2+1; 42 //取兩個子節點中的最大的節點 43 if(((child+1)<heap.size)&&(heap.arr[child]<heap.arr[child+1])) 44 { 45 child++; 46 } 47 //判斷最大的節點是否大於當前的父節點 48 if(cur>=heap.arr[child]) 49 { 50 //不大於,則不需要調整,跳出迴圈 51 break; 52 } 53 else 54 { 55 //大於當前的父節點,進行交換,然後從子節點位置繼續向下調整 56 heap.arr[parent]=heap.arr[child]; 57 heap.arr[child]=cur; 58 } 59 } 60 } 61 62 /* 從最後一個父節點(size/2-1 的位置)逐個往前調整所有父節點(直到根節點), 63 確保每一個父節點都是一個最大堆,最後整體上形成一個最大堆 */ 64 void buildHeap(Heap &heap) 65 { 66 int i; 67 for(i=heap.size/2-1; i>=0; i--) 68 { 69 adjustDown(heap, i); 70 } 71 }