堆排序(Heap Sort)

参照《数据结构》(C语言版)严蔚敏著

#include <iostream.h>

struct SqList
{
	int r[100];
	int length;
};

void HeapAjust(SqList &H, int s, int m);
void HeapSort(SqList &H);

int main(void)
{
	SqList H;  
    H.r[1]=49;  
    H.r[2]=38;  
    H.r[3]=65;  
    H.r[4]=97;  
    H.r[5]=76;  
    H.r[6]=13;  
    H.r[7]=27;  
    H.r[8]=49;  
    H.length=8;

	HeapSort(H);

	cout << endl;
	return 0;
}


void HeapAjust(SqList &H, int s, int m)
{//已知H.r[s..m]中记录的关键字除H.r[s]之外均满足堆定义
 //本函数调整H.r[s]的关键字,使H.r[s..m]成为一个大顶堆
	int rc=H.r[s];

	for(int j=s*2;j<=m;j*=2)
	{
		if(j<m && H.r[j]<H.r[j+1])
		{//找出当前结点的左右孩子结点中的较大者
			j++;
		}

		//将当前结点与孩子结点中的较大者比较
		if(rc>H.r[j]) 
		{//当前结点比孩子结点都大,则满足堆定义,则不再调整
			break;
		}
		else
		{//继续调整该结点
			H.r[s]=H.r[j];
			s=j;
		}
	}
	H.r[s]=rc;
}

void HeapSort(SqList &H)
{
	int temp;

	//把H.r[1..H.length]建成大顶堆
	for(int i=H.length/2;i>0;i--)
	{
		HeapAjust(H, i, H.length);
	}

	//摘取堆顶元素,形成堆排序
	for(i=H.length;i>=1;i--)
	{
		temp=H.r[1];
		H.r[1]=H.r[i];
		H.r[i]=temp;

		cout << temp << "  ";
		
		//将H.r[1..i-1]重新调整成大顶堆
		HeapAjust(H,1,i-1);
	}
}


运行结果:



堆排序小结: 

堆排序方法对记录数较少的文件并不值得提倡,但对n较大的文件还是很有效的。因为其运行时间主要耗费在创建初始堆和调整建新堆时进行的反复“筛选”上。

堆排序方法在最坏的情况下,其时间复杂度也为O(nlogn)。相对于快速排序来说,这是堆排序的最大优点。

而且堆排序方法仅需要一个辅助存储空间,供记录大小的交换。

你可能感兴趣的:(堆排序(Heap Sort))