当前位置:  编程技术>c/c++/嵌入式

优先队列(priority_queue)的C语言实现代码

    来源: 互联网  发布时间:2014-10-21

    本文导语:  优先队列(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
#include
#include
#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 _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
#include
#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;
}


    
 
 
 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • shell脚本中存在类似C语言中的小括号来改变优先级的机制吗?
  • C语言实现图的遍历之深度优先搜索实例
  • C语言运算符及其优先级汇总表口诀
  • C语言运算符优先级列表(超详细)
  • c/c++ 操作符优先级参考
  • ucosII 实现允许存在同优先级任务,ID应该怎么设置?更改优先级后任务ID怎么办?
  • android 4.0 托管进程介绍及优先级和回收机制
  • 菜鸟问,linux的高优先级进程能无条件抢占低优先级进程吗?
  • 请教进程优先的函数
  • 关于goodness函数及进程优先级
  • 请教多线程优先级问题
  • Thread如何设置优先级?
  • 请教:如何设置当前进程的优先级
  • 关于java线程调度优先级
  • 急求 公平的兼顾优先级的任务分发算法!!
  • 请教优先级的问题
  • linux进程优先级问题
  • 一道计算作业优先数的题目___八股考试,我想学东西!
  • Linux中,能不能对线程设置优先级?
  • pthread的优先级问题 (续1)
  • 怎样设置网关的优先级别呢?
  • 2.6内核种进程优先级的疑惑。。。
  • 如果有三个线程在Waiting(Ready to Run)状态,其优先级分别为5,6,7,当Thread scheduler调度时,那个先运行?
  • 一个“最短寻道优先(SSTF)磁盘调度算法”的问题:
  • linux2.6内核的进程优先级是如何设置的?


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3