【数据结构】二叉树之堆排序(完整代码)

来源:互联网 发布:淘宝上代购药品 编辑:程序博客网 时间:2024/05/19 14:35
堆的概念
最小堆:任一结点的关键码均小于等于它的左右孩子的关键码,位于堆顶结点的关键码最
最大堆:任一结点的关键码均大于等于它的左右孩子的关键码,位于堆顶结点的关键码
最大
堆存储在下标为0开始计数的数组中,因此在堆中给定小标为i的结点时:
1、如果i=0,结点i是根节点,没有双亲节点;否则结点i的双亲结点为结点(i-1)/2
2、如果2*i+1>n-1,则结点i无左孩子,否则结点i的左孩子为结点2*i+1
3、如果2*i+2>n-1,则结点i无右孩子,否则结点i的右孩子为结点2*i+2
堆排序的结点表示
typedef struct{ElemType *data;int maxsize;int cursize;}Heap;

堆的创建(最小堆)
//从结点(ArraySize-1)/2开始调整,将每一棵子树都调整成一棵最小堆结构
void Make_Heap(Heap *hp){assert(hp != NULL);int end = hp->cursize -1;int pos = (end-1)/2;while(pos >= 0){FilterDown(hp->data,pos,end);--pos;}}


//检测以i为结点的子树是否满足最小堆,若满足不调整,否则,调整。
void FilterDown(ElemType *ar,int start,int end){int i = start; // root;int j = i*2+1; // leftchild;ElemType tmp = ar[i];while(j <= end){if(j < end && ar[j] >= ar[j+1]) j+=1;if(tmp <= ar[j])  break;         ar[i] = ar[j];i = j;j = i*2+1;}ar[i] = tmp;}
堆的单个元素插入
堆的插入每次都在已经建成的而最小堆的后面插入,但插入之后,有可能破坏了对的
结构,这时就需要对堆进行重新调整
void Insert_Heap(Heap *hp,ElemType *ar,int n){assert(hp != NULL &&  ar != NULL && n>0 );for(int i = 0;i<n;++i){hp->data[i] = ar[i];}hp->cursize = n;Make_Heap(hp);}
堆的数组插入
void Insert_Heap(Heap *hp,ElemType *ar,int n){assert(hp != NULL &&  ar != NULL && n>0 );for(int i = 0;i<n;++i){hp->data[i] = ar[i];}hp->cursize = n;Make_Heap(hp);}
堆的取栈顶
ElemType Pop_Heap(Heap *hp){assert(hp != NULL);int tmp = hp->data[0];Swap(hp->data[0],hp->data[hp->cursize-1]);hp->cursize -= 1;FilterDown(hp->data,0,hp->cursize-1);return tmp;}

算法实现和程序代码:

#include<stdio.h>#include<malloc.h>#include<assert.h>#include<stdlib.h>#include"Heap.h"#define MINHEAPtemplate<class Type>void Swap(Type &a,Type &b){Type tmp = a;a = b;b = tmp;}void FilterDown(ElemType *ar,int start,int end){int i = start; // root;int j = i*2+1; // leftchild;ElemType tmp = ar[i];while(j <= end){if(j < end && ar[j] >= ar[j+1]) j+=1;if(tmp <= ar[j])  break;  ar[i] = ar[j];i = j;j = i*2+1;}ar[i] = tmp;}void FilerUp(ElemType *ar,int start){int j = start, i = (j-1)/2;ElemType tmp = ar[j];while(j > 0){#ifdef MINHEAPif(ar[i] <= tmp)#elseif(ar[i] >= tmp)#endifbreak;ar[j] = ar[i];j = i;i = (j-1)/2;}ar[j] = tmp;}bool Init_Heap(Heap *hp){assert(hp!= NULL);hp->cursize = 0;hp->maxsize = HEAPSIZE;hp->data = (ElemType*)malloc(sizeof(ElemType)*hp->maxsize);if(hp->data == NULL) exit(1); // return false;return true;}void Destroy_Heap(Heap *hp){assert(hp != NULL);free(hp->data);hp->data = NULL;hp->maxsize = 0;hp->cursize = 0;}void Clear_Heap(Heap *hp){assert(hp != NULL);hp->cursize = 0;}bool Empty_Heap(Heap *hp){assert(hp != NULL);return hp->cursize == 0;}bool Full_Heap(Heap *hp){assert(hp != NULL);return hp->cursize == hp->maxsize;}int  Size_Heap(Heap *hp){assert(hp != NULL);return hp->cursize;}// Empty_Heap();ElemType Pop_Heap(Heap *hp){assert(hp != NULL);int tmp = hp->data[0];Swap(hp->data[0],hp->data[hp->cursize-1]);hp->cursize -= 1;FilterDown(hp->data,0,hp->cursize-1);return tmp;}void Make_Heap(Heap *hp){assert(hp != NULL);int end = hp->cursize -1;int pos = (end-1)/2;while(pos >= 0){FilterDown(hp->data,pos,end);--pos;}}void Insert_Heap(Heap *hp,ElemType *ar,int n){assert(hp != NULL &&  ar != NULL && n>0 );for(int i = 0;i<n;++i){hp->data[i] = ar[i];}hp->cursize = n;Make_Heap(hp);}void Push_Heap(Heap *hp,ElemType x){assert(hp != NULL);if(Full_Heap(hp)){// Inc_Heap(ph);}hp->data[hp->cursize] = x;hp->cursize +=1;FilerUp(hp->data,hp->cursize - 1);}













阅读全文
0 0