堆排序

https://www.cnblogs.com/chengxiao/p/6129630.html

https://www.cnblogs.com/chengxiao/p/6129630.html

这两篇篇文章解析不错

      堆排序是利用这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。首先简单了解下堆结构。

  堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆

性质:

       索引为 i 的 结点:左孩子 2*i+ 1  

       索引为 i 的结点 :右孩子 2*i + 2

       索引为 i 的父结点: 索引为 floor((i-1)/2)

       数组构建堆(完全二叉树)开始结点  length/2 -1 ,length数组长度

      堆排序的基本思想是:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了

#include <iostream>
#include <string>
using namespace std;
//构建 最大堆
void maxHeapDown(int *arr, int curr, int length)
{
	//当前指针指向位置 curr
	for (int i = 2 * curr + 1; i < length;i = 2*i+1) 
	{
		//curr 当前指向位置的 左孩子arr[i] 右孩子 arr[i+1]
		if (i+1 < length && arr[i] < arr[i + 1])
			i++;
		if (arr[i] <= arr[curr])
			break;

		/*if (i < length && arr[i] > arr[i + 1])
			i++;
		if (arr[i] >= arr[curr])
		{
			break;
		}*/
		else
		{
			//指针指向节点curr 元素与 孩子交换位置
			int temp = arr[i]; 
			arr[i] = arr[curr];
			arr[curr] = temp;
			//指针直线位置更新
			//curr = i;
		}
		curr = i;
		
	}
}


void heapSort(int *arr,int length)
{
	//构建堆 从非叶子节点开始调整 即 length/2-1
	for (int i = length / 2 - 1; i >= 0; i--)
	{
		maxHeapDown(arr, i, length);
	}
	//交换数据 
	for (int j = length-1; j >0; j--)
	{
		int tmp = arr[0];
		arr[0] = arr[j];
		arr[j] = tmp;
		maxHeapDown(arr, 0, j);
	}

}

int main()
{
	int arr[] = {20,30,40,60,70,110,90,10,150,50,80,100};
	//int arr[] = {312,126,272,226,28,165,123,8,12};
	int len = sizeof(arr) / sizeof(arr[0]);
	cout << "   " << len << endl;
	heapSort(arr, len);
	for (int i = 0; i < len; i++)
		cout << "arr[" + to_string(i) + "]" << arr[i] << endl;
	system("pause");
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值