堆的创建
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);
}