【數據結構】二叉樹之堆排序(完整代碼)

堆的概念
最小堆:任一結點的關鍵碼均小於等於它的左右孩子的關鍵碼,位於堆頂結點的關鍵碼最
最大堆:任一結點的關鍵碼均大於等於它的左右孩子的關鍵碼,位於堆頂結點的關鍵碼
最大
堆存儲在下標爲0開始計數的數組中,因此在堆中給定小標爲i的結點時:
1、如果i=0,結點i是根節點,沒有雙親節點;否則結點i的雙親結點爲結點(i-1)/2
2、如果2*i+1>n-1,則結點i無左孩子,否則結點i的左孩子爲結點2*i+1
3、如果2*i+2>n-1,則結點i無右孩子,否則結點i的右孩子爲結點2*i+2
堆排序的結點表示
typedef struct
{
	ElemType *data;
	int maxsize;
	int cursize;
}Heap;

堆的創建(最小堆)
//從結點(ArraySize-1)/2開始調整,將每一棵子樹都調整成一棵最小堆結構
void Make_Heap(Heap *hp)
{
	assert(hp != NULL);
	int end = hp->cursize -1;
	int pos = (end-1)/2;
	while(pos >= 0)
	{
		FilterDown(hp->data,pos,end);
		--pos;
	}
}


//檢測以i爲結點的子樹是否滿足最小堆,若滿足不調整,否則,調整。
void FilterDown(ElemType *ar,int start,int end)
{
	int i = start; // root;
	int j = i*2+1; // leftchild;
	ElemType tmp = ar[i];
	while(j <= end)
	{
		if(j < end && ar[j] >= ar[j+1]) j+=1;
		if(tmp <= ar[j])  break;
		
         ar[i] = ar[j];
		i = j;
		j = i*2+1;
	}
	ar[i] = tmp;
}
堆的單個元素插入
堆的插入每次都在已經建成的而最小堆的後面插入,但插入之後,有可能破壞了對的
結構,這時就需要對堆進行重新調整
void Insert_Heap(Heap *hp,ElemType *ar,int n)
{
	assert(hp != NULL &&  ar != NULL && n>0 );
	for(int i = 0;i<n;++i)
	{
		hp->data[i] = ar[i];
	}
	hp->cursize = n;
	Make_Heap(hp);
}
堆的數組插入
void Insert_Heap(Heap *hp,ElemType *ar,int n)
{
	assert(hp != NULL &&  ar != NULL && n>0 );
	for(int i = 0;i<n;++i)
	{
		hp->data[i] = ar[i];
	}
	hp->cursize = n;
	Make_Heap(hp);
}
堆的取棧頂
ElemType Pop_Heap(Heap *hp)
{
	assert(hp != NULL);
	int tmp = hp->data[0];
	Swap(hp->data[0],hp->data[hp->cursize-1]);
	hp->cursize -= 1;
	FilterDown(hp->data,0,hp->cursize-1);
	return tmp;
}

算法實現和程序代碼:

#include<stdio.h>
#include<malloc.h>
#include<assert.h>
#include<stdlib.h>
#include"Heap.h"

#define MINHEAP

template<class Type>
void Swap(Type &a,Type &b)
{
	Type tmp = a;
	a = b;
	b = tmp;
}
void FilterDown(ElemType *ar,int start,int end)
{
	int i = start; // root;
	int j = i*2+1; // leftchild;
	ElemType tmp = ar[i];
	while(j <= end)
	{
if(j < end && ar[j] >= ar[j+1]) j+=1;
		if(tmp <= ar[j])  break;
		
  ar[i] = ar[j];
		i = j;
		j = i*2+1;
	}
	ar[i] = tmp;
}
void FilerUp(ElemType *ar,int start)
{
	int j = start, i = (j-1)/2;
	ElemType tmp = ar[j];
	while(j > 0)
	{
#ifdef MINHEAP
		if(ar[i] <= tmp)
#else
		if(ar[i] >= tmp)
#endif
			break;
		ar[j] = ar[i];
		j = i;
		i = (j-1)/2;
	}
	ar[j] = tmp;

}
bool Init_Heap(Heap *hp)
{
	assert(hp!= NULL);
	hp->cursize = 0;
	hp->maxsize = HEAPSIZE;
	hp->data = (ElemType*)malloc(sizeof(ElemType)*hp->maxsize);
	if(hp->data == NULL) exit(1); // return false;
	return true;
}
void Destroy_Heap(Heap *hp)
{
	assert(hp != NULL);
	free(hp->data);
	hp->data = NULL;
	hp->maxsize = 0;
	hp->cursize = 0;

}
void Clear_Heap(Heap *hp)
{
	assert(hp != NULL);
	hp->cursize = 0;
}
bool Empty_Heap(Heap *hp)
{
	assert(hp != NULL);
	return hp->cursize == 0;
}
bool Full_Heap(Heap *hp)
{
	assert(hp != NULL);
	return hp->cursize == hp->maxsize;
}
int  Size_Heap(Heap *hp)
{
	assert(hp != NULL);
	return hp->cursize;
}
// Empty_Heap();
ElemType Pop_Heap(Heap *hp)
{
	assert(hp != NULL);
	int tmp = hp->data[0];
	Swap(hp->data[0],hp->data[hp->cursize-1]);
	hp->cursize -= 1;
	FilterDown(hp->data,0,hp->cursize-1);
	return tmp;
}


void Make_Heap(Heap *hp)
{
	assert(hp != NULL);
	int end = hp->cursize -1;
	int pos = (end-1)/2;
	while(pos >= 0)
	{
		FilterDown(hp->data,pos,end);
		--pos;
	}
}
void Insert_Heap(Heap *hp,ElemType *ar,int n)
{
	assert(hp != NULL &&  ar != NULL && n>0 );
	for(int i = 0;i<n;++i)
	{
		hp->data[i] = ar[i];
	}
	hp->cursize = n;
	Make_Heap(hp);
}

void Push_Heap(Heap *hp,ElemType x)
{
	assert(hp != NULL);
	if(Full_Heap(hp))
	{
		// Inc_Heap(ph);
	}
	hp->data[hp->cursize] = x;
	hp->cursize +=1;
	FilerUp(hp->data,hp->cursize - 1);
}


















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章