1. 程式人生 > >【排序演算法7】堆排序

【排序演算法7】堆排序

此排序演算法完全是看著MoreWindows大神的部落格一邊看一邊體會一邊跟著敲出來的,在這裡還是非常感謝他。

部落格地址https://blog.csdn.net/MoreWindows/article/details/6709644

上述地址對堆排序講的很細緻,這裡就不講了。但是不知道為什麼那篇部落格中評論裡會這麼多人說有錯誤。

#include <stdio.h>
#include <Windows.h>

void Swap(int *a,int *b)
{
	int temp = *a;
	*a = *b;
	*b = temp;
}

void Print(int a[],int n)
{
	for( int i = 0 ; i < n ; ++i )
	{
		printf("%d ",a[i]);
	}
	printf("\n");
}


//  新加入i節點,其父節點為(i-1)/2
void MinHeapFixup(int a[] ,int i)
{
	int j,temp;
	temp = a[i];
	j = (i - 1) / 2;  //父節點
	while( j >= 0 && i != 0 )
	{
		if(j >= 0 && i != 0)
		{
			break;
		}
		a[i] = temp;
		i = j;  //向父節點遞迴,當前這個i表示父節點 
		j = (i - 1) / 2;
	}
	a[i] = temp;
}

//堆的插入
void MinHeapAddNumber(int a[],int n,int nNum)
{
	a[n] = nNum;
	MinHeapFixup(a,n);
}

//調整堆
void MinHeapFixdown(int a[],int i,int n)
{
	int j,temp;
	temp = a[i];
	j = 2 * i + 1;
	while( j < n )
	{
		if( j + 1 < n && a[j + 1] < a[j] )
		{
			++j;
		}
		if( a[j] >= temp )
		{
			break;
		}
		a[i] = a[j];
		i = j;
		j = 2 * i + 1;
	}
	a[i] = temp;
}

//在最小堆中刪除數
void MinHeapDeleteNumber( int a[],int n )
{
	Swap( &a[0] ,&a[n - 1] );
	MinHeapFixdown(a,0,n - 1);
	Print(a,n);
}

//建立最小堆
void MakeMinHeap(int a[],int n)
{
	//葉子節點不用排
	for( int i = n / 2 - 1 ; i >= 0 ; --i)
	{
		MinHeapFixdown(a,i,n);
		printf("下沉的節點%d. ",i);
		Print(a,n);
	}
}

void MinheapsortTodescendarray(int a[],int n)
{
	MakeMinHeap(a,n);
	for( int i = n ; i >= 1 ; --i )
	{
		MinHeapDeleteNumber(a,i);
	}
}

int main()
{
	int a[10] = {9,12,17,30,50,20,60,65,4,49};
	MinheapsortTodescendarray(a,10);
	for( int i = 0 ; i < 10 ; ++i )
	{
		printf("%d ",a[i]);
	}
	printf("\n");
	system("pause");
	return 0;
}

列印結果如下圖,最小堆實現的降序排序

列印結果