您的位置:首页 > 编程语言 > C语言/C++

堆排序(非递归版)-- c语言实现

2015-08-15 09:39 330 查看
    堆,是在逻辑上模仿完全二叉树的一维数组,(假设数组开始下标为0)某父节点 i 其左右孩子可以表示为2*i+1(左)和2*i+2(右).

堆排序的思想是每次从堆顶拿出一个元素(最大或最小取决于是大顶堆还是小顶堆)放入已排序数组,然后将堆最后一个元素插入堆顶,

这样将引起堆的不平衡,然后重新调整堆至平衡,重复做下去。注意,每次拿出堆顶元素堆的大小都会减小1.

关于堆的复杂度:

排序算法平均时间复杂度最坏时间复杂度最好时间复杂度空间复杂度稳定性复杂性
堆排序O(nlgn)O(nlgn)O(nlgn)O(1)不稳定较复杂
#include <stdio.h>
#include <stdlib.h>

#define size 10            /*数组大小*/
#define lchild(i) (2*i+1)  /*数组起始下标为0,其左孩子为2*i+1 */
#define swap(a,b) {a^=b;b^=a;a^=b;} /*两个元素交换*/

/*调整堆平衡的函数*/
void heap_adjust(int *arr,int start,int end)
{
int temp = arr[start];
int i;
for(i = lchild(start); i <= end; i*=2){
/*获得两个孩子中较大的一个,如果右孩子大于左孩子,则
*i下标增加为右孩子下标,否则不变
*/
if(i<end && arr[i]<arr[i+1]){
i++;
}
/*比较父亲和孩子中较大的*/
if(temp > arr[i]){
break;
}
/*孩子比父亲大,孩子上位取代父亲*/
arr[start] = arr[i];
/*以孩子的位置进行下一次调整*/
start = i;
}

/*插入最开始引起堆不平衡的元素*/
arr[start] = temp;
}
/*堆排序主程序*/
void heap_sort(int *arr,int n)
{
int i;
/*创建大顶堆,从最后一个非叶子节点开始,自
*下而上调整。
*/
for(i = n/2;i>=0;i--){
heap_adjust(arr,i,n-1);
}
/*堆排序。每次将堆顶元素与堆的最后一个叶子节点交换
*交换后堆不平衡,重新调整堆,每交换一次,要调整堆
*的大小减小一个
*/
for(i=n -1;i > 0;i--){
swap(arr[0],arr[i]);
heap_adjust(arr,0,i-1);
}

}

int main()
{

int arr[size]={1,3,4,7,13,-1,8,2,6,0};
heap_sort(arr,size);

int i;
for(i = 0;i<size;i++){
printf("%d ",arr[i]);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  排序算法