【WEISS算法书】Prim算法

本文介绍了一种使用普里姆算法求解最小生成树的方法。通过详细的代码示例,展示了如何构建非定向图并利用最小堆来寻找最小生成树的过程。文章涵盖了数据结构的设计、初始化及销毁等关键环节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    写这玩意乱写一气。。估计连自己都看不太懂了。。先留在这儿先。。免得程序给弄丢了。。

Code:
  1. #include <iostream>   
  2. #include <string>   
  3. using namespace std;   
  4.   
  5. struct HeapStruct   
  6. {   
  7.     int Capacity;   
  8.     int size;   
  9.     int *Elements;   
  10. };   
  11. typedef HeapStruct* PriorityQueue;   
  12.   
  13. PriorityQueue Initialize(int MaxElements)   
  14. {   
  15.     PriorityQueue pq=(PriorityQueue)malloc(sizeof(HeapStruct));   
  16.     if(pq==NULL)   
  17.     {   
  18.         cout<<"Bad Memory Allocated!"<<endl;   
  19.         exit(1);   
  20.     }   
  21.     /*if(MaxElements<5)  
  22.     {  
  23.         cout<<"Too Few!"<<endl;  
  24.         return NULL;  
  25.     }  
  26.     */  
  27.     pq->size=0;   
  28.     pq->Capacity=MaxElements;   
  29.     pq->Elements=(int*)malloc(sizeof(int)*pq->Capacity+1);   
  30.        
  31.     if(pq->Elements==NULL)   
  32.     {   
  33.         cout<<"Bad Memory Allocated!"<<endl;   
  34.         exit(1);   
  35.     }   
  36.     pq->Elements[0]=-10000;   
  37.     return pq;   
  38. }   
  39.   
  40. void Destroy(PriorityQueue pq)   
  41. {   
  42.     free(pq->Elements);   
  43.     free(pq);   
  44. }   
  45.   
  46. bool IsFull(PriorityQueue pq)   
  47. {   
  48.     return pq->size==pq->Capacity;   
  49. }   
  50.   
  51. bool IsEmpty(PriorityQueue pq)   
  52. {   
  53.     return pq->size==0;   
  54. }   
  55.   
  56. void Insert(int data,PriorityQueue pq)   
  57. {   
  58.     if(IsFull(pq))   
  59.     {   
  60.         cout<<"Full!"<<endl;   
  61.         return;   
  62.     }   
  63.     int i;   
  64.     for(i=++pq->size;pq->Elements[i/2]>data;i/=2)   
  65.     {   
  66.         pq->Elements[i]=pq->Elements[i/2];   
  67.     }   
  68.     pq->Elements[i]=data;   
  69. }   
  70.   
  71. int DeleteMin(PriorityQueue pq)   
  72. {   
  73.     if(IsEmpty(pq))   
  74.     {   
  75.         cout<<"Empty!"<<endl;   
  76.         exit(1);   
  77.     }   
  78.     int i=1;   
  79.     int child;   
  80.     int minElement=pq->Elements[1];   
  81.     int lastElement=pq->Elements[pq->size--];   
  82.     while(i*2<=pq->size)   
  83.     {   
  84.         child=i*2;   
  85.         if(child!=pq->size && pq->Elements[child]>pq->Elements[child+1])   
  86.         {   
  87.             ++child;   
  88.         }   
  89.         if(pq->Elements[child]<lastElement)   
  90.         {   
  91.             pq->Elements[i]=pq->Elements[child];   
  92.         }   
  93.         else  
  94.         {   
  95.             break;   
  96.         }   
  97.         i=child;   
  98.     }   
  99.     pq->Elements[i]=lastElement;   
  100.     return minElement;   
  101. }   
  102.   
  103. struct VertexNode   
  104. {   
  105.     VertexNode * nextVertex;   
  106.     string edge;   
  107.     int weight;   
  108.     VertexNode(string e,int w):weight(w),edge(e){}   
  109. };   
  110.   
  111. struct Vertex   
  112. {   
  113.     string name;   
  114.     VertexNode *first;   
  115.     Vertex(string n):name(n){first=NULL;}   
  116. };   
  117.   
  118. typedef Vertex* ab;   
  119. struct Entry;   
  120. struct NonDireGraph   
  121. {   
  122.     ab *vertice;   
  123.     int verNum;   
  124.     NonDireGraph(int vn):verNum(vn)   
  125.     {   
  126.         vertice=new ab[verNum];   
  127.         for(int i=0;i<verNum;i++)   
  128.         {   
  129.             cout<<"给个名字";   
  130.             string tmp;   
  131.             cin>>tmp;   
  132.             vertice[i]=new Vertex(tmp);   
  133.             for(;;)   
  134.             {   
  135.                 cout<<"要加边咩?"<<endl;   
  136.                 char tmpC;   
  137.                 cin>>tmpC;   
  138.                 if(tmpC == 'N')   
  139.                 {   
  140.                     break;   
  141.                 }   
  142.                 cout<<"给出边名字"<<endl;   
  143.                 string tmpS;   
  144.                 cin>>tmpS;   
  145.                 cout<<"给出权值"<<endl;   
  146.                 int tmpW;   
  147.                 cin>>tmpW;   
  148.                 VertexNode *tmpV=new VertexNode(tmpS,tmpW);   
  149.                 tmpV->nextVertex=vertice[i]->first;   
  150.                 vertice[i]->first=tmpV;   
  151.             }   
  152.         }   
  153.     }   
  154.     ~NonDireGraph()   
  155.     {   
  156.         for(int i=0;i<verNum;i++)   
  157.         {   
  158.             while(vertice[i]->first!=NULL)   
  159.             {   
  160.                 VertexNode *tmp=vertice[i]->first;   
  161.                 vertice[i]->first=tmp->nextVertex;   
  162.                 delete tmp;   
  163.             }   
  164.             delete vertice[i];   
  165.         }   
  166.         delete [] vertice;   
  167.     }   
  168.        
  169.     void AddKnownVertex(const string &name,Entry *e);   
  170.   
  171.     int FindIndexByName(const string &name)   
  172.     {   
  173.         for(int i=0;i<verNum;i++)   
  174.         {   
  175.             if(vertice[i]->name==name)   
  176.             {   
  177.                 return i;   
  178.             }   
  179.         }   
  180.         return -1;   
  181.     }   
  182. };   
  183.   
  184. struct Entry   
  185. {   
  186.     string name;   
  187.     int isVisited;   
  188.     int currentWeight;   
  189.     string lastVisited;   
  190.     Entry(){}   
  191.     Entry(string n,bool iv,int cw,string lv):name(n),isVisited(iv),currentWeight(cw),lastVisited(lv){}   
  192. };   
  193.   
  194. Entry * InitializeEntry(const NonDireGraph &g)   
  195. {   
  196.     Entry *retEntry=new Entry[g.verNum];   
  197.     for(int i=0;i<g.verNum;i++)   
  198.     {   
  199.         retEntry[i].name=g.vertice[i]->name;   
  200.         retEntry[i].isVisited=0;   
  201.         retEntry[i].currentWeight=30000;   
  202.         retEntry[i].lastVisited="";   
  203.     }   
  204.     return retEntry;   
  205. }   
  206.   
  207. void DisposeEntry(Entry *e)   
  208. {   
  209.     delete [] e;   
  210. }   
  211.   
  212. void NonDireGraph::AddKnownVertex(const string &name,Entry *e)   
  213. {   
  214.     int i=FindIndexByName(name);   
  215.     for(VertexNode *vn=vertice[i]->first;vn!=NULL;vn=vn->nextVertex)   
  216.     {   
  217.         for(int j=0;j<verNum;j++)   
  218.         {   
  219.             if(e[j].isVisited==0 && e[j].name==(vn->edge))   
  220.             {   
  221.                 int previousWeight=0;   
  222.                 for(int k=0;k<verNum;k++)   
  223.                 {   
  224.                     if(e[k].name==name)   
  225.                     {   
  226.                         previousWeight=e[k].currentWeight;   
  227.                     }   
  228.                 }   
  229.                 if(e[j].currentWeight>vn->weight+previousWeight)   
  230.                 {   
  231.                     e[j].currentWeight=vn->weight+previousWeight;   
  232.                     e[j].lastVisited=name;   
  233.                 }   
  234.             }   
  235.         }   
  236.     }   
  237. }   
  238.   
  239. Entry * Prim(NonDireGraph &g,const string &startName)   
  240. {   
  241.     Entry *table=InitializeEntry(g);   
  242.     for(int i=0;i<g.verNum;i++)   
  243.     {   
  244.         if(table[i].name==startName)   
  245.         {   
  246.             table[i].currentWeight=0;   
  247.             table[i].isVisited=1;   
  248.             g.AddKnownVertex(startName,table);   
  249.         }   
  250.     }   
  251.        
  252.     for(;;)   
  253.     {   
  254.         PriorityQueue pq=Initialize(g.verNum);   
  255.         int i;   
  256.         for(i=0;i<g.verNum;i++)   
  257.         {   
  258.             if(!table[i].isVisited)   
  259.             {   
  260.                 Insert(table[i].currentWeight,pq);   
  261.             }   
  262.         }   
  263.        
  264.         int min=DeleteMin(pq);   
  265.         for(i=0;i<g.verNum;i++)   
  266.         {   
  267.             if(table[i].currentWeight==min)   
  268.             {   
  269.                 table[i].isVisited=1;   
  270.                 g.AddKnownVertex(table[i].name,table);   
  271.             }   
  272.         }   
  273.   
  274.         Destroy(pq);   
  275.   
  276.         for(i=0;i<g.verNum;i++)   
  277.         {   
  278.             if(table[i].isVisited==0)   
  279.             {   
  280.                 continue;   
  281.             }   
  282.         }   
  283.         break;   
  284.     }   
  285.     return table;   
  286. }   
  287.   
  288. int main()   
  289. {   
  290.     NonDireGraph ndg(7);   
  291.     Entry *table=Prim(ndg,"V1");   
  292.     for(int i=0;i<ndg.verNum;i++)   
  293.     {   
  294.         cout<<table[i].name<<' ';   
  295.         cout<<table[i].isVisited<<' ';   
  296.         cout<<table[i].currentWeight<<' ';   
  297.         cout<<table[i].lastVisited<<endl;   
  298.     }   
  299.     DisposeEntry(table);   
  300.   
  301.     return 0;   
  302. }   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值