首页 > 其他 > 详细

堆排序

时间:2014-02-17 04:16:24      阅读:429      评论:0      收藏:0      [点我收藏+]

堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆是一个完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

由于堆是一个完全二叉树的结构所以我们在存储的时,使用线性链表或者数组存储。

堆排序有最大堆或者最小堆。其实堆排序是一个递归的过程。让所有子树也是一个最小(或者最大)堆。

 

堆排序的过程有两步:
1. 建立最小(或最大)堆。

2. 将得到最小(或最大)值(第一个元素)与当前堆最后一个元素交换。堆中元素个数减一。如果堆中元素个数不为0,转到下一步

3. 这个时候堆可能已经违反最大(或最下)堆的性质了。进行最大(或最小)堆调整。

 

我们以最小堆最为例子讲解吧。

建立堆的过程,分析的时候我们是从上倒下,使用递归实现。

如图,节点左边的值表示在数组中存储的index,

bubuko.com,布布扣

如果,首先,我们将以节点3为根子树建立最小堆。

其次。我们将以节点2为根子树建立最小堆。

再次。我们将以节点1为根子树建立最小堆。

最后。我们将以节点0为根子树建立最小堆。就完成了建立堆的过程。

这样,我们就可以不使用递归了。

其实,其实我们只需要保证所有节点大有2子树为最小堆。也就是以节点3,2,1,0为根的子树。我们从index最大开始最小堆就行了。


问:其实我们只需要保证所有节点大有2子树为最小堆,这个index怎么算?

提示:注意堆是一个完全二叉树。使用二叉树的性质。节点数/2。

 

堆调整的过程与建堆的过中子树调整是一样的。

 

下面是最小堆的排序过程代码:


#include<stdio.h>
#include<stdlib.h>
#include <stdio.h>

#define MAX 200 

void print_arr(int a[], int n);

int
heap_item_sort(int a[], int n, int len)
{
	int tmp;
	int i,j;


	j = n;
	tmp = a[j];
	for(i = 2*n+1; i < len; i = i*2+1) {
		if(i+1 < len && a[i] > a[i+1]) {
			i++;
		}
		if( tmp > a[i] ) {
			a[j] = a[i];
			j = i;
		}
		else {
			break;
		}

	}
	a[j] = tmp;

	return 0;
}



void
head_sort(int a[], int n)
{
	int tmp ;
	int i;
	
	for(i = n/2 -1 ; i >=0; i--) {
		heap_item_sort(a, i, n);
	}
	for(i = n-1; i >=0; i--) {
		tmp = a[0];
		a[0] = a[i];
		a[i] = tmp;
		heap_item_sort(a,0,i);	
	}
}


void 
print_arr(int a[], int n)
{
	int i = 0;

	while(i < n) {
		printf("%-5d|", a[i++]);
	}
	printf("\n");
}

int main()
{
    
	int a[]={49, 38, 65, 97, 76, 13, 27,10 };
	int n = sizeof(a)/sizeof(int);

	printf("heap sort befor\n");
	print_arr(a, n);

	head_sort(a, n);

	printf("heap sort result\n");
	print_arr(a, n);
}

blog: http//www.rhttp.cn

堆排序

原文:http://blog.csdn.net/reage11/article/details/19288407

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!