您的位置:首页 > 其它

优先级队列

2013-02-26 16:13 197 查看

前言

用最大堆实现的最大优先级队列一般用来进行作业调度的问题

用最小堆实现的最小优先级队列一般用于贪心等

概念

优先级队列是一种用来维护一组元素构成的集合S的数据结构,这一组元素中的每一个都有一个关键字key。
这里以最大堆实现的最大优先级队列为例,支持如下操作:

extract_max(A, n) : 去掉并返回A中的具有最大关键字的元素
increase_key(A, i, key) : 将元素A[i]关键字变为key并且保持最大优先级队列的性质

实现

extract_max

/**
* Description:从节点i开始,维护以i为根节点的子树,使以i为根的子树为最大堆(非递归)
*/
void maxHeapIfy(int *A, int i, int n)
{
int l, r, largest, temp, loc;

for(largest = i; largest <= n;)
{
l = 2 * largest;
r = 2 * largest + 1;
loc = largest;

if(l <= n && A[l] > A[largest])
{
largest = l;
}
if(r <= n && A[r] > A[largest])
{
largest = r;
}

//如果最大值不是根节点,那么交换A[loc], A[largest]
if(largest != loc)
{
temp = A[largest];
A[largest] = A[loc];
A[loc] = temp;
}else
{
break;
}
}
}

/**
* Description:去掉并返回A中具有最大关键字的元素
*/
int heapExtractMax(int *A, int n)
{
int max = A[1];

A[1] = A
;
MaxHeapIfy(A, 1, n - 1);

return max;
}


heap_increase_key

/**
* Description:将元素x的关键字的值增加到k
* heapIncreaseKey && maxHeapIfy 区别:
* heapIncreaseKey : 是当前结点的值增大了,因此要向上将父结点与该结点交换
* maxHeapIfy : 是保持当前结点为根的树是对,因此将当前结点与两个子结点比较,向下逐层恢复堆的性质。
*/
void heapIncreaseKey(int *A, int i, int key)
{
int parent, exchange;

for(A[i] = key, parent = i / 2; i >= 1 && A[parent] < A[i] && parent >= 1)
{
exchange = A[parent];
A[i] = A[parent];
A[i] = exchange;
i = parent;
parent = i / 2;
}
}


练习(哈夫曼树)

用最小堆实现求哈夫曼树的wpl

题目

题目描述:
哈夫曼树,第一行输入一个数n,表示叶结点的个数。需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出所有结点的值与权值的乘积之和。
输入:
输入有多组数据。
每组第一行输入一个数n,接着输入n个叶节点(叶节点权值不超过100,2<=n<=1000)。
输出:
输出权值。
样例输入:
5
1 2 2 5 9
样例输出:
37

ac代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAX 1001

void minHeapIfy(int *A, int i, int n);
void buildMinHeap(int *A, int n);
int heapExtractMin(int *A, int n);
void minHeapInsert(int *A, int i, int key);

int main()
{
int i, j, n, huff[MAX], power, lchild, rchild, parent;

while(scanf("%d", &n) != EOF)
{
//接收参数输入
for(i = 1; i <= n; i ++)
scanf("%d", &huff[i]);

//构建一个最小堆
buildMinHeap(huff, n);

//获取wpl
for(i = 1, j = n, power = 0; i < n; i ++)
{
lchild = heapExtractMin(huff, j);
j -= 1;
rchild = heapExtractMin(huff, j);

parent = lchild + rchild;
power += parent;

minHeapInsert(huff, j, parent);
}

printf("%d\n", power);
}

return 0;
}

/**
* Description:构建最小堆
*/
void buildMinHeap(int *A, int n)
{
int i;

for(i = n / 2; i >= 1; i --)
{
minHeapIfy(A, i, n);
}
}

/**
* Description:调整以i为根的最小堆
*/
void minHeapIfy(int *A, int i, int n)
{
int l, r, min, loc, temp;

for(min = i; min <= n;)
{
l = min * 2;
r = min * 2 + 1;
loc = min;

if(l <= n && A[l] < A[min])
min = l;
if(r <= n && A[r] < A[min])
min = r;

if(min != loc)
{
temp = A[min];
A[min] = A[loc];
A[loc] = temp;
}else
{
break;
}
}
}

int heapExtractMin(int *A, int n)
{
int min = A[1];
A[1] = A
;
minHeapIfy(A, 1, n);

return min;
}

/**
* Description:
* (1)将元素插入到最小优先队列
* (2)因为每次i == length(A),都是在对尾插入,因此只考虑i的parent,不考虑i的children
*/
void minHeapInsert(int *A, int i, int key)
{
int parent, change;

for(A[i] = key, parent = i / 2; parent >= 1 && A[parent] > A[i];)
{
change = A[parent];
A[parent] = A[i];
A[i] = change;
i = parent;
parent = i / 2;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: