算法--堆排序

堆排序

        是一种在位的排序,也就是在任何时候,数组中只有常数个元素存储在数组外,在堆中分别分为大顶堆与小顶堆,也就是最大的元素在堆顶或者最小的元素在堆顶。

快速排序的实现往往要优于堆排序。它可以作为高效的优先级队列。

       最大优先级队列的一个应用就是在分是计算机进行作业调度。要对作业间的优先关系加以记录。当作业被中断后,选择具有高级优先级的作业,最小优先级队列的应用:基于事件驱动的模拟器中,队列中各项是模拟的事件,每一个都有一个发生时间作为其关键字。

      堆可以被视作为一个完全的二叉树。

两个属性:

1)每个结点的值不会小于它的子结点的值(但是在子结点中是无序的)

2)树是完全平衡的,最底层的叶子结点都位于最左边的位置上

缺点:

数据移动的幅度很大,将数组中最左边的元素移到右边花费的时间很多,因为移动后就要重新的调整堆。时间复杂度为O(n)+O(nlogn)+(n-1)=O(nlogm)

主要思想:

将最大的元素放在数组的末尾,重新调整堆的结构。接着将第二大的元素放在最大元素前面那个位置。于是没循环一次就会有一个元素在堆的末尾,堆中元素被移走一个。


template<class T>
void HeapTree<T>::MAX_HEAPIFY(T *heapArray,int index,int length)//执行时间为logn
{
	T temp;
	int changeIndex=0;
	while(index*2<length-1)
	{
		changeIndex=index*2+1;

		if (index*2+2<length)
		{
			if (*(heapArray+(index*2+1))<*(heapArray+(index*2+2)))
			{
				changeIndex=index*2+2;//与左子树进行比较
			}
		}
		if (*(heapArray+index)<*(heapArray+changeIndex))//若是孩子结点比当前的结点的值更大
		{
			temp=*(heapArray+index);
			*(heapArray+index)=*(heapArray+changeIndex);
			*(heapArray+changeIndex)=temp;
			index=changeIndex;//进行转换,也许下面会影响,继续的建堆
		}
		else
		{
			break;
		}
		
	}
}
template<class T>
void HeapTree<T>::BUILD_MAX_HEAP(T *heapArray,int length)//执行时间为O(n)
{
	nodeNum=length;
	for (int index=length/2;index>0;index--)
	{
		MAX_HEAPIFY(heapArray,index-1,length);//对每个元素进行判断,调整堆
	}
}
template<class T>
void  HeapTree<T>::HEAPSORT(T *heapArray,int length)//执行时间为nlog(n)
{
	//主要思想:首先将数组中元素构建成一个大顶堆。在构建的过程从最后一个节点的父节点开始,分析比较到最大元素到相应的位置
	//并将父节点替换到元素大的子结点的位置,这个时候可能子结点的子结点元素又会比这个更大,于是就有了函数中的循环判断
	//排序的过程:将顶元素与最后一个元素进行替换,这个时候顶元素必定是最大的元素,于是,就会有从小到大的排序。
	for (int index=length/2;index>0;index--)
	{
		MAX_HEAPIFY(heapArray,index-1,length);//对每个元素进行判断,调整堆
	}
	while(length>1)
	{	
	    T temp=*heapArray;
	    *heapArray=*(heapArray+length-1);
	    *(heapArray+length-1)=temp;
	    length--;	
		MAX_HEAPIFY(heapArray,0,length);//在堆中并不能保证左右子树的值的大小是按序的,于是采用,当前的与最后的交换
	}
}

template<class T>//返回最大元素,并删除这个元素,就是返回顶端元素
T HeapTree<T>::HEAP_EXTRACT_MAX(T *heapArray,int length)
{
	if(length<1)
	{
		cout<<"heap underflow";
	}
	T max=*heapArray;
	*heapArray=*(heapArray+length-1);
	*(heapArray+length-1)=max;
	MAX_HEAPIFY(heapArray,0,length-1);
	return max;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值