一步一步写算法--堆排序

堆的定义

1,L(i)<=L(2i) 且 L(i)<=L(2i+1);小根堆

2,L(i)>=L(2i) 且 L(i)>=L(2i+1);大根堆

原理

对初始序列建堆,就是一个反复筛选的过程。

n个结点的完全二叉树,最后一个节点是n/2个结点的孩子,对第m/2和其之前的节点为根的子树摔选,看该节点信息与其左右子结点的值比较,如果不符合条件,交换后,再对交换后的子结点进行判断,也就是不断向下调整的过程

源程序:

//测试数据53 17 78 9 45 65 87 32,插入63
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
void AdjustDown(ElemType A[],int k,int len);
//交换实参数据
void swap(int &m,int &n)
{
	int tmp;
	tmp=m;
	m=n;
	n=tmp;
}
//建立大根堆
 void BuildMaxHeap(ElemType A[],int len)
{
	for(int i=len/2;i>0;i--)
		AdjustDown(A,i,len);
}
//建堆,向下调整
 void AdjustDown(ElemType A[],int k,int len)
{
	A[0]=A[k];
	for(int i=2*k;i<=len;i*=2)
	{
		if(i<len && A[i]<A[i+1])	
			i++;
	
		if(A[0]>=A[i])	break;
		else
		{
			A[k]=A[i];
			k=i;
		}
	}
	A[k]=A[0];
}
//堆排序
 void HeapSort(ElemType A[],int len)
{
	//BuildMaxHeap(A,len);
	int i;
	for(i=len;i>1;i--)
	{
		swap(A[i],A[1]);
		AdjustDown(A,1,i-1);
	}
}
//插入数据,向上调整
 void AdjustUp(ElemType A[],int k)
{
	A[0]=A[k];
	int i=k/2;
	while(i>0 && A[i]<A[0])
	{
		A[k]=A[i];
		k=i;
		i=k/2;
	}
	A[k]=A[0];
}
int main()
{
	int n;
	printf("输入数据个数:");
	scanf("%d",&n);
	ElemType *B=(ElemType *) malloc ((n+2) * sizeof(ElemType));
	ElemType *A=(ElemType *) malloc ((n+2) * sizeof(ElemType));
	//ElemType B[10];
	//ElemType A[10];
	//int *A=new int[m];
	int i;
	for(i=1;i<=n;i++)
		scanf("%d",&A[i]);
	BuildMaxHeap(A,n);
	printf("大根堆:");
	for(i=1;i<=n;i++)
		printf("%d ",A[i]);
	printf("\n插入一个数:");
	scanf("%d",&A[n+1]);
	printf("\n插入后的大根堆:");
	BuildMaxHeap(A,n+1);
	for(i=1;i<=n+1;i++)
		printf("%d ",A[i]);
	AdjustUp(A,n+1);
	HeapSort(A,n+1);
	printf("\n堆排序:");
	for(i=1;i<=n+1;i++)
		printf("%d ",A[i]);
	return 0;
	
}

结果

hadoop@master:~/algorithm/sort/HeapSort$ g++ -c HeapSort.cpp
hadoop@master:~/algorithm/sort/HeapSort$ g++ HeapSort.o -o HeapSort
hadoop@master:~/algorithm/sort/HeapSort$ ./HeapSort 
输入数据个数:8
53 17 78 9 45 65 87 32
大根堆:87 45 78 32 17 65 53 9 
插入一个数:63

插入后的大根堆:87 63 78 45 17 65 53 9 32 
堆排序:9 17 32 45 53 63 65 78 87

堆排序的过程实际就是不断删除堆的根数据的过程,每删除一个根元数,就对其余剩余的数据再次建堆,建堆中在不断的向下调整序列。


空间复杂度:O(1)

时间复杂度:建堆:O(n),每次调整:O(h),h调整的高度,最好,最坏和平均情况都是一样的复杂度:O(nlogn)

稳定性:不稳定

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值