求最小生成树Kruskal算法

来源:互联网 发布:java爬虫入门教程 编辑:程序博客网 时间:2024/05/17 02:39

                                                                            求最小生成树Kruskal算法

      本文取自《数据结构与算法》(C语言版)(第三版),出版社是清华大学出版社。

      本博文作为学习资料整理。源代码是VC++ 6.0上可执行程序,我挪到了VS2010中执行。

    在VS2010中新建C++ Win32 控制台应用程序项目,创建结果截图:

         

     Kruskal算法的基本思想是:将图G中的边按权值从小到大的顺序依次添加,如果添加的边使生成树T构成回路,则将其舍弃,依此下去,直到T中包含的边数为n-1条边为止,此时的T即为最小生树。

        Kruskal算法步骤图示例:

                                
       为了方便输出,将最小生成树的输入格式规定为以下形式:
       (顶点1, 顶点2): 权值1
       表示顶点1到顶点2有路径,路径上的权值为1.
       其程序如下:

   #include "stdafx.h"   #include<stdio.h>   #include<stdlib.h>   #include<string.h>   #define MaxVertexNum 100   //队列的声明   typedef struct Qnode   {     int data;     struct Qnode* next;     struct Qnode* prev;   }Qnode;   typedef struct queue   {     Qnode* first;     Qnode* tail;   }Queue;   int isQueueEmpty(Queue* pQue)   {     if(pQue->first==pQue->tail)       return 1;     else       return 0;   }   Queue* queueInit(Queue* pQue)   {     pQue->first=(Qnode*)malloc(sizeof(Queue));     pQue->first->data=-1;     pQue->tail=pQue->first;     return pQue;   }   Qnode* queuePull(Queue* pQue)   {     pQue->tail=pQue->tail->prev;     return pQue->tail->next;   }   void queuePush(Queue* pQue, Qnode* pNode)   {     pNode->next=pQue->first;     pQue->first->prev=pNode;     pQue->first=pNode;   }   Queue* queueEmpty(Queue* pQue)   {     while(pQue->first!=pQue->tail)     {       Qnode* pCurr=pQue->first;       pQue->first=pQue->first->next;       free(pQue->first);     }     return pQue;   }   //图的声明   typedef struct node   {     int adjvex;     int hostvex;     struct node *nextrarc;     int info;   }EdgeNode;   typedef struct vnode   {     char vexdate;     EdgeNode *firstarc;   }VertexNode;   typedef VertexNode AdjList[MaxVertexNum];   typedef struct   {     AdjList adjlist;     int n,e;   }ALGraph;   int initGraph(ALGraph* aGraph);   int mFind(char aChar, ALGraph* aGraph);   int createHead(char aChar, ALGraph* aGraph);   void addBody(char aChar, int aPos, ALGraph* aGraph, int weight);   void Kruskal(ALGraph* aGraph);   int main(void)   {     char a;     int isFinish=0;     int headPos=-1;     char a1='@', a2='@', a3='@', a4='@', a5='@', a6='@', a7='@';     ALGraph g_graph;     initGraph(&g_graph);     printf("Input arcs like this '(start,end:weight)',end with $\n");     while(isFinish==0)     {        while(1)        {          a=getchar();          if(a=='$'||a=='#')          {            if(a=='#')              isFinish=1;            break;          }          if(a==' '||a=='\n')            continue;          a1=a2;          a2=a3;          a3=a4;          a4=a5;          a5=a6;          a6=a7;          a7=a;          if(a1=='('&&a3==','&&a5==':'&&a7==')')          {            if((headPos=mFind(a2,&g_graph))==-1)              headPos=createHead(a2,&g_graph);            addBody(a4,headPos,&g_graph,a6);          }        }     }     Kruskal(&g_graph);     return 0;   }   void Kruskal(ALGraph* aGraph)    {      int i,j,u1,v1,sn1,sn2,k;      int vset[MaxVertexNum];      EdgeNode* E[MaxVertexNum];      k=0;      for(i=0; i<aGraph->n; i++)      {        EdgeNode* temEdge;        for(temEdge=aGraph->adjlist[i].firstarc; temEdge!=NULL;                temEdge=temEdge->nextrarc)        {          E[k]=temEdge;          k++;        }      }      //将边的权值进行排序      for(i=0; i<aGraph->e; i++)      {        for(j=aGraph->e-1; j>i; j--)          if(E[j]->info<E[j-1]->info)          {            EdgeNode* tem=E[j];            E[j]=E[j-1];            E[j-1]=tem;          }      }      for(i=0; i<aGraph->n; i++)        vset[i]=i;      k=1;      j=0;      //添加边      while(k<aGraph->n)      {        u1=E[j]->hostvex;        v1=E[j]->adjvex;        sn1=vset[u1];        sn2=vset[v1];        if(sn1!=sn2)        {          printf("(%d,%d):%c\n",u1,v1,E[j]->info);          k++;          for(i=0; i<aGraph->n; i++)            if(vset[i]==sn2)              vset[i]=sn1;        }        j+=2;      }    }    void addBody(char aChar, int aPos, ALGraph* aGraph, int weight)    {      int inversePos;      EdgeNode* node=(EdgeNode*) malloc(sizeof(EdgeNode));      node->info=weight;      if((node->adjvex=mFind(aChar,aGraph))==-1)        node->adjvex=createHead(aChar,aGraph);      node->hostvex=aPos;      node->nextrarc=NULL;      if(aGraph->adjlist[aPos].firstarc==NULL)        aGraph->adjlist[aPos].firstarc=node;      else      {        EdgeNode* tail=aGraph->adjlist[aPos].firstarc;        while(tail->nextrarc!=NULL)          tail=tail->nextrarc;        tail->nextrarc=node;      }      aGraph->e++;      inversePos=node->adjvex;      node=(EdgeNode*) malloc(sizeof(EdgeNode));      node->info=weight;      node->hostvex=inversePos;      node->adjvex=aPos;      node->nextrarc=NULL;      if(aGraph->adjlist[inversePos].firstarc==NULL)        aGraph->adjlist[inversePos].firstarc=node;      else      {        EdgeNode* tail=aGraph->adjlist[inversePos].firstarc;        while(tail->nextrarc!=NULL)          tail=tail->nextrarc;        tail->nextrarc=node;      }      aGraph->e++;    }   int createHead(char aChar, ALGraph* aGraph)   {     int currPos=aGraph->n;     aGraph->adjlist[currPos].vexdate=aChar;     aGraph->n++;     return currPos;   }   int mFind(char aChar, ALGraph* aGraph)   {     int i=0;     for(i=0; i<aGraph->n; i++)     {       if(aChar==aGraph->adjlist[i].vexdate)         return i;     }     return -1;   }   int initGraph(ALGraph* aGraph)   {     int i=0;     aGraph->e=0;     aGraph->n=0;     for(i=0; i<MaxVertexNum; i++)     {       aGraph->adjlist[i].firstarc=NULL;     }     return 0;   }
         程序运行结果截图如下:Ctrl+F5执行程序Kruskal.cpp

     

0 0
原创粉丝点击