邻接表实现PRIM算法(C++)

参考张宪超老师《数据结构、算法及应用》
原理:
G=是一个连通的带权无向图。Prim算法通过不断地增加生成树的顶点来得到最小生成树。在算法的任一时刻,一部分顶点已经添加到生成树的顶点集合中,而其余顶点尚未加到生成树中。此时,Prim算法通过选择边,使得的权值是所有u(起点)在生成树中,但v(终点)不在生成树中的边的权值最小者,从而找到新的顶点v把她添加到生成树中。
详细步骤:
1)初始状态,U={u1},TE={}。其中,u1是图顶点集合的某一顶点。
2)在所有u∈U,v∈V-U的边(u,v)中寻找代价最小的边(u',v'),并纳入集合TE中;同时将v'纳入集合U中。确保这一过程中不产生回路。
3)如果u=v,则算法结束;否则重复2.
代码实现:
#include #include using namespace std; class edge{ public: int start; int end; int weight; edge(int strt,int ed,int w){ start=strt; end=ed; weight=w; } edge(){ start=-1; end=-1; weight=-1; } }; //邻接表 class listnode{ public: int listver; int edgenam; int weight; listnode * next; listnode(listnode * nextval=NULL){ next=nextval; } listnode(const int& lv,const int& en,const int & w,listnode* nextval=NULL){ listver=lv; edgenam=en; weight=w; next=nextval; } }; class headnode{ public: listnode *start; headnode(){ start=new listnode(); } void removeall(){ listnode *tmp; while(start!= NULL){ tmp=start; start=start->next; delete tmp; } } ~headnode(){ removeall(); } }; class listgraph{ private: headnode* gralist; public: int vertexnum; int edgenum; int *mark; //访问过为1,未访问为0; listgraph(int n){ vertexnum=n; edgenum=0; mark=new int[vertexnum]; for(int i=0;inext!=NULL) { tmpedge.end=tmplst->listver; } return tmpedge; } edge nextedge(edge oneedge){ edge tmpedge; tmpedge.start=oneedge.start; listnode* tmplst=gralist[oneedge.start].start; while(tmplst->next!=NULL&&tmplst->next->listver<=oneedge.end) tmplst=tmplst->next; if(tmplst->next!=NULL) { tmpedge.end=tmplst->next->listver; } return tmpedge; } void setedge(int strt,int end,int wt){ listnode* tmplst=gralist[strt].start; while(tmplst->next!=NULL&&tmplst->next->listvernext; //确定该边在边结点插入位置 //边在边结点中不存在 if(tmplst->next==NULL){ tmplst->next=new listnode; tmplst->next->listver=end; tmplst->next->edgenam=edgenum; tmplst->next->weight=wt; edgenum++; setedge(end,strt,wt); return; } //边在边结点中已存在 if(tmplst->next->listver==end){ edgenum--; return; } //边在边结点中不存在,但在边表中其后存在其他边 if(tmplst->next->listver>end) { listnode* tmp=tmplst->next; tmplst->next=new listnode; tmplst->next->listver=end; tmplst->next->edgenam=edgenum; tmplst->next->next->weight=wt; tmplst->next->next=tmp; edgenum++; setedge(end,strt,wt); return; } } void deledge(int start,int end){ listnode* tmplst=gralist[start].start; while(tmplst->next!=NULL&&tmplst->next->listvernext; if(tmplst->next==NULL){ cout<<"couldn't find"<next->listver==end) { listnode * tmp=tmplst->next->next; delete tmplst->next; tmplst->next=tmp; edgenum--; } } void show(int v){ cout<"<listver<<" "<edgenam; while(tmp->next!=NULL) { tmp=tmp->next; cout<<"->"<listver<<" "<edgenam; } } return; } void show(){ cout<<"邻接表展示如下"<next;tmp!= NULL;tmp=tmp->next) { nearest[tmp->listver]=tmp->weight; } neighbor[s]=-1;//将已加入到生成树的点的最近邻设置成-1 for(i=1;i-1){ min=nearest[j]; v=j; } } if(v>=0){ //将V加入到生成树集合中,更新生成树外的各个点最小权值的边信息 neighbor[v]=-1; edge tempedge(-2,v,nearest[v]); mst[i]=tempedge;//将边加入到生成树集合中 for(listnode* tmp=gralist[v].start->next;tmp!=NULL;tmp=tmp->next){ int u=tmp->listver; if(neighbor[u]!=-1&&nearest[u]>tmp->weight){ //用于V关联的边更新生成树之外顶点到生成树集合的最小权值边 neighbor[u]=v; nearest[u]=tmp->weight; } } } } delete[]neighbor; delete[]nearest; cout<<"after prim(from V"<


你可能感兴趣的:(菜鸡敲代码)