/* 二叉堆(优先队列)的基本操作的测试(从小到大排列) */
#include <cstdio>
#include <cstdlib>
typedef struct _tBINARY_HEAP_
{
int max_size;
int current_size;
int *node;
}tBINARY_HEAP;
const int MAX_HEAP_SIZE = 10;
const int MIN_HEAP_NODE_VALUE = -11111111;
void percolate_down(tBINARY_HEAP *pHeap, int i);
void insert_node_to_binary_heap(tBINARY_HEAP *&pHeap, int value);
bool is_full_heap(tBINARY_HEAP *pHeap);
void show_heap_element(tBINARY_HEAP *pHeap);
//方法一. 插入节点到二叉堆, 逐渐建堆---有下滤过程
tBINARY_HEAP *create_binary_heap(void)
{
int num;
tBINARY_HEAP *pHeap = NULL;
scanf("%d", &num);
while (num != -999)
{
insert_node_to_binary_heap(pHeap, num);
scanf("%d", &num);
}
return pHeap;
}
void insert_node_to_binary_heap(tBINARY_HEAP *&pHeap, int value)
{
if (pHeap == NULL)
{
pHeap = new tBINARY_HEAP;
pHeap->max_size = MAX_HEAP_SIZE;
pHeap->current_size = 0;
pHeap->node = new int[MAX_HEAP_SIZE+1];
pHeap->node[pHeap->current_size] = MIN_HEAP_NODE_VALUE;
pHeap->node[++(pHeap->current_size)] = value;
}
else
{
if (is_full_heap(pHeap))
{
printf("heap is full.\n");
return;
}
int i;
for (i=++(pHeap->current_size); pHeap->node[i/2] > value; i /=2)
pHeap->node[i] = pHeap->node[i/2]; //跟父节点调换位置
pHeap->node[i] = value;
}
return;
}
//方法二, 先将所有的关键字插入空堆中, 然后下滤若干次变为二叉堆
tBINARY_HEAP *create_binary_heap2(const int element[], int num)
{
tBINARY_HEAP *pHeap;
int i;
pHeap = new tBINARY_HEAP;
pHeap->current_size = 0;
pHeap->max_size = num+1;
pHeap->node = new int[pHeap->max_size];
pHeap->node[0] = MIN_HEAP_NODE_VALUE;
for (i = 0; i < num; ++i)
pHeap->node[++(pHeap->current_size)] = element[i];
//对i节点下滤
for (i=pHeap->current_size/2; i>=1; --i)
percolate_down(pHeap, i);
return pHeap;
}
void percolate_down(tBINARY_HEAP *pHeap, int i)
{
if (pHeap == NULL)
return;
int child, tmp;
for (int j = i; j * 2 <= pHeap->current_size; j = child)
{
child = j * 2;
tmp = pHeap->node[j];
if (child != pHeap->current_size) //节点总数为偶数
{
if (pHeap->node[child+1] < pHeap->node[child])
child++;
}
if (pHeap->node[j] > pHeap->node[child])
{
pHeap->node[j] = pHeap->node[child];
pHeap->node[child] = tmp;
}
}
}
bool is_full_heap(tBINARY_HEAP *pHeap)
{
if (pHeap == NULL)
return true;
if (pHeap->current_size > pHeap->max_size)
return true;
return false;
}
bool is_empty_heap(tBINARY_HEAP *pHeap)
{
if (pHeap == NULL)
return true;
if (pHeap->current_size == 0) //node[0]作为哨兵
return true;
return false;
}
//删除堆中的最小元素---有上滤过程
int delete_min_node(tBINARY_HEAP *&pHeap)
{
if (pHeap == NULL)
return NULL;
if (is_empty_heap(pHeap))
{
printf("heap is null.\n");
return pHeap->node[0];
}
int min_node = pHeap->node[1];
int last_node = pHeap->node[pHeap->current_size--];
int child, i;
for (i = 1; i * 2 <= pHeap->current_size; i = child)
{
child = i * 2;
if (child != pHeap->current_size && pHeap->node[child] > pHeap->node[child+1]) //当堆的节点是偶数时
child++;
if (last_node > pHeap->node[child]) //最后一个节点大于空穴的最小孩子, 空穴的最小孩子上移到空穴位置
pHeap->node[i] = pHeap->node[child];
else
break;
}
pHeap->node[i] = last_node;
return min_node;
}
void show_heap_element(tBINARY_HEAP *pHeap)
{
for (int i = 0; i <= pHeap->current_size; ++i)
printf("%d ", pHeap->node[i]);
}
void destory_heap(tBINARY_HEAP *&pHeap)
{
delete [](pHeap->node); pHeap->node = NULL;
delete pHeap; pHeap = NULL;
return;
}
int main(void)
{
int a[] = {4, 3, 6, 1, -3, 0, 5, 9, -30, 34};
//int b[] = {150, 80, 40, 30, 10, 70, 110, 100, 20, 90, 60, 50, 120, 140, 130};
//tBINARY_HEAP *pHeap = create_binary_heap2(b, sizeof(b)/sizeof(b[0]));
tBINARY_HEAP *pHeap = create_binary_heap2(a, sizeof(a)/sizeof(a[0]));
show_heap_element(pHeap);
destory_heap(pHeap);
printf("\n");
pHeap = create_binary_heap();
show_heap_element(pHeap);
destory_heap(pHeap);
printf("\n");
return 0;
}
二叉堆(优先队列)的基本操作的测试
最新推荐文章于 2022-10-04 16:25:54 发布