最大堆(優先隊列)基本概念,即一個完整建立,插入,刪除代碼


堆(優先隊列)priority queue
特殊的隊列,取出元素的順序是依照元素的優先權(關鍵字)大小,而出元素進入隊列的先后順序
操作:查找最大值(最小值),刪除(最大值)

數組:
鏈表:
有序數組:
有序鏈表:

采用二叉搜索樹? NO

采用完全二叉樹 YES
堆的連個特性
結構性:用數組表示的完全二叉樹:
有序性:任一結點的關鍵字是其字樹所有結點的最大值(或最小值)
最大堆(MaxHeap)也稱大頂堆:最大值
最小堆(MinHeap)也稱“小頂堆”:最小值
從根節點到任意結點路徑上結點序列的有序性
操作:插入任意一個元素,刪除最 大值元素
最大堆的刪除:取出根節點(最大值)元素,同時刪除堆的一個結點

最大堆的建立:將已存在的N個元素按最大堆的要求存放在一個以為數組中

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 //最大堆
 4 
 5 #define MaxData 1000        //哨兵,該值應該根據具體情況定義為大於堆中所有可能元素的值
 6 
 7 typedef int ElementType;  8 
 9 typedef struct HeapNode * MaxHeap; 10 struct HeapNode { 11     int Capacity;            //堆的最大容量
12     int Size;                //堆中當前元素個數
13     ElementType *Data;    //用於存儲元素的數組
14 };

建一個空的最大堆:

 1 //建立一個空的最大堆
 2 MaxHeap InitHeap(int maxsize)  3 {  4     MaxHeap H = (MaxHeap)malloc(sizeof(struct HeapNode));  5     H->Data = (ElementType*)malloc(sizeof(struct HeapNode) * (maxsize + 1));        //堆中的元素是從下標為1開始存儲的,但是為了保證這個堆能存下maxsize個元素,所以要分配maxsize + 1個內存單元
 6     H->Capacity = maxsize;  7     H->Size = 0;  8     H->Data[0] = MaxData;            //將0下標的單元存儲哨兵
 9     for (int i = 1; i < maxsize + 1; i++) 10         H->Data[i] = 0; 11     return H; 12 }

判斷堆是否已滿或是否為空:

 1 int IsEmpty(MaxHeap H)  2 {  3     return H->Size == 0;  4 }  5 
 6 //判斷堆是否已滿
 7 int IsFull(MaxHeap H)  8 {  9     return H->Size == H->Capacity; 10 }

插入一個元素:

 1 //最大堆中插入一個元素
 2 void Insert(MaxHeap H, ElementType item)  3 {  4     int i;  5     if (IsFull(H))  6  {  7         printf("The heap is full\n");  8         return;  9  } 10     i = ++H->Size;        //i為插入后堆中最后一個元素的位置
11     for (; H->Data[i / 2] < item; i /= 2) 12         H->Data[i] = H->Data[i / 2];        //循環退出時,父節點的數據已經大於item, item已經找到了正確的位置
13     H->Data[i] = item;    //將item賦給正確的下標單元
14 }

刪除一個元素:

 1 ElementType Delete(MaxHeap H)  2 {  3  ElementType temp, Max;  4     int parent = 1, child;  5     if (IsEmpty(H))  6  {  7         printf("The heap is empty!\n");  8         return 0;  9  } 10     Max = H->Data[1];            //現將最大值即根節點的值記錄下來
11     temp = H->Data[H->Size--];        //用最后的結點元素暫時代替根節點的數據,然后將堆的數據大小減1 12 
13     //如果2 * parent > 0,那么說明parent已經是根節點了
14     for (; 2 * parent <= H->Size; parent = child) 15  { 16         child = 2 * parent; 17 
18         //如果Child != H->Size說明child不是最后一個結點,該parent結點還有右節點, 19         //並且如果右節點的值大於左結點,那么child++;
20         if (child != H->Size && (H->Data[child + 1] < H->Data[child])) 21             child++;        //child指向左右子節點的較大者
22         if (temp > H->Data[child]) break;            //如果孩子結點已經小於temp了, 說明找到了合適的位置
23         else
24             H->Data[parent] = H->Data[child]; 25  } 26     H->Data[parent] = temp; 27     return Max; 28 }

最大堆的建立:

1.第一步,將N個元素按輸入順序存入二叉樹中,這一步需要求滿足完全二叉樹的結構特性,而不管其有序性

2.從最后一個右孩子的結點開始調整,做類似刪除元素時的下濾操作,逐個結點調整,直至根節點

 1 //創建一個最大堆
 2 MaxHeap CreateMaxHeap()  3 {  4     int dt, i = 0, j;  5     int parent, child;  6  ElementType X;  7     MaxHeap H = InitHeap(20);        //先創建一個空的最大堆,然后往里面填充元素
 8     while (scanf_s("%d", &dt) != EOF)  9  { 10         H->Data[i + 1] = dt; 11         i++; 12         H->Size++; 13  } 14     for (j = i / 2; j >= 1; j--)        //從i / 2開始逐一向下過濾
15  { 16         //下面的操作和刪除元素是一模一樣的,只是不用將的元素個數減一
17         X = H->Data[j]; 18         for (parent = j; 2 * parent <= H->Size; parent = child) 19  { 20             child = 2 * parent; 21             if (child != H->Size && H->Data[child] < H->Data[child + 1]) 22                 child++; 23             if (H->Data[child] < X) 24                 break; 25             else
26                 H->Data[parent] = H->Data[child]; 27  } 28         H->Data[parent] = X; 29  } 30     return H; 31 }

打印堆中的元素:

1 //打印堆中元素
2 void printHeap(MaxHeap H) 3 { 4     for (int i = 1; i <= H->Size; i++) 5         printf("%d ", H->Data[i]); 6     printf("\n"); 7 }

先序建立樹:

 1 void PreOrderCreateHeap(MaxHeap H, int index)  2 {  3     int dt;  4     scanf_s("%d", &dt);  5     if (dt == 0)  6  {  7         return;  8  }  9     H->Size++; 10     H->Data[index] = dt; 11     printf("please enter the left child of %d :", dt); 12     PreOrderCreateHeap(H, 2 * index); 13     printf("please enter the right child of %d: ", dt); 14     PreOrderCreateHeap(H, 2 * index + 1); 15 }

主函數:

1 int main() 2 { 3     MaxHeap H = CreateMaxHeap(); 4     PreOrderCreateHeap(H, 1); 5  printHeap(H); 6 
7     return 0; 8 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM