堆
堆分为最大堆和最小堆,最大堆的子节点都比父节点小,若用与序列对应的一维数组存储,则可看成一颗完全二叉树
建立最大堆 (最小堆与之同理)
#define max 20
#define maxdata 100
//堆的结构
struct HeapSort//从1的下标开始存放
{
int* elem;
int size;//当前个数
int maxsize;//最大容量
};
typedef struct HeapSort* heap;
//初始化堆
heap create() {
heap h = (heap)malloc(sizeof(struct HeapSort));
h->elem = (int*)malloc((max+1)* sizeof(int));//从下标为1的地方开始放
h->size = 0;
h->maxsize = max;
h->elem[0] = maxdata;//哨兵,记录堆的可能的最大值
return h;
}
//创建堆
heap buildheap(int* arr,int len) {
heap h = create();
for (int j = 1; j <= len; j++) { //将数组的元素拷贝进堆h
h->elem[j] = arr[j - 1];
h->size++;
}
int i,child;
for (int p = len / 2; p > 0; p--) {
int x = h->elem[p];
for (i = p; 2 * i <= len; i = child) {//当p节点的孩子节点还有子节点时,循环,防止p节点值太小而破坏结构
child = i * 2;
if (child < len && h->elem[child] < h->elem[child + 1])
child++; //找到左右子树的最大值
if (x >= h->elem[child]) break;
else {
h->elem[i] = h->elem[child];
}
}
h->elem[i] = x;
}
return h;
}
插入操作
void insert(heap h,int x) {
if (h->size == h->maxsize+1) {
printf("堆已满");
}
else {
h->size++;
int child= h->size;
for (; h->elem[child / 2] < x; child /= 2)
h->elem[child] = h->elem[child/2];//向上找到x的位置
h->elem[child] = x;
}
}
删除操作
删除必是删除下标为1的点,然后把数组最后的节点放到顶点,然后调整堆,找到数组最后那个节点该放的位子
//删除并取出最大值
int deletex(heap h) {
int maxval;
if (h->size == 0) {
printf("空");
return -1;
}
else {
int p;
int x=h->elem[h->size--];
maxval = h->elem[1];//保留最大值
int child=2;
for (p = 1; 2 * p < h->size;p=child) {
child= 2 * p;
if (child<h->size&&h->elem[child] < h->elem[child + 1])
child++;
if (x >= h->elem[p])
break;
else h->elem[p] = h->elem[child];
}
h->elem[p] = x;
}
return maxval;
}