c-PriorityQuque

来源:互联网 发布:卖宠物的软件 编辑:程序博客网 时间:2024/06/01 08:02

/*@file test.c*/
/*compiled ok with mingGW/gcc chinayaosir*/
/*优先队列测试程序*/

#include <stdio.h>
#include "pqueue.h"

int main()
{
 // Example use of priority queue
 pqueue queue;
 node n1, n2, n3,n4,n5,t;
 n1.data = 12;  n1.priority = 3;/*level 3*/
 n2.data = 25;  n2.priority = 1;/*level 1*/ 
 n3.data = 66;  n3.priority = 4;/*level 4*/
 n4.data = 22;  n4.priority = 2;/*level 2*/
 n5.data = 99;  n5.priority = 0;/*level 0*/
 /*初始化队列*/     
 init_queue(&queue);
 /*入队5个结点*/
 printf("1.结点5个依次入队/n");
 enqueue(&queue, &n1);
 printf("(数据=%d,级别=%d )/n",n1.data,n1.priority);
 enqueue(&queue, &n2);
 printf("(数据=%d,级别=%d )/n",n2.data,n2.priority);
 enqueue(&queue, &n3);
 printf("(数据=%d,级别=%d )/n",n3.data,n3.priority);
 enqueue(&queue, &n4);
 printf("(数据=%d,级别=%d )/n",n4.data,n4.priority);
 enqueue(&queue, &n5);
 printf("(数据=%d,级别=%d )/n",n5.data,n5.priority);
 printf("2.打印/n");
 print_queue(&queue);
 printf("3.出队()/n"); 
 t=dequeue(&queue);/*元素出队*/
 print_queue(&queue);
 printf("4.出队()/n"); 
 t=dequeue(&queue);/*元素出队*/
 print_queue(&queue);
 printf("5.出队()/n"); 
 t=dequeue(&queue);/*元素出队*/
 print_queue(&queue);   
 return 0;
}

/*
运行结果
1.结点5个依次入队
(数据=12,级别=3 )
(数据=25,级别=1 )
(数据=66,级别=4 )
(数据=22,级别=2 )
(数据=99,级别=0 )
2.打印
[ 99 25 66 12 22 ]
3.出队()
[ 25 22 66 12 ]
4.出队()
[ 22 12 66 ]
5.出队()
[ 12 66 ]

*/

/****************************************************************/

/**@file pqueue.h
*功能:基于数组的二项堆构建一个优先队列. 
*compiled ok with mingGW/vc++ with chinayaosir
*/

#include <stdlib.h>

/*1.堆操作宏定义 */
#define PARENT(i)  ((i-1)/2)
#define LEFT(i)   ((2*i+1))
#define RIGHT(i)  (2*(i+1))
#define priority(i)  (i.priority)

#define TRUE    1
#define FALSE   0
#define NULL  0
#define PQUEUESIZE      1000

/*2.node struct*/
typedef int datatype;
typedef struct {
 int x;   /* x 坐标 */
 int y;   /* y 坐标 */
 int priority;  /* node优先级别 */
 datatype data;  /* node的数据*/
 struct node * parent; /* link to parent node */
}node;

/*3.priority-quque struct*/
typedef struct {
        node q[PQUEUESIZE+1]; /* 结点数组 */
        int count;  /* 元素个数 */
} pqueue;

/*priority ADT LIST*/

/*0.1.empty()*/
int empty(pqueue *q){
        if (q->count == 0)
  return (TRUE);
        else
  return (FALSE);
}

/*0.2.contains()*/
int contains(pqueue *q, node *n){
 int i;
 for(i=0; i<q->count; i++){
  if(q->q[i].data == n->data)
   return (TRUE);
 }
 return (FALSE);
}

/*0.3.print_queue()*/
print_queue(pqueue *q){
 int i;
 printf("[ ");
 for(i=0; i<q->count; i++) printf("%d ",q->q[i].data);
 printf("]/n");
}

 

/*1.init_queue*/
void init_queue(pqueue *q){
        q->count = 0;
}

/*2.enqueue(pqueue *, node * )入队*/
/*入队之前,node的节点一定要填好数据内容和优先级别*/
void enqueue(pqueue *q, node * x){
 int parent, leaf;
 node value, temp;
 /*2.1检查是否为空?*/
        if (q->count >= PQUEUESIZE){
  printf("Warning: pqueue overflow enpqueue x=%dn",x);
   return;
 }
        /*2.2添加结点node*/
 q->count++;
 leaf = q->count - 1;  
 q->q[leaf] = *x;   

 /*2.3队列中结点的数据按priority从小到大进行提升*/
 parent = PARENT(leaf);
 value = q->q[leaf];
 while(leaf > 0 && (priority(q->q[leaf]) < priority(q->q[parent]))){
  temp = q->q[leaf];
  q->q[leaf] = q->q[parent];
  q->q[parent] = temp;
  leaf = parent;
  parent = PARENT(leaf);
 }
 q->q[leaf] = value;
}

/*3.dequeue(pqueue *)出队*/
/*找出队列中priority最小的结点node出队*/
node dequeue(pqueue *q)
{
  int heapsize, root, childpos;
  node minVal, temp;
  node value;

  minVal = q->q[0];
  q->q[0] = q->q[q->count-1];  // take last element and put on root of tree
  q->count--;    // adjust size

  root = 0;
  if(q->count > 1)
  {
   // percolate down
   heapsize = q->count;
   value = q->q[root];   // get root
   while(root < heapsize)
   {
    childpos = LEFT(root);
    if(childpos < heapsize)
    {
     if((RIGHT(root) < heapsize) &&
      (priority(q->q[childpos+1]) <
       priority(q->q[childpos])))
     {
      childpos++;
     }
     if(priority(q->q[childpos]) < priority(q->q[root]))
     {
      temp = q->q[root];
      q->q[root] = q->q[childpos];
      q->q[childpos] = temp;
      root = childpos;
     }
     else
     {
      q->q[root] = value;
      break;
     }
    }
    else
    {
     q->q[root] = value;
     break;
    }
   }
  }
  return minVal;/*返回级别最高的结点*/
}