0.1)本文总结于 数据结构与算法分析;源代码均为原创, 旨在了解到我们学习了优先队列后,还能干些什么东西出来, 增加学习的interest;
0.2)以下列出了 关于二叉堆(优先队列)的其他有用的操作, 其内容基本可以囊括大部分的优先队列知识点, 亮点是这里还引入到了 堆排序;
0.3)二叉堆的insert 和 deleteMin 基本操作和概念,参见 http://blog.csdn.net/pacosonswjtu/article/details/49498023
1.1)降低关键字的值——decreaseKey
1.2)增加关键字的值——increaseKey
1.3)删除某个位置上的元素——deleteElement
1.4)构建堆——buildHeap
1.5)优先队列的应用(我这里只列出 了选择问题, 当然远远不止这一个应用, 这个应用我还没有编写源代码实现)
Attention)
2.0)Warning of percolateDown :
2.1)download source code :
https://github.com/pacosonTang/dataStructure-algorithmAnalysis/tree/master/chapter6
2.2)source code at a glance:
[1st file binaryheap.h]
#include <stdio.h>
#include <malloc.h>
#define ElementType int
#define Error(str) printf("\n error: %s \n",str)
struct BinaryHeap;
typedef struct BinaryHeap *BinaryHeap;
void swap(ElementType *x, ElementType *y);
BinaryHeap initBinaryHeap(int capacity);
void insert(ElementType value, BinaryHeap bh);
ElementType deleteMin(BinaryHeap);
int isFull(BinaryHeap bh);
int isEmpty(BinaryHeap bh);
void percolateUp(int index, BinaryHeap bh);
void percolateDownFromOne(int index, BinaryHeap bh);
void printBinaryHeap(BinaryHeap bh);
void printBinaryHeapFromZero(BinaryHeap bh);
struct BinaryHeap
{
int capacity;
int size;
ElementType *elements;
};
[2st file binaryHeapBasicOperation.c]
#include "binaryheap.h"
//judge whether the BinaryHeap is full or not , also 1 or 0
int isFull(BinaryHeap bh)
{
return bh->size == bh->capacity - 1 ? 1 : 0 ;
}
//judge whether the BinaryHeap is empty or not , also 1 or 0
int isEmpty(BinaryHeap bh)
{
return bh->size == 0 ? 1 : 0 ;
}
void swap(ElementType *x, ElementType *y)
{
ElementType temp;
temp = *x;
*x = *y;
*y = temp;
}
// get the left child of node under index with startup 1
int leftChildFromOne(int index)
{
return index * 2;
}
ElementType deleteMin(BinaryHeap bh)
{
ElementType minimum;
ElementType *data;
if(isEmpty(bh))
{
Error("failed deleting minimum , for the BinaryHeap is empty, from func deleteMin !");
return -1;
}
data = bh->elements;
minimum = data[1];
swap(&data[1], &data[bh->size]);
bh->size-- ; // size-- occurs prior to percolateDownFromOne
percolateDownFromOne(1, bh) ;
return minimum;
}
// Attention, the index of the heap starts from 1
void insert(ElementType value, BinaryHeap bh)
{
int i;
if(isFull(bh))
{
Error("failed insertion , for the BinaryHeap is full, from func insert!");
return ;
}
for(i = ++bh->size; bh->elements[i/2] > value; i /= 2)
bh->elements[i] = bh->elements[i / 2];
bh->elements[i] = value;
}
BinaryHeap initBinaryHeap(int capacity)
{
BinaryHeap bh;
ElementType *temp;
bh = (BinaryHeap)malloc(sizeof(struct BinaryHeap));
if(!bh) {
Error("out of space, from func initBinaryHeap");
return NULL;
}
bh->capacity = capacity;
bh->size = 0;
temp = (ElementType *)malloc(capacity * sizeof(ElementType));
if(!temp) {
Error("out of space, from func initBinaryHeap");
return NULL;
}
bh->elements = temp;
return bh;
}
void printBinaryHeap(BinaryHeap bh)
{
int i;
ElementType *temp;
if(!bh)
Error("printing execution failure, for binary heap is null, from func printBinaryHeap");
temp = bh->elements;
for(i = 1; i < bh->capacity; i++)
{
printf("\n\t index[%d] = ", i);
if(i <= bh->size)
printf("%d", bh->elements[i]);
else
printf("NULL");
}
printf("\n");
}
//print the binary heap who starts from index 0
void printBinaryHeapFromZero(BinaryHeap bh)
{
int i;
ElementType *temp;
if(!bh)
Error("printing execution failure, for binary heap is null, from func printBinaryHeap");
temp = bh->elements;
for(i = 0; i < bh->capacity; i++)
{
printf("\n\t index[%d] = ", i);
if(i < bh->size)
printf("%d", bh->elements[i]);
else
printf("NULL");
}
printf("\n");
}
[3rd file binaryHeapOtherOperation.c]
#include "binaryheap.h"
#define Infinity 10000
// switch the elements
void swap(ElementType *x, ElementType *y)
{
ElementType temp;
temp = *x;
*x = *y;
*y = temp;
}
// get the parent of the element with index
int parentFromOne(int index)
{
return index / 2;
}
// percolating up the element when its value is greater than children (minimal heap)
//Attention: all of bh->elements starts from index 1
void percolateUpFromOne(int index, BinaryHeap bh)
{
ElementType *data;
ElementType temp;
int size;
int parent;
data = bh->elements;
size = bh->size;
for(temp = data[index]; parentFromOne(index) > 0; index = parent)
{
parent = parentFromOne(index);
if(parent == 0 || temp > data[parent])
break;
else
data[index] = data[parent];
}
data[index] = temp;
}
// get the left child of node under index with startup one
int leftChildFromOne(int index)
{
return index * 2;
}
// percolating down the element when its value is greater than children (minimal heap)
//Attention: all of bh->elements starts from index 1
void percolateDownFromOne(int index, BinaryHeap bh)
{
ElementType *data;
int size;
ElementType temp;
int child;
data = bh->elements;
size = bh->size;
for(temp = data[index]; leftChildFromOne(index) <= size; index = child)
{
child = leftChildFromOne(index);
if(child < size && data[child] > data[child+1])
child++;
if(temp > data[child])
data[index] = data[child];
else
break;
}
data[index] = temp;
}
//decreasing value of the element under index by increment
void decreaseKey(int index, ElementType decrement, BinaryHeap bh)
{
if(index > bh->size || index < 1)
{
Error(" failed decreaseKey, since overstep the boundary! ");
return ;
}
bh->elements[index] -= decrement; // update the element under given index
percolateUpFromOne(index, bh);
}
//increasing value of the element under index by increment
void increaseKey(int index, ElementType increment, BinaryHeap bh)
{
if(index > bh->size || index < 1)
{
Error(" failed increaseKey, since overstep the boundary! ");
return ;
}
bh->elements[index] += increment; // update the element under given index
percolateDownFromOne(index, bh);
}
//deleting the element under index
void deleteElement(int index, BinaryHeap bh)
{
decreaseKey(index, Infinity, bh); // 1st step, decreaseKey operation placing the element under index upto the root
deleteMin(bh); //2nd step, deleteMin deleting the element under the root;
}
// get the left child of node under index with startup zero
int leftChildFromZero(int index)
{
return index * 2 + 1;
}
// percolating down the element when its value is greater than children (minimal heap)
//Attention: all of bh->elements starts from index 0
void percolateDownFromZero(int index, BinaryHeap bh)
{
ElementType *data;
ElementType temp;
int size;
int child;
data = bh->elements;
size = bh->size;
for(temp = data[index]; leftChildFromZero(index) < size; index = child)
{
child = leftChildFromZero(index);
if(child < size - 1 && data[child] > data[child+1])
child++;
if(temp > data[child])
data[index] = data[child];
else
break;
}
data[index] = temp;
}
// building the heap with data in array randomly
void buildHeap(BinaryHeap bh)
{
int i;
ElementType *data;
data = bh->elements;
for(i = bh->size/2; i >= 0; i--)
percolateDownFromZero(i, bh);
}
int main()
{
ElementType data[] = {85, 80, 40, 30, 10, 70, 110}; // P141
ElementType buildHeapData[] = {150, 80, 40, 30, 10, 70, 110, 100, 20, 90, 60, 50, 120, 140, 130};
BinaryHeap bh;
int size;
int i;
int capacity;
printf("\n\t=== test for inserting the binary heap with {85, 80, 40, 30, 10, 70, 110} in turn ===\n");
capacity = 14;
bh = initBinaryHeap(capacity);
size = 7;
for(i = 0; i < size; i++)
insert(data[i], bh);
printBinaryHeap(bh);
printf("\n\t=== test for inserting the binary heap with {100, 20, 90} in turn ===\n");
insert(100, bh);
insert(20, bh);
insert(90, bh);
printBinaryHeap(bh);
printf("\n\t=== test for inserting the binary heap with 5 ===\n");
insert(5, bh);
printBinaryHeap(bh);
printf("\n\t=== test for 3 deletings towards the minimum in binary heap ===\n");
deleteMin(bh);
printBinaryHeap(bh);
deleteMin(bh);
printBinaryHeap(bh);
deleteMin(bh);
printBinaryHeap(bh);
// other operations in bianry heap
printf("\n\t====== test for other operations in bianry heap as follows ======\n");
printf("\n\t=== test for increaseKey(4, 120, bh) ===\n");
increaseKey(4, 120, bh);
printBinaryHeap(bh);
printf("\n\t=== test for increaseKey(2, 120, bh) ===\n");
increaseKey(2, 120, bh);
printBinaryHeap(bh);
printf("\n\t=== test for decreaseKey(9, 195, bh) ===\n");
decreaseKey(9, 195, bh);
printBinaryHeap(bh);
printf("\n\t=== test for decreaseKey(4, 90, bh) ===\n");
decreaseKey(4, 90, bh);
printBinaryHeap(bh);
printf("\n\t=== test for decreaseKey(7, 50, bh) ===\n");
decreaseKey(7, 50, bh);
printBinaryHeap(bh);
printf("\n\t=== test for decreaseKey(5, 155, bh) ===\n");
decreaseKey(5, 155, bh);
printBinaryHeap(bh);
printf("\n\t=== test for deleteElement(4, bh) ===\n");
deleteElement(4, bh);
printBinaryHeap(bh);
printf("\n\t=== test for deleteElement(1, bh) ===\n");
deleteElement(1, bh);
printBinaryHeap(bh);
printf("\n\t=== test for deleteElement(3, bh) ===\n");
deleteElement(3, bh);
printBinaryHeap(bh); // test over , Bingo!
// as you know, the build heap operation is identical with other operations
printf("\n\t=== test for building heap with {150, 80, 40, 30, 10, 70, 110, 100, 20, 90, 60, 50, 120, 140, 130} ===\n");
capacity = 16;
bh = initBinaryHeap(capacity);
bh->size = 15;
bh->elements = buildHeapData;
buildHeap(bh);
printBinaryHeapFromZero(bh);
return 0;
}