目录
堆的结构体
struct Heap { int *data; //数组首地址 int length; //堆中元素的数量 int maxsize; //堆中的最大容量 };
堆的创建
struct Heap * initialize(int maxsize){ //初始化堆 struct Heap * mHeap; mHeap = (struct Heap *)malloc(sizeof(struct Heap)); mHeap->data = (int *)malloc((maxsize+1) * sizeof(int)); mHeap->length = 0; mHeap->maxsize = maxsize; mHeap->data[0] = 945034985; //创建哨兵 return mHeap; }
堆的插入操作
//插入堆 void insert(struct Heap *mHeap,int x){ if(mHeap->length == mHeap->maxsize){ printf("堆已满!"); return; } int i = ++mHeap->length; mHeap->data[i] = x; //插入最后的位置 while(x > mHeap->data[i/2]) { mHeap->data[i] = mHeap->data[i / 2]; i = i / 2; //指向下标变为修改后父节点位置;继续判断(往上走) } mHeap->data[i] = x; }
堆的调整
void percDown(struct Heap *mHeap,int i){ //调整已有中的位置 int w = mHeap->data[i]; int k = i*2; //儿子结点 i为父亲下标 for(;k <= mHeap->length; k = i * 2) { if (k < mHeap->maxsize && mHeap->data[k] < mHeap->data[k + 1]) { k++; } if(w >= mHeap->data[k]) break; else { mHeap->data[i] = mHeap->data[k]; //进行交换 i = k; } } mHeap->data[i] = w; }void BuildMaxHeap(struct Heap *mHeap){ int i; for(i = mHeap->length/2;i>0;i--){ //只需要调整非终端结点即可 percDown(mHeap,i); } }
堆的删除操作
void delete(struct Heap *mHeap,int x){ int i; for( i = 1;i<= mHeap->length;i++){ //查找需要删除的数组下标 if(mHeap->data[i] == x){ break; } } mHeap->data[i] = mHeap->data[mHeap->length]; //最后一个代替他 mHeap->length--; BuildMaxHeap(mHeap); //调整 }
堆排序
void sortHeap(struct Heap *mHeap){ if(mHeap == NULL){ return; } int length = mHeap->length; while(length >= 1){ int w = mHeap->data[1]; //当前为堆中的最大值 //将最大值与最后一位调换 mHeap->data[1] = mHeap->data[length]; mHeap->data[length] = w; length--; //最后一位不用在参与下面的调整 for(int i = length/2;i >= 1;i--){ //只需要调整非终端结点即可 int child = 2 * i; int cnt = i; //被检查的父亲结点数组下标 int D = mHeap->data[cnt]; //被调整结点的数据 for(;child <= length;child = cnt * 2) { if (child < length && mHeap->data[child] < mHeap->data[child + 1]) { child++; } if (mHeap->data[child] <= D) { break; }else{ mHeap->data[cnt] = mHeap->data[child]; cnt = child; } } mHeap->data[cnt] = D; } } }
完整代码
#include <stdio.h> #include <stdlib.h> struct Heap { int *data; //数组首地址 int length; //堆中元素的数量 int maxsize; //堆中的最大容量 }; struct Heap * initialize(int maxsize){ //初始化堆 struct Heap * mHeap; mHeap = (struct Heap *)malloc(sizeof(struct Heap)); mHeap->data = (int *)malloc((maxsize+1) * sizeof(int)); mHeap->length = 0; mHeap->maxsize = maxsize; mHeap->data[0] = 945034985; //创建哨兵 return mHeap; } void percDown(struct Heap *mHeap,int i){ //调整已有中的位置 int w = mHeap->data[i]; int k = i*2; //儿子结点 i为父亲下标 for(;k <= mHeap->length; k = i * 2) { if (k < mHeap->maxsize && mHeap->data[k] < mHeap->data[k + 1]) { k++; } if(w >= mHeap->data[k]) break; else { mHeap->data[i] = mHeap->data[k]; //进行交换 i = k; } } mHeap->data[i] = w; } void BuildMaxHeap(struct Heap *mHeap){ int i; for(i = mHeap->length/2;i>0;i--){ //只需要调整非终端结点即可 percDown(mHeap,i); } } //插入堆 void insert(struct Heap *mHeap,int x){ if(mHeap->length == mHeap->maxsize){ printf("堆已满!"); return; } int i = ++mHeap->length; mHeap->data[i] = x; //插入最后的位置 while(x > mHeap->data[i/2]) { mHeap->data[i] = mHeap->data[i / 2]; i = i / 2; //指向下标变为修改后父节点位置;继续判断(往上走) } mHeap->data[i] = x; } //堆的输出 void printHeap(struct Heap *mHeap){ for(int i = 1;i<= mHeap->length;i++){ printf("%d ",mHeap->data[i]); } } void delete(struct Heap *mHeap,int x){ int i; for( i = 1;i<= mHeap->length;i++){ //查找需要删除的数组下标 if(mHeap->data[i] == x){ break; } } mHeap->data[i] = mHeap->data[mHeap->length]; //最后一个代替他 mHeap->length--; BuildMaxHeap(mHeap); //调整 } //堆排序 void sortHeap(struct Heap *mHeap){ if(mHeap == NULL){ return; } int length = mHeap->length; while(length >= 1){ int w = mHeap->data[1]; //当前为堆中的最大值 //将最大值与最后一位调换 mHeap->data[1] = mHeap->data[length]; mHeap->data[length] = w; length--; //最后一位不用在参与下面的调整 for(int i = length/2;i >= 1;i--){ //只需要调整非终端结点即可 int child = 2 * i; int cnt = i; //被检查的父亲结点数组下标 int D = mHeap->data[cnt]; //被调整结点的数据 for(;child <= length;child = cnt * 2) { if (child < length && mHeap->data[child] < mHeap->data[child + 1]) { child++; } if (mHeap->data[child] <= D) { break; }else{ mHeap->data[cnt] = mHeap->data[child]; cnt = child; } } mHeap->data[cnt] = D; } } } int main(){ int maxsize; int x,i,c; printf("数组的最大长度:"); scanf("%d",&maxsize); struct Heap *mHeap = initialize(maxsize); //初始化 scanf("%d",&x); while(x != -1){ mHeap->data[++mHeap->length] = x; scanf("%d",&x); } BuildMaxHeap(mHeap); printf("堆调整后:"); printHeap(mHeap); printf("\n请输入你要插入的数据:"); scanf("%d",&i); insert(mHeap,i); BuildMaxHeap(mHeap); printf("插入后:"); printHeap(mHeap); //printf("%d",mHeap->length); printf("\n输入需要删除的数据:"); scanf("%d",&c); delete(mHeap,c); printf("删除后:"); printHeap(mHeap); sortHeap(mHeap); printf("\n堆排序:"); printHeap(mHeap); }