Prim算法优先级队列版 算法基础篇(四)

View Code
  1 // Prim算法.cpp : 定义控制台应用程序的入口点。
  2 //
  3 
  4 #include "stdafx.h"
  5 #include <stdio.h>
  6 #include <string>
  7 #include <queue>
  8 #include <stdlib.h>
  9 using namespace std;
 10 #define Max 10
 11 #define Infinity 1000
 12 typedef unsigned int EdgeType;
 13 typedef unsigned int DistType;
 14 typedef int VexType;
 15 
 16 
 17 struct Graph     //图结构 包括边点数,边数组,访问标记,从初始点到点的路径长度。
 18 {
 19   int Arc;int Vex;
 20   EdgeType Edge[Max][Max];
 21   bool Vis[Max];
 22   DistType Dist[Max];
 23 };
 24 
 25 struct QueElem  //Que节点这个节点的设计主要是为了在使用优先级队列时比较方便
 26 {
 27     VexType V;
 28     DistType D;
 29     friend bool operator > (struct QueElem  Q1,struct QueElem  Q2)
 30     {
 31         return Q1.D> Q2.D;
 32     }
 33 };
 34 
 35 typedef struct QueElem Q;
 36 
 37 //priority_queue<Q,vector<Q>,greater<Q> > PriorQue;
 38 priority_queue<Q,vector<Q>,greater<Q> > PriorQue;     //申明优先级队列,建立小顶堆。
 39  Q QueArr[Max];                                      //队列数组
 40 
 41 void ReadGraph(Graph *G)                      //读图函数
 42 {
 43     int x,y;
 44     int weigh;
 45     printf("请输入点数和边数!\n");
 46     scanf("%d%d",&(G->Vex),&(G->Arc));
 47     memset(G->Edge,-1,sizeof(G->Edge));
 48     memset(G->Vis,0,sizeof(G->Vis));
 49     memset(G->Dist,-1,sizeof(G->Dist));
 50     for(int i=0;i<G->Arc;i++)
 51     {
 52         printf("请输入第%d条边的起点终点和权值:",i+1);
 53         scanf("%d%d%u",&x,&y,&weigh);
 54         G->Edge[x][y]=weigh;
 55         G->Edge[y][x]=weigh;
 56     }
 57 #if 0
 58     for(int i=0;i<G->Vex;i++)
 59     {
 60         Vis[i]=false;
 61         Dist[i]=Infinity;
 62     }
 63 #endif
 64 
 65     G->Dist[0]=0;
 66     for(int i=0;i<Max;i++)
 67     {
 68         QueArr[i].V=i;
 69         QueArr[i].D=G->Dist[i];
 70     }
 71 
 72 }
 73 
 74 
 75 void Prim(Graph *G)         
 76 {
 77     int i;
 78     Q pQ;
 79     PriorQue.push(QueArr[0]);//推入头数组元素 
 80 
 81     while(!PriorQue.empty())                    
 82     {
 83         pQ=PriorQue.top();             //这个语句要用好,他和那个operator函数息息相关,注意operator参数只能为引用或者原型,不能指针
 84         printf("pQ=%d\n",pQ.V);
 85         PriorQue.pop();
 86         G->Vis[pQ.V]=true;
 87         for(i=0;i<G->Vex;i++)
 88         {
 89             if(G->Edge[pQ.V][i]< Infinity && !(G->Vis[i]) )  //检验是否有边和是否已访问
 90             {
 91                 if(G->Dist[pQ.V]+G->Edge[pQ.V][i]<G->Dist[i])
 92                 {
 93                     G->Dist[i]=G->Dist[pQ.V]+G->Edge[pQ.V][i];
 94                     QueArr[i].D=G->Dist[i];
 95                 }
 96                 PriorQue.push(QueArr[i]);
 97             }
 98         }
 99     }
100 }
101 
102 
103 
104 
105 int _tmain(int argc, _TCHAR* argv[])
106 {
107     Graph *G=(Graph *)malloc(sizeof (struct Graph));
108     ReadGraph(G);
109     Prime(G);
110     for(int i=0;i<G->Vex;i++)
111         printf("G->Dist[%d]=%u\n",i,G->Dist[i]);
112     return 0;
113 }

posted on 2012-06-14 16:46  北冥茶花开  阅读(221)  评论(0编辑  收藏  举报

导航