1. 程式人生 > >資料結構—堆的學習:堆化陣列、堆的插入、堆的刪除

資料結構—堆的學習:堆化陣列、堆的插入、堆的刪除

原網頁:http://blog.csdn.net/morewindows/article/details/6709644

程式如下:

//資料結構堆的建立(堆化陣列)、堆的插入和刪除
#include<stdio.h>
#include <stdlib.h>
//交換兩個元素值
void swap(int &a,int &b)
{
	if(a!=b)
	{
		a=a^b;
		b=a^b;
		a=a^b;
	}
}
//從結點i處開始調整,使之成為最小堆 n為結點總數,一般從0開始計算, i結點的子節點為2*i+1,2*i+2  將大數下沉
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])       //找出i結點子節點的最小的
		   j++;
		if (a[j]>=temp)               //子節點最小值大於父結點,即找到父節點應該放的位置:最後一次更新的i
		   break;
		a[i]=a[j];                    //子節點最小值小於父節點的值,將較小的子節點往上移動過,替換它的父節點
		i=j;
		j=2*i+1;
		
	}
	a[i]=temp;
}

//調整為最大堆   將小的數下沉
void MaxHeapFixDown(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])       //找出i結點子節點的最大的
			j++;
		if (a[j]<temp)               //子節點最大值小於父結點,即找到父節點應該放的位置:最後一次更新的i
			break;
		a[i]=a[j];                    //子節點最大值大於父節點的值,將較小的子節點往上移動過,替換它的父節點,
		i=j;                          //並更新i,j
		j=2*i+1;

	}
	a[i]=temp;
}
//將陣列A進行堆化,即陣列經轉換後模擬的是一個最小堆
void MakeMinHeap(int a[],int n)           
{
	for (int i=n/2-1;i>=0;i--)
	      MinHeapFixDown(a,i,n);
}
//將陣列A進行堆化,即陣列經轉換後模擬的是一個最大堆
void MakeMaxHeap(int a[],int n)           
{
	for (int i=n/2-1;i>=0;i--)
		MaxHeapFixDown(a,i,n);
}
//陣列資料堆排序 最小堆 降序排序   前提:該陣列已是一個最小堆
void MinHeapSortDes(int a[],int n)
{
   for (int i=n-1;i>=1;i--)
   {
	   swap(a[i],a[0]);
	   MinHeapFixDown(a,0,i);
   }
}
//陣列資料堆排序 最大堆 升序排序   前提:該陣列已是一個最大堆
void MaxHeapSortDes(int a[],int n)
{
	for (int i=n-1;i>=1;i--)
	{
		swap(a[i],a[0]);
		MaxHeapFixDown(a,0,i);
	}
}
//堆的操作:插入與排序
//堆的插入:用陣列模擬堆,插入的元素在陣列的最後,插入後再調整堆
//新加入結點i其父節點為(i-1)/2   最小堆插入調整
void MinHeapFixup(int a[],int i)
{
	int j,temp;
	temp=a[i];
	j=(i-1)/2;
	while(j>=0)
	{
		if(a[j]<=temp)
			break;
		a[i]=a[j];
		if (0==j)
		{
		  a[j]=temp;
		  break;
		}		
		i=j;
		j=(i-1)/2;
	}
	if (j!=0)
	{
		a[i]=temp;
	}	
}
//在最小堆中插入資料nNum
void MinHeapInsert(int a[],int n,int nNum)
{
	a[n]=nNum;
	MinHeapFixup(a,n);
}
//堆的刪除:每次刪除第0個數據,將最後一個數據的值賦給根節點,然後調整堆
//在最小堆中刪除數
void MinHeapDeleteNumber(int a[],int n)
{
	swap(a[0],a[n-1]);         //交換第一個元素與最後一個元素(相當於刪除第一個元素)
	MinHeapFixDown(a,0,n-1);   //從上往下調整堆
}

//測試程式
int main()
{
	int A[]={9,12,17,30,50,20,60,65,4,49};
    int len=sizeof(A)/sizeof(A[0]);
	MakeMinHeap(A,len);               //最小化堆(堆化陣列)
//	MakeMaxHeap(A,len);               //最大化堆
    for (int i=0;i<len;i++)
		printf("%d ",A[i]);
	printf("\n");
	MinHeapDeleteNumber(A,len);      //堆的刪除
	/*MinHeapInsert(A,len,2);*/      //堆的插入
	for (int i=0;i<len;i++)
		printf("%d ",A[i]);
	printf("\n");
//	MaxHeapSortDes(A,len);          //堆排序 最大堆 升序
//     MinHeapSortDes(A,len);       //堆排序 最小堆 降序
// 	for (int i=0;i<len;i++)
// 		printf("%d ",A[i]);
// 	printf("\n");
// 	for (int i=0,j=len-1;i<j;i++,j--)         //陣列元素倒序
// 		swap(A[i],A[j]);
// 	for (int i=0;i<len;i++)
// 		printf("%d ",A[i]);
	system("pause");
	return 0;
}