最大堆(优先队列)基本概念,即一个完整建立,插入,删除代码


堆(优先队列)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