堆排序C语言实现

堆构建过程请参照上一篇博客《大根堆小根堆的实现》http://blog.csdn.net/stormlovetao/article/details/8665506

这里再加上一个堆的排序算法

首先看一个例子的演示(图片均来自哈工大李建中《算法设计与分析》课件)

堆排序C语言实现_第1张图片堆排序C语言实现_第2张图片

堆排序C语言实现_第3张图片

堆排序C语言实现_第4张图片

堆排序C语言实现_第5张图片

堆排序C语言实现_第6张图片

通过这个例子不难看出,主要思想是将大根堆的对顶取出,放到数组的最后一个位置,将最后一个位置原来的数放到堆顶,然后对堆顶做调整Max-Heapify(见链接内博客)。

算法伪代码:

堆排序C语言实现_第7张图片

重点来啦,直接上代码,代码亲测没有问题的,只是可能得换一下输入数据而已。

#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;
}


 

你可能感兴趣的:(c,堆排序)