排序----堆排序

1、堆數據結構

        堆數據結構:是一種數組對象。它可以視爲一個完全二叉樹,數中的每個節點和數組的每個元素一一對應。

        最大根堆:堆中最大值存放在根節點中。並且以某一節點爲根的子樹中,各節點的值都不大於該子樹根結點的值。

2、維護堆的性質

        我們假設某一節點A[i],以A[i]的左孩子A[LEFT[i]]和右孩子A[RIGHT[i]]爲根的兩棵子樹都是最大根堆,但這時A[i]可能小於其子女,這樣就違反了最大根堆的性質。所以,我們需要做出相應的調整,使其滿足最大根堆的性質。

        在A[LEFT[i]]和A[RIGHT[i]]中找出最大的,然後將其下標保存在largest中,如果A[i]是最大的,則以i爲根的子樹是最大根堆,程序結束。否則,交換A[i]和A[largest],從而使其子女滿足最大根堆性質。但是下標爲largest的節點交換後值是A[i],以該節點爲根的子樹又有可能破壞最大根堆的性質,因此我們還需要對以largest爲節點的子樹遞歸調用維護堆性質的函數。

維護堆性質的函數:

//更新堆,保持堆的性質
//輸入數組a,需調整的子樹根節點i,數組長度len
void MaxHeapIfy(int *a,int i,int len)
{
	int largest=i,temp;
	if(2*i<=len&&a[2*i]>a[i])
	{
		largest=2*i;
	}
	if(2*i+1<=len&&a[2*i+1]>a[largest])
	{
		largest=2*i+1;
	}
	if(largest!=i)
	{
		temp=a[i];
    	a[i]=a[largest];
    	a[largest]=temp;
		MaxHeapIfy(a,largest,len);
	}	
}

3、創建最大根堆

        我們看可以自底向上的調用MaxHeapIfy函數來將一個數組(數組A從1到n存放元素,A[0]不存放有效元素,便於後面操作)變成一個最大根堆。我們知道子數組A[[n/2]+1,...,n]中的元素都是子樹的葉子,因此可以單獨看成只含一個元素的堆。所以只需要對其與元素調用MaxHeapIfy函數以創建最大根堆。

創建最大根堆函數如下:

//創建最大根堆
//輸入數組a,數組最後一個元素位置n
void BuildMaxHeap(int *a,int n)
{
	for (int i=n/2;i>0;i--)
	{
		MaxHeapIfy(a,i,n);
	}
}

4、堆排序

        首先將數組變成一個最大根堆,然後將根元素和數組最後一個元素互換,這樣數組最後一個元素存放的是數組最大值。然後從堆中"去掉"節點n,將剩餘的節點變成最大堆,繼續前面一樣的操作,直至最大根堆中只剩下一個根節點,此時數組排序完畢。

//堆排序
//輸入數組a,數組最後一個元素位置n
void HeapSort(int *a,int n)
{
	BuildMaxHeap(a,n);
	for (int i=n;i>0;)
	{
		int temp=a[1];
		a[1]=a[i];
		a[i]=temp;
    	MaxHeapIfy(a,1,--i);
	}
}

5、堆排序完整程序如下:

#include "stdafx.h"
#include "iostream.h"
#include "string.h"
#include <time.h>
#include <stdlib.h>

//更新堆,保持堆的性質
//輸入數組a,需調整的子樹根節點i,數組長度len
void MaxHeapIfy(int *a,int i,int len)
{
	int largest=i,temp;
	if(2*i<=len&&a[2*i]>a[i])
	{
		largest=2*i;
	}
	if(2*i+1<=len&&a[2*i+1]>a[largest])
	{
		largest=2*i+1;
	}
	if(largest!=i)
	{
		temp=a[i];
    	a[i]=a[largest];
    	a[largest]=temp;
		MaxHeapIfy(a,largest,len);
	}	
}
//創建最大根堆
//輸入數組a,數組最後一個元素位置n
void BuildMaxHeap(int *a,int n)
{
	for (int i=n/2;i>0;i--)
	{
		MaxHeapIfy(a,i,n);
	}
}
//堆排序
//輸入數組a,數組最後一個元素位置n
void HeapSort(int *a,int n)
{
	BuildMaxHeap(a,n);
	for (int i=n;i>0;)
	{
		int temp=a[1];
		a[1]=a[i];
		a[i]=temp;
    	MaxHeapIfy(a,1,--i);
	}
}

int main(int argc, char* argv[])
{
	int a[]={0,23,5,35,32,435,42,75,24,24,12,64,53,31,97,75,324,75,86,9,54,24,235};
	int len=sizeof(a)/sizeof(int);
	HeapSort(a,len-1);
	for (int i=0;i<len;i++)
	{
		cout<<a[i]<<" ";
	}
	cout<<endl;

	return 0;
}


 

發佈了96 篇原創文章 · 獲贊 19 · 訪問量 57萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章