堆排序

堆排序(Heap Sort),只需要一个记录大小的辅助空间,每个待排序的记录仅占有一个存储空间。堆的定义如下:n个元素的序列{k1, k2, … , kn}当且仅当满足下关系时,称之为堆。Ki <= K2i && Ki <= K2i+1 或 Ki >= K2i && Ki >= K2i+1,(i = 1, 2, … , n/2」)。若将和此序列对应的一维数组看成是一个完全二叉树,则堆的含义表明,完全二叉树中所有非终端结点的值均不大于(或不小于)其左、右孩子结点的值。则堆顶元素(或完全二叉树的根)必为序列中n个元素的最小值(或最大值)。

理解:若在输出堆顶的最小值之后,使得剩余的n – 1个元素的序列重又建成一个堆,则得到n个元素中的次小值。如此反复执行,便能得到一个有序序列,这个过程称之为堆排序。时间复杂度为O(nlogn)

注意:在进行堆排序是,由于下标的位置是使用父节点乘以2计算的,这样的话,对于数组来说,应该舍去第一个位置,从下表为1的位置开始使用,否则会出错。

//将下标序号从s到m的元素调整为大顶堆,其中除关键下标为s的记录外,其他元素已经构成了大顶堆
template <typename T>
void heapAdjust(vector<T>& array,int s,int m)
{
	T rc = array[s];//记录下需要调整的位置的记录

	//其中s保存的是需要调整的位置,j保存的是应该和s交换记录的位置
	for (int j = 2 * s;j <= m;j *= 2)
	{
		if (j < m && array[j] < array[j+1])//较大的记录与s进行交换,位置由j保存
			j++;

		if (rc >= array[j])//如果s比左右子节点均大,那么不用调整,原来的结构已经满足大顶堆要求
			break;

		array[s] = array[j];
		s = j;
	}
	array[s] = rc;
}

template <typename T>
void heapsort(vector< T >& array,int length)
{
	for (int i = length/2;i > 0;i--)//将无序表建成一个大顶堆
	{
		heapAdjust(array,i,length);
	}

	for (int j = length;j > 1;j--)//每次讲堆顶元素与堆的最后一个元素(不是所有元素的最后一个,是原来的一个子集)交换,然后调整堆结构
	{
		T temp = array[j];
		array[j] = array[0];
		array[1] = temp;

		heapAdjust(array,1,j-1);//调整新的堆
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值