#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;
}
}
heap.cpp
最新推荐文章于 2025-03-13 21:33:02 发布