排序演算法__堆排序

Enjoy_process發表於2019-03-08

                                                    排序演算法__堆排序

 

 

一、介紹

堆排序是指利用堆這種資料結構所設計的一種排序演算法。堆是一個近似完全二叉樹的結構,並同時滿足堆積的性質:即子結點的鍵值或索引總是小於(或者大於)它的父節點。 

 

二、C++實現

最大堆實現升序 

#include<iostream>
#include<algorithm>

using namespace std;

//最大堆向下調整演算法 
void down(int a[],int start,int end)
{
	int c=start,tmp=a[c];//c表示當前元素,tmp表示要調整元素start的值 
	for(int l=2*c+1;l<=end;c=l,l=2*l+1) 
	{
		if(l<end&&a[l]<a[l+1]) l++;//選擇左右孩子較大者 
		if(a[c]>=a[l]) break;//如果當前元素的值大於等於它的左右孩子,則退出(滿足最大堆的要求了) 
		//否則就讓它和它的孩子交換(值較大的一個孩子) 
		a[c]=a[l]; 
		a[l]=tmp;
	}
} 

//堆排序,構建最大堆,升序排列 
void heapSort(int a[],int n)
{
	//先構建最大堆,n/2-1是最後一個有孩子的結點 
	for(int i=n/2-1;i>=0;i--) down(a,i,n-1); 
	for(int i=n-1;i>0;i--)
	{
		swap(a[0],a[i]);//將此時的最大值即a[0]和a[i]交換 
		down(a,0,i-1);//將元素a[0]向下調整,直至滿足最大堆的定義 
	}
}

int main()
{
	int a[]={10,9,8,7,6,5,4,3,2,1};
	int len=sizeof(a)/sizeof(a[0]);
	printf("排序前:");
	for(int i=0;i<len;i++)
	  printf("%d ",a[i]);
	heapSort(a,len);
	printf("\n排序後:");
	for(int i=0;i<len;i++)
	  printf("%d ",a[i]);
	return 0;
}

最小堆實現降序

#include<iostream>
#include<algorithm>

using namespace std;

void down(int a[],int start,int end)
{
	int c=start,tmp=a[c];//c表示當前元素,tmp表示要調整元素start的值 
	for(int l=2*c+1;l<=end;c=l,l=2*l+1)
	{
		if(l<end&&a[l]>a[l+1]) l++;//選擇左右孩子較小者 
		//如果當前元素的值小於等於它的左右孩子,則退出(滿足最小堆的要求了) 
		if(a[c]<=a[l]) break;
		//否則就讓它和它的孩子交換(值較小的一個孩子) 
		a[c]=a[l];
		a[l]=tmp;
	}
}

//堆排序,構建最小堆,降序排列 
void heapSort(int a[],int n)
{
	//先構建最小堆,n/2-1是最後一個有孩子的結點 
	for(int i=n/2-1;i>=0;i--) down(a,i,n-1);
	for(int i=n-1;i>0;i--)
	{
		swap(a[0],a[i]);//將此時的最小值即a[0]和a[i]交換 
		down(a,0,i-1);//將元素a[0]向下調整,直至滿足最小堆的定義 
	}
}

int main()
{
	int a[]={1,2,3,4,5,6,7,8,9,10};
	int len=sizeof(a)/sizeof(a[0]);
	printf("排序前:");
	for(int i=0;i<len;i++)
	  printf("%d ",a[i]);
	heapSort(a,len);
	printf("\n排序後:");
	for(int i=0;i<len;i++)
	  printf("%d ",a[i]);
	return 0;
}

 

三、時間複雜度和穩定性

堆排序是不穩定的演算法。時間複雜度為O(nlogn)

相關文章