利用反圈法寻找无向图的所有连通子图

来源:互联网 发布:微信淘宝天猫内部优惠 编辑:程序博客网 时间:2024/06/09 04:17


1)       算法思想:

     利用构造反圈逐一寻找连通子图。初始化原图中的每个顶点为false,将已经找到的完整连通子图的顶点存入一个矩阵C中的一行,并将原始图中已加入反圈中的顶点标记为true;继续在原图中标记为false的顶点中构造反圈,寻找下一个连通子图,并将对应顶点加入矩阵C的下一行;如此循环,直到原图中所有顶点都标记为true为止。下面将此思想转化为具体的算法,不妨令算法名称为:反圈法寻找无向图的所有连通子图。

2)       算法描述:


3)       程序

  • 构造边结构程序

  • package sy1;/* * 构造图的边结构 */public class Arc {public Vnode firstNode;//定义边的始点public Vnode LastNode;//定义边的中点public Arc NextArc;//定义边的下一条边public boolean flag;//标识边是否访问过public boolean isFlag() {return flag;}public void setFlag(boolean flag) {this.flag = flag;}public Arc getNextArc() {return NextArc;}public void setNextArc(Arc nextArc) {NextArc = nextArc;}public Vnode getLastNode() {return LastNode;}public void setLastNode(Vnode lastNode) {LastNode = lastNode;}public int weight;//定义边对应的权值//建立一条具有权值weight的边public Arc(int weight){this(null,null,null,weight);}public Arc(Vnode firstNode,Vnode LastNode,int weight){this(firstNode,LastNode,null,weight);}public Arc(Vnode firstNode,Vnode LastNode,Arc NextArc,int weight){this.firstNode=firstNode;this.LastNode=LastNode;this.NextArc=NextArc;this.weight=weight;}public Vnode getFirstNode() {return firstNode;}public void setFirstNode(Vnode firstNode) {this.firstNode = firstNode;}public int getWeight() {return weight;}public void setWeight(int weight) {this.weight = weight;}}

  • 构造顶点结构程序

  • package sy1;/* * 建立一个图中的顶点结构 */public class Vnode {public int vw;//顶点的序数(即表示第几个顶点)public String V;//顶点的名称public boolean flag;//标识顶点是否访问过,如果flag=false表示没有被访问过public boolean isFlag() {return flag;}public void setFlag(boolean flag) {this.flag = flag;}public String getV() {return V;}public void setV(String v) {V = v;}public int getVw() {return vw;}public void setVw(int vw) {this.vw = vw;}public Arc aw[];//表明从顶点出发的边的权重集public Vnode next[];//从顶点出发的边的终点public Vnode[] getNext() {return next;}public Arc[] getAw() {return aw;}public void setNext(Vnode next[]) {this.next = next;}public Vnode(String V,int vw,boolean flag){this.vw=vw;this.V=V;this.flag=flag;}//返回顶点位置public Vnode(String V,int vw){this(V,vw,false);}}

  • 定义网络流图的边结构

  • package sy1;/* * 定义网络流图的边结构 */public class FlowArc {public Vnode firstNode;//定义边的始点public Vnode LastNode;//定义边的中点public Arc NextArc;//定义边的下一条边public int flow;//定义边的流量值public int Capacity;//定义边的容量值public int cost;//定义边的费用值//构造函数public FlowArc(Vnode u,Vnode v,Arc s,int c,int f,int b){this.firstNode=u;this.LastNode=v;this.NextArc=s;this.flow=f;this.Capacity=c;this.cost=b;}//始点public Vnode getFirstNode() {return firstNode;}public void setFirstNode(Vnode firstNode) {this.firstNode = firstNode;}//终点public Vnode getLastNode() {return LastNode;}public void setLastNode(Vnode lastNode) {LastNode = lastNode;}//邻接边public Arc getNextArc() {return NextArc;}public void setNextArc(Arc nextArc) {NextArc = nextArc;}//流量public int getFlow() {return flow;}public void setFlow(int flow) {this.flow = flow;}//容量public int getCapacity() {return Capacity;}public void setCapacity(int capacity) {Capacity = capacity;}//费用public int getCost() {return cost;}public void setCost(int cost) {this.cost = cost;}}

  • 图的类型

  • package sy1;public enum GraphKind {Gra,//无向图Digra,//有向图FlowGra,//费用流图CostFlowGra;//网络流图}

  • 图结构接口程序

  • package sy1;/* * 新建一个图结构接口 */public interface IGraph {public void createGraph() throws Exception;//新建图public int getVexNum();//返回图中顶点数public int getArcNum();//返回图中边数public String getVex(int v) throws Exception;//给定顶点v所处的位置,返回顶点对应顶点名称public int locateVex(String v) throws Exception;//给定顶点名称,返回对应顶点的位置public int firstAdjVex(int v) throws Exception;//给定顶点所处位置,返回该顶点的第一个邻接点public int nextAdjVex(int v,int w) throws Exception;//给定顶点v以及它的邻接点w对应的位置,返回顶点相对于w的下一个邻接点的位置}

  • 构造一条路径的长度

  • package sy1;/* * 构造路径长度路径结构 */public class lengthOfPath {int lamda;//路径长度String recent;//本路径中当下顶点的前一个顶点String past;//初始化路径public lengthOfPath(String v){this.lamda=0;this.recent=v;this.past=null;}public int getLamda() {return lamda;}public void setLamda(int lamda) {this.lamda = lamda;}public String getRecent() {return recent;}public void setRecent(String recent) {this.recent = recent;}public String getPast() {return past;}public void setPast(String past) {this.past = past;}}

  • 构造图结构程序

  • package sy1;import java.util.Scanner;/* * 构造图结构 */public class MyGraph implements IGraph {public final static int Inf=Integer.MAX_VALUE;//表示整型无穷大,用来标识两个顶点是否有边相连public GraphKind kind;//定义图的类型public int vexNum,arcNum;//定义顶点以及边的数目public int vw[];//顶点位置集public Vnode[] V;//顶点结构public Arc[] A;//边结构public String[] v;//顶点名称集public int[][] arcs;//邻接矩阵也就是边的关系public int[][][] F;//网络流图构成的邻接矩阵public void createGraph() throws Exception {Scanner s=new Scanner(System.in);System.out.println("请输入所要构建的图的类型:");GraphKind kind=GraphKind.valueOf(s.next());//开关语句选择构图方法switch(kind){case Gra:createGra();//构造无向图return;case Digra:createDigra();//构造有向图return;case FlowGra:createFlow();//构造有向图return;case CostFlowGra:createCostFlow();}}/* * 构造网络流图包含费用 */private void createFlow() throws Exception {Scanner s=new Scanner(System.in);System.out.println("请分别输入图的顶点数和边数;");vexNum=s.nextInt();//输入顶点数arcNum=s.nextInt();//输入边数v=new String[vexNum];vw=new int[vexNum];V=new Vnode[vexNum];for(int i=0;i<vexNum;i++){V[i]=new Vnode(v[i],vw[i]);//定义顶点集}System.out.println("请分别输入图的各个顶点:");for(int i=0;i<vexNum;i++){String S=s.next();int vw=s.nextInt();V[i].setV(S);V[i].setVw(vw);}//初始化邻接矩阵F=new int[vexNum][vexNum][2];for(int i=0;i<vexNum;i++){for(int j=0;j<vexNum;j++){F[i][j][0]=Inf;//初始化容量值F[i][j][1]=Inf;//初始化流量值}}System.out.println("请输入每条边的两个顶点及其相关参数:");for(int i=0;i<arcNum;i++){int v=locateVex(s.next());//输入起始点int u=locateVex(s.next());//输入终点for(int j=0;j<2;j++){F[v][u][j]=s.nextInt();}}}private void createCostFlow() throws Exception {Scanner s=new Scanner(System.in);System.out.println("请分别输入图的顶点数和边数;");vexNum=s.nextInt();//输入顶点数arcNum=s.nextInt();//输入边数v=new String[vexNum];vw=new int[vexNum];V=new Vnode[vexNum];for(int i=0;i<vexNum;i++){V[i]=new Vnode(v[i],vw[i]);//定义顶点集}System.out.println("请分别输入图的各个顶点:");for(int i=0;i<vexNum;i++){String S=s.next();int vw=s.nextInt();V[i].setV(S);V[i].setVw(vw);}//初始化邻接矩阵F=new int[vexNum][vexNum][3];for(int i=0;i<vexNum;i++){for(int j=0;j<vexNum;j++){F[i][j][0]=Inf;//初始化容量值F[i][j][1]=Inf;//初始化流量值F[i][j][3]=Inf;//初始化费用}}System.out.println("请输入每条边的两个顶点及其相关参数:");for(int i=0;i<arcNum;i++){int v=locateVex(s.next());//输入起始点int u=locateVex(s.next());//输入终点for(int j=0;j<3;j++){F[v][u][j]=s.nextInt();}}}/* * 构造有向图 */private void createDigra() throws Exception {Scanner s=new Scanner(System.in);System.out.println("请分别输入图的顶点数和边数;");vexNum=s.nextInt();//输入顶点数arcNum=s.nextInt();//输入边数v=new String[vexNum];vw=new int[vexNum];V=new Vnode[vexNum];A=new Arc[arcNum];for(int i=0;i<vexNum;i++){V[i]=new Vnode(v[i],vw[i]);//定义顶点集}System.out.println("请分别输入图的各个顶点:");for(int i=0;i<vexNum;i++){String S=s.next();int vw=s.nextInt();V[i].setV(S);V[i].setVw(vw);}//初始化邻接矩阵arcs=new int[vexNum][vexNum];for(int i=0;i<vexNum;i++){for(int j=0;j<vexNum;j++){arcs[i][j]=Inf;}}System.out.println("请输入每条边的两个顶点及其权值:");for(int i=0;i<arcNum;i++){int v=locateVex(s.next());//输入起始点int u=locateVex(s.next());//输入终点arcs[v][u]=s.nextInt();//输入顶点v到顶点u的弧的权重值A[i]=new Arc(V[v],V[u],arcs[v][u]);}}/* * 构造无向图 */private void createGra() throws Exception {Scanner s=new Scanner(System.in);System.out.println("请分别输入图的顶点数和边数;");vexNum=s.nextInt();//输入顶点数arcNum=s.nextInt();//输入边数v=new String[vexNum];vw=new int[vexNum];V=new Vnode[vexNum];for(int i=0;i<vexNum;i++){V[i]=new Vnode(v[i],vw[i]);//定义顶点集}System.out.println("请分别输入图的各个顶点:");for(int i=0;i<vexNum;i++){String S=s.next();int vw=s.nextInt();V[i].setV(S);V[i].setVw(vw);}//初始化邻接矩阵arcs=new int[vexNum][vexNum];for(int i=0;i<vexNum;i++){for(int j=0;j<vexNum;j++){arcs[i][j]=Inf;}}System.out.println("请输入每条边的两个顶点及其权值:");for(int i=0;i<arcNum;i++){int v=locateVex(s.next());//输入起始点int u=locateVex(s.next());//输入终点arcs[v][u]=arcs[u][v]=s.nextInt();//输入顶点v到顶点u的弧的权重值}}public int getVexNum() {return vexNum;}public int getArcNum() {return arcNum;}//如果已知顶点在邻接矩阵中的位置,返回顶点的名称public String getVex(int v) throws Exception{if(v<0 || v>vexNum){throw new Exception("第"+v+"个顶点不存在");}return V[v].getV();}//判断所给的顶点名称是否是图中的顶点,如果是则返回顶点所在的位置public int locateVex(String v) throws Exception {for(int i=0;i<vexNum;i++){//System.out.println(v);if(getVex(i).equals(v)){//System.out.println(i);return i;}}return -1;}//返回v位置顶点的下一个邻接点的位置public int firstAdjVex(int v) throws Exception {if(v<0 || v>vexNum){throw new Exception("第"+v+"个顶点不存在");}for(int i=0;i<vexNum;i++){if(arcs[v][i]!=-1 && arcs[v][i]<Inf){return i;}}return -1;}//已知始点和终点的位置,返回该边在边集合A中的下标public int FirstIndex(int a,int b){for(int i=0;i<arcNum;i++){if(A[i].getFirstNode().getVw()==a && A[i].getLastNode().getVw()==b){return i;}}return -1;}//返回v位置顶点的下一个邻接点的位置(即查找v的下一个邻接点)public int nextAdjVex(int v, int w) throws Exception {if(v<0 || v>=vexNum){throw new Exception("第"+v+"个顶点不存在!");}// ifVnode vex=V[v];//找到位置v上的顶点Arc arcvw=null;//初始化一条边for(Arc arc=vex.getAw()[0];arc!=null;arc=arc.NextArc){if(arc.getFirstNode().getVw()==w){arcvw=arc;break;}// if}// forif(arcvw!=null && arcvw.getNextArc()!=null){return arcvw.getNextArc().getFirstNode().getVw();}elsereturn -1;}/*public static void main(String args[]) throws Exception{int n=0,m=0;MyGraph G=new MyGraph();G.createGraph();System.out.println("请输出所构建图的邻接矩阵:");for(int i=-1;i<G.getVexNum();i++){if(i<0){System.out.print("     ");for(int j=0;j<G.getVexNum();j++){System.out.print(G.getVex(j)+"    ");}System.out.println();}else{for(int j=-1;j<G.getVexNum();j++){if(j<0){System.out.print(G.getVex(i)+"    ");}else{                         if(G.arcs[i][j]==Inf){                         System.out.print("INF"+"    ");}//  if                         else{                         System.out.print(G.arcs[i][j]+"    ");                         }//else}// else}// forSystem.out.println();}// else}// for}*/}

  • 用反圈法实现最短路径

  • package sy1;import java.util.Scanner;/* * 利用反圈法实现最短路径算法 */public class ShortestPath {public final static int Inf=Integer.MAX_VALUE;//表示整型无穷大,用来标识两个顶点是否有边相连public int[][] M;//有向图邻接矩阵public Vnode[] V;//有向图的顶点集public Vnode X[];//反圈中的顶点集public Arc F[];//反圈中的边集合public String Vs;//路径起始点public String Vt;//路径终止点public int ArcNum;public int num;//反圈中的边数lengthOfPath L[];//始点到对应位置顶点的路径长度public boolean Flag=true;public int SL=0;;//构造方法public ShortestPath(int M[][],Vnode V[],int ArcNum){this.M=M;this.V=V;this.ArcNum=ArcNum;X=new Vnode[V.length];F=new Arc[ArcNum];L=new lengthOfPath[X.length];}/* * 最短路径实现方法 */public String ShortPath(String Vs,String Vt){int num=0;int k=0;this.Vs=Vs;this.Vt=Vt;String st="";String S[]=new String[X.length];//初始化Sfor(int i=0;i<S.length;i++){S[i]="";}for(int i=0;i<ArcNum;i++){F[i]=new Arc(Inf);}S[k]=Vt;k++;for(int i=0;i<X.length;i++){X[i]=new Vnode("",i);//System.out.println(V[i].getV()+"空");L[i]=new lengthOfPath(X[i].getV());}for(int i=0;i<V.length;i++){V[i].setFlag(false);//System.out.println(Vs+V[i].getV());if(Vs.equals(V[i].getV())){X[i].setV(V[i].getV());  //对反圈的顶点集进行初始化//System.out.println(X[i].getV());V[i].setFlag(true);//表示V[i]点已经被访问过L[i]=new lengthOfPath(Vs);L[i].setPast(null);//初始化Vs的前一个顶点的名称为nullL[i].setLamda(0);//初始化Vs-->Vs的路径长度为0}if(Vt.equals(V[i].getV())){num=i;//S[i]=Vt;}}boolean f1=ZX(Vt);if(f1==true){Flag=false;return "";}else{String temp=L[num].getRecent();//得到终点的名称SL=L[num].getLamda();while(!temp.equals(Vs) && k<X.length){for(int i=0;i<X.length;i++){if(temp.equals(X[i].getV())){num=i;}}temp=L[num].getPast();S[k]=temp;k++;}k=0;for(int i=S.length-1;i>0;i--){if(!S[i].equals("")){st=st+S[i]+"---->";}}st=st+S[0];return st;}}/* * 构造正向反圈的方法 */public boolean ZX(String Vt){boolean f=false;//用来判断是否有路boolean flag=false;//用来判断反圈中的顶点集是否等于图的顶点集boolean flag1=true;//用来判断反圈是否为空int min=Inf;//用来求取最小权值弧长int index1=0;//用来表示权值最小的非反圈对应点的位置int index2=0;//用来表示权值最小的反圈对应点的位置//如果反圈中顶点集不等于图的顶点集,就继续反圈运算/*for(int i=0;i<X.length;i++){if(X[i].getV().equals(Vt)){flag=false;break;}}*/while(flag==false){flag1=true;min=Inf;for(int i=0;i<X.length;i++){if(!X[i].getV().equals("")){for(int j=0;j<V.length;j++){if(V[j].isFlag()==false && M[X[i].getVw()][V[j].getVw()]!=Inf){if((L[i].lamda+M[X[i].getVw()][V[j].getVw()])<min){min=M[X[i].getVw()][V[j].getVw()]+L[i].lamda;index1=j;index2=i;//System.out.println(index2+" "+index1);}// if}// if}// for}// if}// forif(index1!=-1 && index2!=-1){X[index1]=new Vnode(V[index1].getV(),index1);//将该点加入反圈的点集合V[index1].setFlag(true);L[index1]=new lengthOfPath(X[index1].getV());L[index1].setPast(X[index2].getV());//设置当前顶点的前一个顶点//System.out.println(X[index1].getV()+" "+L[index1].getPast()+" "+index1);L[index1].setLamda(L[index2].getLamda()+M[index2][index1]);//计算路径长度F[num]= new Arc(X[index2],V[index1],M[index2][index1]);}index1=-1;index2=-1;for(int i=0;i<F.length;i++){if(F[i].getWeight()!=Inf){flag1=false;//表示反圈中已有元素,即不为空//System.out.println(flag1+"  "+Inf+"    "+F[i].getWeight());break;}}for(int i=0;i<F.length;i++){F[i]= new Arc(null,null,Inf);//System.out.println(F[num].getWeight());}for(int i=0;i<X.length;i++){if(X[i].getV().equals(Vt)){flag=true;break;}}//System.out.println(flag+"  "+flag1);if(flag1==true){f=true;break;}}// whilereturn f;}public static void main(String args[]) throws Exception{//实现最短路径String L;String vs;String vt;Scanner s=new Scanner(System.in);MyGraph G=new MyGraph();G.createGraph();System.out.println("请输出所构建图的邻接矩阵:");for(int i=-1;i<G.getVexNum();i++){if(i<0){System.out.print("          ");for(int j=0;j<G.getVexNum();j++){System.out.print(G.getVex(j)+"         ");}System.out.println();}else{for(int j=-1;j<G.getVexNum();j++){if(j<0){System.out.print(G.getVex(i)+"         ");}else{                         if(G.arcs[i][j]==Inf){                         System.out.print("INF"+"         ");}                         else{                         System.out.print(G.arcs[i][j]+"         ");                         }}//else}// ifSystem.out.println();}// for}//elseShortestPath S=new ShortestPath(G.arcs,G.V,G.getArcNum());System.out.println("请输入初始点:");vs=s.next();System.out.println("请输入终点:");vt=s.next();System.out.println("请输出所求的最短路径:");L=S.ShortPath(vs, vt);if(!L.equals("")){System.out.println(L);}System.out.println("这条最短路径的长度: "+S.SL);}}

  • 找出连通图的所有连通分支

  • package sy1;/* * 判断一个图是否是连通的 */public class FindConnectedSubGraph {public final static int Inf=Integer.MAX_VALUE;//表示整型无穷大,用来标识两个顶点是否有边相连public int[][] M;//有向图邻接矩阵public Vnode[] V;//有向图的顶点集public Vnode X[];//反圈中的顶点集public Vnode C[][];//用来存储图的连通分支public int c=0;//用来表示图的连通分支的数目public Arc F[];//反圈中的边集public int ArcNum;public int num;//反圈中的边数public FindConnectedSubGraph(int M[][],Vnode V[],int ArcNum){this.M=M;this.V=V;this.ArcNum=ArcNum;X=new Vnode[V.length];//初始化反圈顶点集X[0]=new Vnode(V[0].getV(),V[0].getVw());V[0].setFlag(true);for(int i=1;i<X.length;i++){X[i]=new Vnode("",i);}F=new Arc[ArcNum];//初始化反圈集C=new Vnode[V.length][V.length];for(int i=0;i<V.length;i++){for(int j=0;j<V.length;j++){C[i][j]=new Vnode("",j);}}num=0;}public int ZF(){int count,count1=0,count2=0,index1=-1,index2=-1;for(int i=0;i<V.length;i++){if(!V[i].isFlag()){count2++;}}//System.out.println("count2="+count2);while(count1-1!=count2){//表示反圈已满//System.out.println("count2="+count2);count=0;count1=0;for(int i=0;i<V.length;i++){if(!X[i].getV().equals("")){//对于非反圈集合中的每一个顶点for(int j=0;j<V.length;j++){if(!V[j].isFlag()){//对于反圈中的每一个顶点if(M[X[i].getVw()][V[j].getVw()]!=Inf){//反圈中的顶点和非反圈中的顶点之间有边相连index1=j;index2=i;count++;//表示反圈中增加边break;}//if}}//for}//if if(count!=0){break;}}//forfor(int k=0;k<V.length;k++){if(!X[k].getV().equals("")){count1++;}// if}//for//System.out.println("count="+count+",count1="+count1+",count2="+count2);if(index1!=-1 && index2!=-1){X[index1]=new Vnode(V[index1].getV(),index1);//将该点加入反圈的点集合V[index1].setFlag(true);index1=-1;index2=-1;}else if(count==0 && count1-1!=count2){//System.out.println("count="+count+",count1="+count1+",count2="+count2);for(int l=0;l<V.length;l++){//System.out.print(X[l].getV()+"     ");if(!X[l].getV().equals("")){C[c][l]=new Vnode(X[l].getV(),X[l].getVw());}}// for//System.out.println();c++;//System.out.println("c="+c);for(int i=0;i<V.length;i++){if(!V[i].isFlag()){X[0]=new Vnode(V[i].getV(),i);V[i].setFlag(true);break;}// if}// forfor(int i=1;i<V.length;i++){X[i]=new Vnode("",i);}if(ZF()==0){count2=0;break;}//System.out.println("false");}else if(count1-1==count2){for(int l=0;l<V.length;l++){//System.out.print(X[l].getV()+"     ");if(!X[l].getV().equals("")){C[c][l]=new Vnode(X[l].getV(),X[l].getVw());}}// for//System.out.println();break;}//表示已经找到了一个子图}// ifreturn count2;}public static void main(String args[]) throws Exception{//实现最短路径MyGraph G=new MyGraph();G.createGraph();System.out.println("请输出所构建图的邻接矩阵:");for(int i=-1;i<G.getVexNum();i++){if(i<0){System.out.print("          ");for(int j=0;j<G.getVexNum();j++){System.out.print(G.getVex(j)+"         ");}System.out.println();}else{for(int j=-1;j<G.getVexNum();j++){if(j<0){System.out.print(G.getVex(i)+"         ");}else{                         if(G.arcs[i][j]==Inf){                         System.out.print("INF"+"         ");}                         else{                         System.out.print(G.arcs[i][j]+"         ");                         }}//else}// ifSystem.out.println();}// for}//elseFindConnectedSubGraph I=new FindConnectedSubGraph(G.arcs,G.V,G.arcNum);I.ZF();if(I.c==0){System.out.println("原图是连通的,它总的有"+(I.c+1)+"个连通子图!"+"它的连通子图就是它本身!");}else{System.out.print("原图不连通,它总的有"+(I.c)+"个连通子图!");for(int i=0;i<I.c;i++){System.out.println("第"+(i+1)+"个连通子图对应的邻接矩阵");String m[]=new String[G.vexNum];int index[]=new int[G.vexNum];int count=0;for(int j=0;j<I.V.length;j++){if(!I.C[i][j].getV().equals("")){//System.out.print(I.C[i][j].getV()+"    ");m[count]=I.C[i][j].getV();index[count]=I.C[i][j].getVw();count++;}//System.out.println();}for(int j=-1;j<count;j++){if(j<0){System.out.print("          ");for(int k=0;k<count;k++){System.out.print(m[k]+"         ");}System.out.println();}else{for(int k=-1;k<count;k++){if(k<0){System.out.print(m[j]+"         ");}else{                         if(G.arcs[index[j]][index[k]]==Inf){                         System.out.print("INF"+"         ");}                         else{                         System.out.print(G.arcs[index[j]][index[k]]+"         ");                         }}//else}// ifSystem.out.println();}// for}//else}//else}//if}}

4) 示例:


代入上面程序示例输出:


对于图(1)

对于图(2)


对于图(3)

对于图(4)


5) 算法总结:

1)算法的主要思想是反圈法求支撑树,但是当不连通时要调用反圈法继续求剩下图的支撑树,整个过程是对反圈法求支撑树的一个迭代。

2)在编程过程中,需要注意的一点是,当从迭代内部出来时要记得将迭代外部的数据释放掉,不然运行出来的结果就会是错的。
0 0