细说堆排序

目录

1.什么是堆

2.大根堆和小根堆

3.堆的特性

4.排序思路

5.向下调整法

4.堆排序的实现

4.1向下调整法

4.2堆排序

1.什么是堆

堆是一种完二叉树的数据结构,分为大根堆,和小根堆

2.大根堆和小根堆

大根堆:父节点都大于子节点。                            小根堆:父节点都小于字节点。

3.堆的特性

1.堆的本质就是个数组,这种树状的结构是我们想象出来的,实际进行排序的时候操作的是数组。

例:上面两个堆在数组中的实际存储如图

2.堆的父节点和子节点的下标存以下两种关系:

parent = (child-1)/2;左孩子和右孩子都可以,因为存在向上取整。

LeftChild = child * 2+1 ,RightChild  = child *2 +2

3.大根堆的堆顶元素就是数组最大的数,小根堆的堆顶元素是数组最小的元素

4.排序思路

1.用向下调整法建堆。

2.交换堆顶和堆底最后一个元素。(大根堆顶的元素是最大的,直接放到末尾就不用管了)

3.将n-1个数重新建堆。

4.重复以上过程。

5.向下调整法

为什么选择用向下调整法建堆,而不用向上调整法建堆,是因为,向下调整的效率比向上调整高很多,这里不做过多解释。

向下调整法也有它本身的局限性,他要求左右子树必须是大堆或者小堆所以堆排必须必须从最后一个节点的父亲节点开始向下调整,不断向上调整,因为三个节点,要么是大堆,要么是小堆,不存在是不是堆的问题。

4.堆排序的实现

4.1向下调整法

void AdjustDown(int *a,int parent , int n)
{
	int child = parent * 2 + 1;
	while (child < n)
	{
		if (child+1<n && a[child + 1] > a[child])//找出左右孩子大的那一个
		{
			child++;
		}
		if (a[child] >a[parent])//比父亲大就交换
		{
			swap(&a[parent], &a[child]);
			parent = child;
			child = parent * 2 + 1;
		}
		else//没有发生交换说明已经是大堆(小堆)
		{
			break;
		}
    }
}

4.2堆排序

void HeapSort(int* a, int n)
{   
     //从最后一个孩子的父亲节点,由下向上 用向下调整法建堆。
	 for (int i = (n-1-1)/2;i >= 0; i--)//-1-1的原因是最后一个孩子的位置是(n-1)													
	 {								  //求父亲节点是(child-1)/2所以是(n-1-1)/2;
		 AdjustDown(a,i,n);
	 }
	 int end = n - 1;
	 while (end > 0)
	 {
		 swap(&a[end], &a[0]);		 
		 AdjustDown(a,0,end);
         end--;
	 }
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值