手机
当前位置:查字典教程网 >编程开发 >C语言 >优先队列(priority_queue)的C语言实现代码
优先队列(priority_queue)的C语言实现代码
摘要:优先队列(priority_queue)和一般队列(queue)的函数接口一致,不同的是,优先队列每次出列的是整个队列中最小(或者最大)的元...

优先队列(priority_queue)和一般队列(queue)的函数接口一致,不同的是,优先队列每次出列的是整个队列中最小(或者最大)的元素。

本文简要介绍一种基于数组二叉堆实现的优先队列,定义的数据结构和实现的函数接口说明如下:

一、键值对结构体:KeyValue

复制代码 代码如下:

// =============KeyValue Struct==================================

typedef struct key_value_struct KeyValue;

struct key_value_struct

{

int _key;

void *_value;

};

KeyValue *key_value_new(int key, void *value);

void key_value_free(KeyValue *kv, void (*freevalue)(void *));

键值对作为优先队列的中数据的保存形式,其中key用于保存优先级,_value用于指向实际的数据。

key_value_new用于创建一个KeyValue结构体;key_value_free用于释放一个KeyValue结构体的内存,

参数freevalue用于释放数据指针_value指向的内存。

二、优先队列结构体:PriorityQueue

复制代码 代码如下:

// =============PriorityQueue Struct==============================

#define PRIORITY_MAX 1

#define PRIORITY_MIN 2

typedef struct priority_queue_struct PriorityQueue;

struct priority_queue_struct

{

KeyValue **_nodes;

int _size;

int _capacity;

int _priority;

};

PriorityQueue *priority_queue_new(int priority);

void priority_queue_free(PriorityQueue *pq, void (*freevalue)(void *));

const KeyValue *priority_queue_top(PriorityQueue *pq);

KeyValue *priority_queue_dequeue(PriorityQueue *pq);

void priority_queue_enqueue(PriorityQueue *pq, KeyValue *kv);

int priority_queue_size(PriorityQueue *pq);

int priority_queue_empty(PriorityQueue *pq);

void priority_queue_print(PriorityQueue *pq);

1) 其中nodes字段是二叉堆数组,_capacity是nodes指向的KeyValue*指针的个数,_size是nodes中实际存储的元素个数。

_priority可以是PRIORITY_MAX或PRIORITY_MIN,分别表示最大元素优先和最小元素优先。

2) priority_queue_new和priority_queue_free分别用于创建和释放优先队列。

3) priority_queue_top用于取得队列头部元素,

4)priority_queue_dequeue用于取得队列头部元素并将元素出列。

其实现的基本思路,以最大优先队列说明如下:

①将队列首部nodes[0]保存作为返回值

②将队列尾部nodes[_size-1]置于nodes[0]位置,并令_size=_size-1

③令当前父节点parent(nodes[i])等于新的队列首部(i=0)元素,

parent指向元素的儿子节点为left = nodes[2 * i + 1]和rigth = nodes[2 * i + 2],

比较left和right得到优先级高的儿子节点,设为nodes[j](j = 2 *i + 1或2 *i + 2),

④如果当前父节点parent的优先级高于nodes[j],交换nodes[i]和nodes[j],并更新当前父节点,

即令i=j,并循环 ③;

如果当前父节点的优先级低于nodes[j],处理结束。

5)priority_queue_enqueue用于将KeyValue入列

其实现的基本思路,以最大优先队列说明如下:

①设置nodes[_size] 为新的KeyValue,并令_size++

②令当前儿子节点child(nodes[i])为新的队列尾部节点(i=_size-1),child的父节点parent为nodes[j],

其中j= (i - 1) / 2

③如果当前儿子节点child的优先级高于parent, 交换nodes[i]和nodes[j],并更新当前儿子节点

即令i = j,并循环③;

如果当前儿子节点的优先级低于parent,处理结束。

6) priority_queue_size用于取得队列中元素个数,priority_queue_empty用于判断队列是否为空。

7)priority_queue_print用于输出队列中的内容。

文件pq.h给出了数据结构和函数的声明,文件pq.c给出了具体实现,main.c文件用于测试。虽然是使用过程化编程的C语言,可以看到具体的编码中应用了基于对象的思想,我们对数据结构和相关函数做了一定程度的聚集和封装。

复制代码 代码如下:

/*

*File: pq.h

*purpose: declaration of priority queue in C

*/

#ifndef _PRIORITY_QUEUE_H

#define _PRIORITY_QUEUE_H

// =============KeyValue Struct==================================

typedef struct key_value_struct KeyValue;

struct key_value_struct

{

int _key;

void *_value;

};

KeyValue *key_value_new(int key, void *value);

void key_value_free(KeyValue *kv, void (*freevalue)(void *));

// =============PriorityQueue Struct==============================

#define PRIORITY_MAX 1

#define PRIORITY_MIN 2

typedef struct priority_queue_struct PriorityQueue;

struct priority_queue_struct

{

KeyValue **_nodes;

int _size;

int _capacity;

int _priority;

};

PriorityQueue *priority_queue_new(int priority);

void priority_queue_free(PriorityQueue *pq, void (*freevalue)(void *));

const KeyValue *priority_queue_top(PriorityQueue *pq);

KeyValue *priority_queue_dequeue(PriorityQueue *pq);

void priority_queue_enqueue(PriorityQueue *pq, KeyValue *kv);

int priority_queue_size(PriorityQueue *pq);

int priority_queue_empty(PriorityQueue *pq);

void priority_queue_print(PriorityQueue *pq);

#endif

/*

*File:pq.c

*purpose: definition of priority queue in C

*Author:puresky

*Date:2011/04/27

*/

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include "pq.h"

//Private Functions

static void priority_queue_realloc(PriorityQueue *pq);

