实现堆的排序(从小到大)
变化之前的初始化堆
bool InitHeap(Heap& heap, int* orginal, int size) {
int capacity = DEFAULT_CAPCITY > size ? DEFAULT_CAPCITY : size;//比较宏定义的数组大小和函数传进来的数组大小
heap.arr = new int[capacity];//动态分配数组内存
if (!heap.arr)
return false;
heap.size = 0;
heap.capacity = capacity;
//如果存在原始数据则构建堆
if (size > 0) {
memcpy(heap.arr, orginal, size * sizeof(int));
heap.size = size;
//建堆
buildHeap(heap);
}
else {
heap.size = 0;
}
return true;
}
变化之后
//初始化堆
bool InitHeap(Heap& heap, int* orginal, int size) {
//heap.arr = new int[capacity];//动态分配数组内存
heap.arr = orginal;
if (!heap.arr)
return false;
heap.size = size;
heap.capacity = size;
//如果存在原始数据则构建堆
if (size > 0)
//建堆
buildHeap(heap);
return true;
}
代码如下
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct _Heap {
int* arr; //存储堆元素的数组
int size; //当前已经存储的元素个数
int capacity; // 当前存储的容量
}Heap;
bool InitHeap(Heap& heap, int* orginal, int size);//初始化堆
bool insert(Heap& heap, int value);//插入元素
static void buildHeap(Heap& heap);//建立堆
void heapsort(Heap& heap);//堆排序
static void adjustDown(Heap& heap, int index);//向下调整
//初始化堆
bool InitHeap(Heap& heap, int* orginal, int size) {
//heap.arr = new int[capacity];//动态分配数组内存
heap.arr = orginal;
if (!heap.arr)
return false;
heap.size = size;
heap.capacity = size;
//如果存在原始数据则构建堆
if (size > 0)
//建堆
buildHeap(heap);
return true;
}
//实现堆排序
void heapsort(Heap& heap) {//因为是&引用操作符,所以heap.arr就是origVals[];
if (heap.size < 1)
return;
while (heap.size > 0) {
int tmp = heap.arr[0];
heap.arr[0] = heap.arr[heap.size - 1];
heap.arr[heap.size - 1] = tmp;
heap.size--;
adjustDown(heap, 0);//从0开始向下调整一直循环
}
}
//向下调整堆元素
void adjustDown(Heap& heap, int index) {//index是当前节点位置
int cur = heap.arr[index];//当前待调整节点
int parent, child;
//判断是否存在大于当前节点子节点,如果不存在,则堆本身是平衡的
//不需要调整,如果存在,则将最大的字节点与之交换,交换后如果这个子
//节点还有子节点,则需要按照同样的步骤对这个子节点进行调整
//寻找父节点的两个子节点
for (parent = index; (parent * 2 + 1) < heap.size; parent = child) {//父节点等于当前节点,然后子节点要小于数组的最大长度
child = parent * 2 + 1;//+1是左子节点
//取两个子节点的最大的一个
if (((child + 1) < heap.size && heap.arr[child] < heap.arr[child + 1])) {//首先子节点不能大于数组的长度,然后就比较两个子节点的大小
child++;
}
//把大的子节点和父节点进行比较,然后交换
if (cur >= heap.arr[child]) {
break;
}
else {//交换父子节点
heap.arr[parent] = heap.arr[child];
heap.arr[child] = cur;
}
}
}
//建堆
//从最后一个父节点(size/2-1的位置)逐个往前调整所有父节点,(直到根节点),确保
//每一个父节点都是最大堆,最后整体上形成一个最大堆
void buildHeap(Heap& heap) {
int i;
for (i = heap.size / 2 - 1; i >= 0; i--) {
adjustDown(heap, i);
}
}
int main(void) {
Heap hp;//创建一个新堆
int origVals[] = { 1,2,3,87,93,82,92,86,95 };
int i = 0;
if (!InitHeap(hp, origVals, sizeof(origVals) / sizeof(int))) {
fprintf(stderr, "初始化堆失败!\n");
exit(-1);
}
for (int i = 0; i < hp.size; i++) {
printf("the %dth element:%d\n", i, hp.arr[i]);
}
//堆排序
heapsort(hp);
for (int i = 0; i < sizeof(origVals) / sizeof(origVals[0]); i++) {
printf(" %d", origVals[i]);
}
system("pause");
return 0;
}
总结
学数据结构一定要动手画啊啊啊啊啊啊