堆排序

分析

	1.首先整个排序过程分为两部分:第一,是将所给数据变成最大堆的形式。第二,交换数据。变成最大堆后,
	  数组第一个元素总是最大的,然后将st[0],st[10]交换,交换后此时再将st[0]~st[9]变成最大堆,然后再
	  交换数据,以此类推。
	2.堆结构,当前节点的左子节点下标是2*i+1,右子节点下标为2*i+2;节点的父节点是i/2-1;并且一般来说
	  堆都是完全二叉树
	3.堆排序的时间复杂度是O(N*lgN)。假设被排序的数列中有N个数。
	  遍历一趟的时间复杂度是O(N),需要遍历多少次呢?堆排序是采用的二叉堆进行排序的,二叉堆就是一棵
	  二叉树,它需要遍历的次数就是二叉树的深度,而根据完全二叉树的定义,它的深度至少是lg(N+1)。
	  最多是多少呢?由于二叉堆是完全二叉树,因此,它的深度最多也不会超过lg(2N)。因此,遍历一趟的时间
	  复杂度是O(N),而遍历次数介于lg(N+1)和lg(2N)之间;因此得出它的时间复杂度是O(N*lgN)

附注:
1.最大堆通常被用来进行"升序"排序,而最小堆通常被用来进行"降序"排序
2

#include<iostream>
#include<stdlib.h>

using namespace std;

class MyClass
{
public:
	void maxHeapSort(int st[],int start,int end){
		int current = start;
		int left = current * 2 + 1;
		int tmp = st[current];

		for (; left <= end; current = left, left = left * 2 + 1){
			//选取左右节点中较大的U一个值和当前节点比较,此处left < end而不是<=,因为++可能越界
			if (left < end&&st[left] < st[left + 1]){
				++left;
			}

			//如果当前节点大,则结束,否则将大的和当前节点交换位置,接着对比当前节点
			if (tmp >= st[left]){
				break;
			}
			else{
				st[current] = st[left];
				st[left] = tmp;
			}
		}
		return;
	}

	void heapSortAscend(int st[], int len){
		//从开始到数组中间遍历,使其变为最大堆
		for (int i = (len - 1) / 2; i >= 0; --i){
			maxHeapSort(st, i, len - 1);
		}

		//交换数据
		for (int i = len-1; i > 0; --i){
			int tmp = st[0];
			st[0] = st[i];
			st[i] = tmp;
			maxHeapSort(st, 0, i-1);
		}
	}
};


void main()
{
	MyClass bb;
	int i;
	int a[] = { 20, 30, 90, 40, 70, 110, 60, 10, 100, 50, 80 };
	int ilen = (sizeof(a)) / (sizeof(a[0]));

	cout << "before sort:";
	for (i = 0; i<ilen; i++)
		cout << a[i] << " ";
	cout << endl;

	bb.heapSortAscend(a, ilen);          // 升序排列
	//heapSortDesc(a, ilen);        // 降序排列

	cout << "after  sort:";
	for (i = 0; i<ilen; i++)
		cout << a[i] << " ";
	cout << endl;
	system("pause");
	return;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值