heap.cpp

#include <iostream>

using namespace std;

struct HeapStruct;
typedef struct HeapStruct *PriorityQueue;

PriorityQueue Initialize(int MaxElements);
void Destroy(PriorityQueue H);
void MakeEmpty(PriorityQueue H);
void Insert(int X, PriorityQueue H);
int DeleteMin(PriorityQueue H);
int FindMin(PriorityQueue H);
int IsEmpty(PriorityQueue H);
int IsFull(PriorityQueue H);

#define MinPQSize (10)
#define MinData (-32767)

struct HeapStruct
{
	int Capacity;
	int Size;
	int *Elements;
};

PriorityQueue Initialize(int MaxElements)
{
	PriorityQueue H;

	if (MaxElements < MinPQSize)
	{
		cout << "Priority queue size is too small" << endl;
		return NULL;
	}

	H = (PriorityQueue)malloc(sizeof(struct HeapStruct));
	if (H == NULL)
	{
		cout << "Out of space!!!" << endl;
		return NULL;
	}

	/* Allocate the array plus one extra for sentinel */
	H->Elements = (int *)malloc((MaxElements + 1)
		* sizeof(int));
	if (H->Elements == NULL)
	{
		cout << "Out of space!!!" << endl;
		return NULL;
	}

	H->Capacity = MaxElements;
	H->Size = 0;
	H->Elements[0] = MinData; /* 哨兵 */

	return H;
}

void MakeEmpty(PriorityQueue H)
{
	H->Size = 0;
}

/* H->Element[ 0 ] is a sentinel
 * 平均时间 = O(1)
 * 最坏事件 = O(log N)
 */
void Insert(int X, PriorityQueue H)
{
	int i;

	if (IsFull(H))
	{
		cout << "Priority queue is full" << endl;
		return;
	}

	/* Percolate up */
	for (i = ++H->Size; H->Elements[i / 2] > X; i /= 2)
		H->Elements[i] = H->Elements[i / 2];
	H->Elements[i] = X;
}

/* 平均时间 = O(log N)
 * 最坏时间 = O(log N)
 */
int DeleteMin(PriorityQueue H)
{
	int i, Child;
	int MinElement, LastElement;

	if (IsEmpty(H))
	{
		cout << "Priority queue is empty" << endl;
		return H->Elements[0];
	}
	MinElement = H->Elements[1];
	LastElement = H->Elements[H->Size--];

	// 从根节点将空洞下滤
	for (i = 1; i * 2 <= H->Size; i = Child)
	{
		/* Find smaller child */
		Child = i * 2;
		if (Child != H->Size && H->Elements[Child + 1] < H->Elements[Child])
			Child++;

		/* Percolate one level */
		if (LastElement > H->Elements[Child])
			H->Elements[i] = H->Elements[Child];
		else
			break;  /* 关键 */
	}
	H->Elements[i] = LastElement;
	return MinElement;
}

int FindMin(PriorityQueue H)
{
	if (!IsEmpty(H))
		return H->Elements[1];
	cout << "Priority Queue is Empty" << endl;
	return H->Elements[0];
}

int IsEmpty(PriorityQueue H)
{
	return H->Size == 0;
}

int IsFull(PriorityQueue H)
{
	return H->Size == H->Capacity;
}

void Destroy(PriorityQueue H)
{
	free(H->Elements);
	free(H);
}

/* 堆排序 */
void Swap(int *Lhs, int *Rhs)
{
	int Tmp = *Lhs;
	*Lhs = *Rhs;
	*Rhs = Tmp;
}

void PercDown(int A[], int Parent, int N)
{
	int Child;
	int Tmp;

	for (Tmp = A[Parent]; (Child = Parent * 2 + 1) < N; Parent = Child)
	{
		//Child = Parent * 2 + 1;
		if (Child != N - 1 && A[Child + 1] > A[Child])
			Child++;
		if (Tmp < A[Child])
			A[Parent] = A[Child];
		else
			break;
	}
	A[Parent] = Tmp;
}

// O(N log N)
void Heapsort(int A[], int N)
{
	int i;

	/* BuildHeap, 平均时间 = O(N) */
	for (i = N / 2; i >= 0; i--)     // 从最后一个父节点开始下滤过程,构建一个最大堆
		PercDown(A, i, N);

	for (i = N - 1; i > 0; i--)
	{
		Swap(&A[0], &A[i]);  /* DeleteMax */
		PercDown(A, 0, i);
	}
}


// 建立一个最大堆,O(N)
void BuildHeap(int a[], int len)
{
	// 每个父节点下滤
	for (int parent = len / 2; parent >= 0; parent--)
	{
		int tmp = a[parent];
		while (2 * parent + 1 < len)
		{
			int child = 2 * parent + 1;
			if (child < len - 1 && a[child + 1] > a[child])
				child++;
			if (a[child] > tmp)
			{
				a[parent] = a[child];
				parent = child;
			}
			else
				break;
		}
		a[parent] = tmp;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值