堆构建过程请参照上一篇博客《大根堆小根堆的实现》http://blog.csdn.net/stormlovetao/article/details/8665506
这里再加上一个堆的排序算法
首先看一个例子的演示(图片均来自哈工大李建中《算法设计与分析》课件)
通过这个例子不难看出,主要思想是将大根堆的对顶取出,放到数组的最后一个位置,将最后一个位置原来的数放到堆顶,然后对堆顶做调整Max-Heapify(见链接内博客)。
算法伪代码:
重点来啦,直接上代码,代码亲测没有问题的,只是可能得换一下输入数据而已。
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
#include <string.h>
/*
目的:建立大根堆,也可以变成小根堆,
核心:堆的调整
输入:文件,整数以空格隔开
输出:大根堆
*/
void Swap(uint32_t* array, uint32_t i, uint32_t j)
{
assert(array);
uint32_t tmp;
tmp = array[j];
array[j] = array[i];
array[i] = tmp;
}
/*大根堆调整*/
void MaxHeapify(uint32_t* array, uint32_t heapSize, uint32_t currentNode)
{
uint32_t leftChild, rightChild, largest;
leftChild = 2*currentNode + 1;
rightChild = 2*currentNode + 2;
if(leftChild < heapSize && array[leftChild] > array[currentNode])
largest = leftChild;
else
largest = currentNode;
if(rightChild < heapSize && array[rightChild] > array[largest])
largest = rightChild;
if(largest != currentNode)
{
Swap(array, largest, currentNode);
MaxHeapify(array, heapSize, largest);
}
}
/*构建大根堆*/
void MaxHeapCreat(uint32_t* array, uint32_t heapSize)
{
int i;
for(i = heapSize/2; i >= 0; i--)
{
MaxHeapify(array, heapSize, i);
}
}
/*小根堆调整*/
void MinHeapify(uint32_t* array, uint32_t heapSize, uint32_t currentNode)
{
uint32_t leftChild, rightChild, minimum;
leftChild = 2*currentNode + 1;
rightChild = 2*currentNode + 2;
if(leftChild < heapSize && array[leftChild] < array[currentNode])
minimum = leftChild;
else
minimum = currentNode;
if(rightChild < heapSize && array[rightChild] < array[minimum])
minimum = rightChild;
if(minimum != currentNode)
{
Swap(array, minimum, currentNode);
MinHeapify(array, heapSize, minimum);
}
}
/*构建小根堆*/
void MinHeapCreat(uint32_t* array, uint32_t heapSize)
{
int i;
for(i = heapSize/2; i >= 0; i--)
{
MinHeapify(array, heapSize, i);
}
}
void HeapSort(uint32_t* array, uint32_t heapSize)
{
MaxHeapCreat(array, heapSize);
int i;
uint32_t arraySize = heapSize;
for(i = arraySize - 1; i >= 1; i--)
{
Swap(array, 0, i);
heapSize--;
MaxHeapify(array, heapSize, 0);
}
}
int main()
{
uint32_t tmp;
uint32_t *array;
array = malloc(sizeof(uint32_t));
int i, heapSize = 0;
/*从文件中读出待排序数据*/
char* filePathway = "C:/Users/Administrator/Desktop/data.txt";
FILE* fp;
fp = fopen(filePathway, "rb");
if(!fp)
{
fprintf(stderr, "Can not open file correctly\n");
}
while(!feof(fp))
{
fscanf(fp, "%d", &tmp);
heapSize++;
array = realloc(array, sizeof(uint32_t) * (heapSize ));
if(array == NULL)
{
fprintf(stderr, "realloc error!\n");
return 1;
}
array[heapSize - 1] = tmp;
}
printf("The origen dataset:\n");
for(i = 0; i < heapSize; i++)
{
printf("%d\t", array[i]);
}
printf("\n");
/*构建小根堆并输出*/
MinHeapCreat(array, heapSize);
printf("Output the MinHeap:\n");
for(i = 0; i < heapSize; i++)
{
printf("%d\t", array[i]);
}
printf("\n");
/*构建大根堆并输出*/
MaxHeapCreat(array, heapSize);
printf("Output the MaxHeap:\n");
for(i = 0; i < heapSize; i++)
{
printf("%d\t", array[i]);
}
/*堆排序*/
HeapSort(array, heapSize);
printf("Output the SortedHeap:\n");
for(i = 0; i < heapSize; i++)
{
printf("%d\t", array[i]);
}
free(array);
fclose(fp);
return 0;
}