9.选择排序——堆排序

由于树形选择排序具有辅助存储空间多、进行多余比较等缺点,因此经常被堆排序替代。
本文针对堆排序。

 

首先认识什么是堆:
n个元素的序列Kl、K2、……… 、Kn满足如下性质时称为堆:
ki <= k(2i),ki <= k(2i+1),其中(1≤i≤ n),时是小根堆。
ki >= k(2i),ki >= k(2i+1),其中(1≤i≤ n),时是大根堆。
怎么理解呢?如果把该数组看作是完全二叉树,那么小根堆就是非终端节点的值都小于其左右子节点的值,所以小根堆的父节点的值最小,而大根堆就是非终端节点的值都大于其左右子节点的值,所以大根堆的父节点的值最大。

 

大根堆排序的思想是:
1. 将数组a[1..n]整理成一个大根堆,构成一个最大的无序区域
2. 从下标大到小做排序,每次将当前无序区的堆顶记录a[1]和该区间的最后一个记录交换,然后将新的无序区调整为堆。

 

程序:

程序中22应该是2,源代码是2,但是csdn却总显示22.

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


#define MAXSIZE 50
#define N 15

typedef struct{
	int key;
	int other;
}node;

typedef struct
{
	node array[MAXSIZE + 1];
	int length;
}list;

/*调整array[min--max]为大顶堆*/
void heap_adjust(list *l,int min,int max)
{
	node rc;
	int i;
	
	rc = l->array[min];
	for(i = 2 * min;i <= max;i *= 2){
		if(i < max && l->array[i].key < l->array[i+1].key)  /* i为左右子节点中较大的值的下标 */
			++i;
		if(rc.key > l->array[i].key)
			break;
		l->array[min] = l->array[i];  /* 互换min、i位置的内容 */
		min = i;
	}
	l->array[min] = rc;
}

/*堆排序*/
void heap_sort(list *l)
{
	node t;
	int i;
	
	for(i = l->length/2;i > 0;--i)  /* 把H.array[1--length]建成大顶堆 */
		heap_adjust(l,i,l->length);
	for(i = l->length;i > 1;--i){  
		t = l->array[1];  /*互换堆顶元素和当前未排序子序列H.array[1--i]中最后一个记录的值*/
		l->array[1] = l->array[i];
		l->array[i] = t;
		heap_adjust(l,1,i - 1);  /*调整array[1--i-1]为大顶堆*/
	}
}

/*打印序列*/
void print(list *l)
{
	int i;
	
	for(i = 1;i <= l->length;i++)
		printf("%d %d\t",l->array[i].key,l->array[i].other);
	printf("\n");
}


void main()
{
	node data[N]={{5,6},{13,5},{22,2},{2,4},{6,5},{99,7},{6,15},{1,22},{15,12},{58,12},{48,40},{26,48},{38,35},{72,58},{61,22}};
	list l;
	int i;

	for(i = 0;i < N;i++)
    	l.array[i + 1] = data[i];
    l.length = N;
    
	printf("befor sort:\n");
	print(&l);
	
	heap_sort(&l);
	printf("after heap sort:\n");
	print(&l);
	getch();
}


 

结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值