小源求学 发表于 2012-12-13 21:22:05

堆和优先队列的应用

<div id="cnblogs_post_body">什么是堆:
堆的定义:n个元素的序列k={k0,k1,……,kn-1},当且仅满足条件
(1)ki >= k2i+1 和 ki >= k2i+2      (2)ki <= k2i+1 和 ki <= k2i+2

(1)称为大根堆 (2)称为小根堆

可以把堆看成完全二叉树。

什么是优先队列:
优先队列是一种常见的抽象数据类型,它与"队列"不同,不遵循"先进先出"原则,而遵循"最小元素先出"原则。

优先队列的基本操作有三个:
(1) 向优先队列里插入一个元素
(2) 在优先队列找出最小元素
(3) 删除优先队列中最小元素
可以用堆来实现有限队列

优先队列的实现:

<div class="cnblogs_code">1 #include "stdio.h"2 #include "stdlib.h"3 4 typedef int DATATYPE;5 6 /********************优先队列存储结构********************************/7 struct priorityQueue 8 {9   int MAXNUM; //存储结构长度 10   int n; //实际元素个数 11   DATATYPE * element; 12 }; 13 typedef struct priorityQueue *PQ; 14 15 /********************创建优先队列***********************************/ 16 PQ createPQ(int maxnum) 17 { 18   PQ pq = NULL; 19   pq = (PQ) malloc(sizeof(struct priorityQueue)); 20   if(NULL != pq) 21     { 22         pq->element = malloc(sizeof(DATATYPE) * maxnum); 23         if(pq->element != NULL) 24       { 25             pq->MAXNUM = maxnum; 26             pq->n = 0; 27       } 28     } 29   return pq; 30 } 31 32 /****************************判断优先队列是否为空****************************/ 33 int isEmpty_heap(PQ pq) 34 { 35   return pq->n == 0; 36 } 37 38 /**************************往优先队列中插入元素*******************************/ 39 void add_heap(PQ pq, DATATYPE x) 40 { 41   int i = -1; //标志元素最后要插入位置的下标 42   if(pq->n >= pq->MAXNUM) //如果队列已满,无法插入 43     { 44         printf("PriorityQueue is full"); 45         return; 46     } 47   //寻找插入的位置,pq->n是未有元素的空位 48   for(i = pq->n; i > 0 && x < pq->element[(i-1)/2]; i = (i - 1)/2) 49     { 50         pq->element = pq->element[(i-1)/2]; 51     } 52   //插入元素 53   pq->element = x; 54   pq->n++; 55 } 56 57 /*************************在三个元素中,找出最小元素的下标********************/ 58 int findMinIndex(PQ pq,int index1, int index2, int index3) 59 { 60   int min = 0; 61   min = (pq->element < pq->element)?index1:index2; 62   min = (pq->element < pq->element)?min:index3; 63   return min; 64 } 65 66 /*************************删除优先队列最小元素************************************/ 67 void removeMin_heap(PQ pq) 68 { 69   int endIndex,leftchild,rightchild,index,minIndex; 70   if(isEmpty_heap(pq)) //如果为空队列,返回 71         return; 72   endIndex = --pq->n; //找到队列尾元素下标,并将首元素删除 73 74   index = 0; //空位的下标,开始时在根节点处 75   for(;index < endIndex;) 76     { 77         leftchild = index*2 + 1; 78         rightchild = index*2 + 2; 79         if(leftchild > endIndex || rightchild > endIndex) 80       { 81             pq->element = pq->element; 82             break; 83       }             84                85         minIndex = findMinIndex(pq,endIndex,leftchild,rightchild); 86         pq->element = pq->element; 87         if(minIndex == endIndex) 88             break; 89         else if(minIndex == leftchild) 90             index = leftchild; 91         else if(minIndex == rightchild) 92             index = rightchild; 93     } 94 } 95 96 97 98 /***********************显示优先队列中元素的排列****************************/ 99 void show(PQ pq)100 {101   int i = 0;102   103   for(i = 0; i < pq->n; i++)104     {105         printf("%d, ",pq->element);106     }107 108 }109 110 int main()111 {112   PQ pq = createPQ(6);113   add_heap(pq, 3);114   add_heap(pq, 2);115   add_heap(pq, 8);116   add_heap(pq, 4);117   add_heap(pq, 6);118   add_heap(pq, 10);119   120     show(pq);121   printf("\n");122   123     removeMin_heap(pq);124     show(pq);125   return 0;126 }
页: [1]
查看完整版本: 堆和优先队列的应用