For heap ordering, first know what is the heap data structure, heap data structure is a complete binary tree, but it has its own nature.
For example, the nature of the maximum heap is:a[parent[i]]>=a[i]; that the value of each node is greater than or equal to the value of its left and right child, less than or equal to its parent node. We are here to discuss only the largest heap of cases. We know that a fully binary tree corresponds to a maximum heap, and all we have to do is convert the two fork tree to the maximum heap, which is called the maximum heap maintenance, and we define the function Maxheapfy (a,i) to operate.
Code:
/** *maxheapfy (a,i): Maintain position I maximum heap properties, assuming left (i) and right (i) Two binary trees for the root are the largest heaps, */ void maxheapfy (int *a , int i) {//maintenance position I max heap properties, int L,r,now; L=left (i); R=right (i); Now=i; //record current node if (L<=heapsize&&a[l]>a[now]) {now=l; //swap a[l] and a[i], and recursively maintain the next current node now } if (R<=heapsize&&a[r]>a[now]) {now=r; //swap a[l] and a[i], and recursively maintain the next current node now } if (now!=i) {//is not the current node and needs to be swapped to swap the current node with the maximum value of the left and right children Swap (A[i],a[now]); Maxheapfy (A,now); //recursively maintains the current node until the leaf node }}
The following is the construction of the heap based on the maintenance nature of the maximum heap:
/**
*buildmaxheap (a,n): Enter an unordered array A[1...N], build the largest heap, we know that the elements in the array a[(n/2+1) ... n] are all
* Leaf nodes in the tree, each can be seen as the largest heap of an element, then we remember that the maxheapfy (a,i) function is used to maintain
* The maximum heap is premised on the Child Left (i) and right (i) is the maximum heap, so we can take advantage of the maxheapfy (a,i) function from i:[(N/2). 1]
* Maximum heap creation is achieved.
*/
Code:
void BuildMaxHeap(int *A,int n){//A[1..n] heapsize=n;//全局变量,表示最大堆的大小 for(int i=n/2;i>=1;i--){//从n/2..1维护堆中每个节点的最大堆性质:结点的值大于起孩子的值 MaxheapFY(A,i); }}
We know that the first element of the largest heap is definitely the maximum value in the array, we can exchange (A[1] and a[n]) at this time A[n] is already the largest value, do not need to operate, only need to maintain the remaining n-1 elements of the subscript 1 of the maximum heap nature, after running into the largest heap of n-1 elements, Continue with the above interchange until 2 elements are left, and the sorting is complete.
Code:
void HeapSort(int *A,int n){ BuildMaxHeap(A,n);//建立最大堆 for(int i=n;i>=2;i--){ //cout<<A[1]<<" "; swap(A[1],A[i]);//交互A[1]和A[i],使得A[i]中为当前最大的元素 heapsize--;//堆大小减去1,便于下次操作去掉已经排好序的元素 MaxheapFY(A,1);//此时A[1]不一定满足最大堆的性质,重新维护下标1的最大堆的性质 }}
At this point we have completed the largest heap of build and heap sorting code, the largest heap has a more important use, is based on the maximum heap of the maximum priority queue implementation, the maximum priority queue is the largest element first, of course, there is also a minimum priority queue, is based on the minimum heap construction. We've learned that data structures all know that every data structure has its properties and operations (methods or functions), so let's take a look at what the maximum priority queue should support. There must be: take the first element of the queue, delete the first element, insert the element, modify the value of the element keyword, and so on.
/**
* Below gives the maximum priority queue corresponding to the operation
* 1, Pqueue_insert (a,x): The element x is inserted into the set S, the set S corresponds to a maximum priority queue
* 2, Pqueue_maxnum (A): Returns the element with the largest key value in the maximum priority queue S
* 3, Pqueue_pop (A): Remove and return the maximum priority queue S maximum key value of the element and delete
* 4, Pqueue_incresasekey (A,x,key): Adds the value of the key of element x to key (which corresponds to the maximum priority queue here)
*
* Special attention:::
* Priority queues here are maintained and manipulated based on the maximum heap build, so the maximum priority queue
* Before operation, the initial Hu function Pqueue_init (a,n) must be performed: Initialize the length to n set S and construct the maximum heap
*/
Various function code implementations:
initialization function Pqueue_init (a,n):
void PQueue_Init(int *A,int n){ BuildMaxHeap(A,n);//调用建立最大堆的函数进行初始化}
function Pqueue_maxnum (A) that returns the largest element:
int PQueue_Maxnum(int*A){ return A[1];}
Remove and return the first element of the maximum priority queue Pqueue_pop (A):
int PQueue_Pop(int *A){ if(heapsize>=1){ intmax=A[1]; A[1]=A[heapsize]; --heapsize;//堆大小(最大优先级队列的大小)减去1, MaxheapFY(A,1);//维护剩下的heaps的最大堆的性质 returnmax; } elsereturn -1;//删除失败}
After modifying the element keyword and maintaining the function Pqueue_incresasekey (a,x,key):
int PQueue_IncresaseKey(int *A,int i,int key){//增大A[i]的键值 ifreturn -1;//不符合最大堆的要求(仅仅是这里的定义) A[i]=key;//注意此时i的所有祖先都有可能不在满足最大堆的性质, //因此我们余姚判断所有的祖先是否满足最大堆的要求 while(i>1&&A[PARENT(i)]<A[i]){ swap(A[i],A[PARENT(i)]); i=PARENT(i);//向上判断到达当前的当前的结点满足最大堆的性质或者到达祖宗结点 }}
Insert element Pqueue_insert (a,x):
void PQueu_Insert(int *A,int key){ //插入首先最大优先级队列的大小增加1 ++heapsize; A[heapsize]=INF;//对新增的结点赋值一个永远娶不到的最小的值(仅对应于本程序的最大优先级队列) //剩下的操作就相当于将下标heapsize的关键字增大到key后,进行维护了,直接调用函数就好了 PQueue_IncresaseKey(A,heapsize,key);}
At this point all functions are defined and implemented, which is the maximum priority queue.
Appendix All code and test (few):
/** * @xiaoran heap sequencing is an algorithm for in-place sequencing with a data structure heap, * First understand what the heap data structure is, how to construct the largest heap and maintain the maximum heap *, and use a high-efficiency priority queue for data structures.#include <iostream> #include <cstdio> #include <map> #include <cstring> #include <string> #include <algorithm> #include <queue> #include <vector> #include <stack> #include <cstdlib > #include <cctype> #include <cmath> #define LLLong Long#define PARENT (x) x>>1#define LEFT (x) x<<1#define RIGHT (x) (x<<1)+1#define INF-100000000#define PT (A,n) for(intI=1; i<=n;i++) cout<<a[i]<<" "; Cout<<endl;using namespace Std;intHeapsize=0;//The size of the heap/** * Output A[1..N] * /voidPrint (int*a,intN) { for(intI=1; i<=n;i++) cout<<a[i]<<" "; Cout<<endl;}/** *maxheapfy (a,i): Maintain position I maximum heap nature, at this time assume that left (i) and right (i) are the root of the two binary trees are the largest heap, * /voidMaxheapfy (int*a,inti) {//Maintenance position I maximum heap nature, intL,r,now; L=left (i); R=right (i); Now=i;//Record the current node. if(L<=heapsize&&a[l]>a[now]) {now=l;//Swap a[l] and a[i], and recursively maintain the next current node now}if(R<=heapsize&&a[r]>a[now]) {now=r;//Swap a[l] and a[i], and recursively maintain the next current node now}if(now!=i) {//is not the current node and needs to be swapped to swap the current node with the maximum value of the left and right childrenSwap (A[i],a[now]); Maxheapfy (A,now);///recursively maintain the current node until the leaf node}}/** *buildmaxheap (a,n): Enter an unordered array A[1...N], build the largest heap, we know the array a[(n/2+1) ... n] The elements in the tree are the leaf nodes, each can be seen as the largest heap of an element, Then we remember that the maxheapfy (a,i) function is used to maintain the maximum heap of the premise that its child Left (i) and right (i) are the largest heaps, so we can take advantage of the maxheapfy (a,i) function from i:[(N/2): 1] * To achieve maximum heap creation. */voidBuildmaxheap (int*a,intN) {//A[1..N]Heapsize=n; for(inti=n/2; i>=1; i--) {//maintenance of the maximum heap nature of each node in the heap from n/2..1: The value of the node is greater than the child's valueMaxheapfy (A,i); }}/** * The following two functions are used to construct a heap sorting algorithm heapsort (a,n); * Call Buildmaxheap (a,n) to set the input array A[1..N] as the maximum heap. Note that at this point the maximum value of the array is a[1], * we just swap a[1] and a[n], remove a[n] (--heapsize), maintain the nature of the maximum heap of line label 1: maxheapfy (a,1), * until the heap size n-1 down to 2 */voidHeapsort (int*a,intN) {buildmaxheap (a,n);//Build Maximum heap for(inti=n;i>=2; i--) {//cout<<a[1]<< "";Swap (a[1],a[i]);//Interaction a[1] and a[i], making a[i] the largest element in the currentheapsize--;//Heap size minus 1, easy next operation to remove the already ordered elementsMaxheapfy (A,1);//At this time a[1] does not necessarily meet the nature of the maximum heap, re-maintain the maximum heap of subscript 1 Properties}}/** * Let's discuss the maximum priority queue based on the implementation of the maximum heap * Obviously the priority queue is a data structure, and we know that any data structure has its corresponding operation (function) * below gives the maximum priority queue corresponding operation * 1, Pqueue_insert (a,x): inserting element x into the set S, the set S corresponds to a maximum priority queue * 2, Pqueue_maxnum (a): Returns the maximum priority queue S, the element with the largest key value * 3, Pqueue_pop (a): Remove and return the maximum priority queue S maximum key value element and delete the Pqueue_incresasekey (A,x,key): Adds the value of the keyword of element x to the key (which corresponds to the maximum priority queue here) * * Special attention:: * Here the priority queue is based on the maximum heap established, after maintenance and operation, so in the maximum priority queue * Before operation, the initial Hu function Pqueue_init (a,n) must be performed: Initialize the length to n set S and construct the maximum heap * */voidPqueue_init (int*a,intN) {buildmaxheap (a,n);//Call the function that establishes the maximum heap to initialize}intPqueue_maxnum (int*a) {returna[1];}intPqueue_pop (int*a) {if(heapsize>=1){intmax=a[1]; a[1]=a[heapsize]; --heapsize;//Heap size (the size of the maximum priority queue) minus 1,Maxheapfy (A,1);//Maintain the nature of the largest heap of remaining heaps returnMax }Else return-1;//delete failed}intPqueue_incresasekey (int*a,intIintKey) {///increase the key value of A[i] if(Key<a[i])return-1;//Does not meet the requirements of the maximum heap (just the definition here)A[i]=key;//Note that all ancestors of I at this time may not satisfy the nature of the maximum heap, ///So we yuyao to determine whether all ancestors meet the maximum heap requirements while(i>1&&a[parent (i)]<a[i]) {Swap (a[i],a[parent (i))); I=parent (i);//Up to the current node to meet the nature of the maximum heap or reach ancestor nodes .}}voidPqueu_insert (int*a,intKey) {//Insert first maximum priority queue size increased by 1++heapsize; A[heapsize]=inf;//Assign a value to the new node A minimum value that will never be married (corresponds to the maximum priority queue for this program only) //The rest of the operation is equivalent to the subscript heapsize keyword increased to key, maintenance, directly call the function is OKPqueue_incresasekey (A,heapsize,key);}intMain () {inta[9]={0,4,2,5,6,2,6,1,7};/** * Heap sequencing Test * /Print (A,8); Heapsort (A,8); Print (A,8);/** * Maximum priority queue Test * /Pqueue_init (A,8); Cout<<pqueue_maxnum (A) <<endl; Cout<<pqueue_pop (A) <<endl; Cout<<pqueue_maxnum (A) <<endl; Pqueue_incresasekey (A,5,Ten); Pqueu_insert (A, A); Cout<<pqueue_maxnum (A) <<endl; Cout<<pqueue_pop (A) <<endl; Cout<<pqueue_maxnum (A) <<endl;return 0;}
Heap data structure + heap ordering + implementation of maximum priority queue heap