static void priority_queue_adjust_head(PriorityQueue *pq);

static void priority_queue_adjust_tail(PriorityQueue *pq);

static int priority_queue_compare(PriorityQueue *pq,

int pos1,

int pos2);

static void priority_queue_swap(KeyValue **nodes,

int pos1,

int pos2);

//Functions of KeyValue Struct

KeyValue *key_value_new(int key,

void *value)

{

KeyValue *pkv = (KeyValue *)malloc(sizeof(KeyValue));

pkv->_key = key;

pkv->_value = value;

return pkv;

}

void key_value_free(KeyValue *kv,

void (*freevalue)(void *))

{

if(kv)

{

if(freevalue)

{

freevalue(kv->_value);

}

free(kv);

}

}

//Functions of PriorityQueue Struct

PriorityQueue *priority_queue_new(int priority)

{

PriorityQueue *pq = (PriorityQueue *)malloc(sizeof(PriorityQueue));

pq->_capacity = 11; //default initial value

pq->_size = 0;

pq->_priority = priority;

pq->_nodes = (KeyValue **)malloc(sizeof(KeyValue *) * pq->_capacity);

return pq;

}

void priority_queue_free(PriorityQueue *pq,

void (*freevalue)(void *))

{

int i;

if(pq)

{

for(i = 0; i < pq->_size; ++i)

key_value_free(pq->_nodes[i], freevalue);

free(pq->_nodes);

free(pq);

}

}

const KeyValue *priority_queue_top(PriorityQueue *pq)

{

if(pq->_size > 0)

return pq->_nodes[0];

return NULL;

}

KeyValue *priority_queue_dequeue(PriorityQueue *pq)

{

KeyValue *pkv = NULL;

if(pq->_size > 0)

{

pkv = pq->_nodes[0];

priority_queue_adjust_head(pq);

}

return pkv;

}

void priority_queue_enqueue(PriorityQueue *pq,

KeyValue *kv)

{

printf("add key:%dn", kv->_key);

pq->_nodes[pq->_size] = kv;

priority_queue_adjust_tail(pq);

if(pq->_size >= pq->_capacity)

priority_queue_realloc(pq);

}

int priority_queue_size(PriorityQueue *pq)

{

return pq->_size;

}

int priority_queue_empty(PriorityQueue *pq)

{

return pq->_size <= 0;

}

void priority_queue_print(PriorityQueue *pq)

{

int i;

KeyValue *kv;

printf("data in the pq->_nodesn");

for(i = 0; i < pq->_size; ++i)

printf("%d ", pq->_nodes[i]->_key);

printf("n");

printf("dequeue all datan");

while(!priority_queue_empty(pq))

{

kv = priority_queue_dequeue(pq);

printf("%d ", kv->_key);

}

printf("n");

}

static void priority_queue_realloc(PriorityQueue *pq)

{

pq->_capacity = pq->_capacity * 2;

pq->_nodes = realloc(pq->_nodes, sizeof(KeyValue *) * pq->_capacity);

}

static void priority_queue_adjust_head(PriorityQueue *pq)

{

int i, j, parent, left, right;

i = 0, j = 0;

parent = left = right = 0;

priority_queue_swap(pq->_nodes, 0, pq->_size - 1);

pq->_size--;

while(i < (pq->_size - 1) / 2)

{

parent = i;

left = i * 2 + 1;

right = left + 1;

j = left;

if(priority_queue_compare(pq, left, right) > 0)

j++;

if(priority_queue_compare(pq, parent, j) > 0)

{

priority_queue_swap(pq->_nodes, i, j);

i = j;

}

else

break;

}

}

static void priority_queue_adjust_tail(PriorityQueue *pq)

{

int i, parent, child;

i = pq->_size - 1;

pq->_size++;

while(i > 0)

{

child = i;

parent = (child - 1) / 2;

if(priority_queue_compare(pq, parent, child) > 0)

{

priority_queue_swap(pq->_nodes, child, parent);

i = parent;

}

else

break;

}

}

static int priority_queue_compare(PriorityQueue *pq,

int pos1,

int pos2)

{

int adjust = -1;

int r = pq->_nodes[pos1]->_key - pq->_nodes[pos2]->_key;

if(pq->_priority == PRIORITY_MAX)

r *= adjust;

return r;

}

static void priority_queue_swap(KeyValue **nodes,

int pos1,

int pos2)

{

KeyValue *temp = nodes[pos1];

nodes[pos1] = nodes[pos2];

nodes[pos2] = temp;

}

/*

*File: main.c

*purpose: tesing priority queue in C

*Author:puresky

*Date:2011/04/27

*/

#include <stdio.h>

#include <stdlib.h>

#include "pq.h"

int main(int argc, char **argv)

{

int i;

PriorityQueue *pq = priority_queue_new(PRIORITY_MAX);

int a[]={1, 9, 7, 8, 5, 4, 3, 2, 1, 100, 50, 17};

for(i = 0; i < sizeof(a)/ sizeof(int); ++i)

{

KeyValue *kv = key_value_new(a[i], NULL);

priority_queue_enqueue(pq, kv);

}

priority_queue_print(pq);

priority_queue_free(pq, NULL);

system("pause");

return 0;

}

【优先队列(priority_queue)的C语言实现代码】相关文章:

使用C语言实现CRC校验的方法

基于条件变量的消息队列 说明介绍

输出1000以内的素数的算法(实例代码)

C语言实现逆波兰式实例

递归法求最大公约数和最小公倍数的实现代码

C语言 实现N阶乘的程序代码

解析C++无锁队列的实现代码

利用C语言实现HashTable

用C# 实现鼠标框选效果的实现代码

c++ 巧开平方的实现代码

精品推荐
分类导航