数据结构实验——图的最小生成树和最短路径(有向图无向图判断)

实验一:判断一个无向图是不是一棵树

  public boolean isTree()

实验二:判断两个图是否相同

  public boolean equlas(Object obj)

实验方法与步骤(需求分析、算法设计思路、流程图等)

  1. 判断一个无向图是不是一棵树

判断一个图有n个结点,同时具有n-1条边,同时该图是个连通图。若满足条件,则是二叉树,否则并不是二叉树。

  1. 判断两个图是否相同

通过遍历,比较结点和边的数量,同时比较边的权值,若都相同,则返回true,否则返回false。

四、实验原始纪录(源程序、数据结构等)

public abstract class AbstractGraph<T>                    

{

    protected static final int MAX_WEIGHT=99999;

    protected SeqList<T> vertexlist;

    boolean directed;

    public AbstractGraph(int length)                       

    {

        this.vertexlist = new SeqList<T>(length);

    //    System.out.println(this.vertexlist);

    }

    public AbstractGraph()                                 

    {

        this(10);                                        

    }

    public int vertexCount()                             

    {

        return this.vertexlist.size();                     

    }

    public int edeCount()

    {

return 0;

    }

    public String toString()                            

    {

        return "顶点集合:"+this.vertexlist.toString()+"\n";

    }

    public T getVertex(int i)                        

    {

        return this.vertexlist.get(i);                

    }

    public void setVertex(int i, T x)                      

    {

        this.vertexlist.set(i,x);                          

    }

    

    public abstract int insertVertex(T x);               

    public abstract void removeVertex(int i);              

    public abstract int weight(int i, int j);             

    protected abstract int next(int i, int j);

    public void DFSTraverse(int i)                         

    {

        boolean[] visited=new boolean[this.vertexCount()];

        int j=i;

        do

        {   if (!visited[j])                             

            {

                System.out.print("{ ");

                this.depthfs(j, visited);                

                System.out.print("} ");

            }

            j = (j+1) % this.vertexCount();               

        } while (j!=i);

        System.out.println();

    }

    private void depthfs(int i, boolean[] visited)

    {

        System.out.print(this.getVertex(i)+" ");          

        visited[i] = true;                                

        for (int j=this.next(i,-1); j!=-1; j=this.next(i,j))

            if(!visited[j])                             

                depthfs(j, visited);                   

    }

    public void BFSTraverse(int i)                        

    {

        boolean[] visited = new boolean[this.vertexCount()];

        int j=i;

        do

        {   if (!visited[j])                            

            {

                System.out.print("{ ");

                breadthfs(j, visited);                    

                System.out.print("} ");

            }

            j = (j+1) % this.vertexCount();             

        } while (j!=i);

        System.out.println();

    }

    private void breadthfs(int i, boolean[] visited)

    {

        System.out.print(this.getVertex(i)+" ");         

        visited[i] = true;                                 

        LinkedQueue<Integer> que = new LinkedQueue<Integer>();

        que.add(i);                                        

        while (!que.isEmpty())                            

        {

            i = que.poll();                               

            for (int j=next(i,-1); j!=-1; j=next(i,j))    

                if (!visited[j])                          

                {

                    System.out.print(this.getVertex(j)+" ");

                    visited[j] = true;

                    que.add(j);                                          

                }

        }

    }

    public void minSpanTree()

    {

        Triple[] mst = new Triple[vertexCount()-1];       

        for (int i=0; i<mst.length; i++)                   

            mst[i]=new Triple(0,i+1,this.weight(0,i+1));   

        for (int i=0; i<mst.length; i++)                   

        {

            System.out.print("mst边集合:");

            for(int j=0; j<mst.length; j++)

                System.out.print(mst[j].toString()+",");            

            System.out.println();            

                

            int min=i;           

            for (int j=i+1; j<mst.length; j++)             

                if (mst[j].value < mst[min].value)

                {

                    min = j;                            

                }

            

            Triple edge = mst[min];

            if (min!=i)

            {

                mst[min] = mst[i];

                mst[i] = edge;

            }

            int tv = edge.column;                         

            for (int j=i+1; j<mst.length; j++)

            {

                int v = mst[j].column;                    

                int weight = this.weight(tv,v);

                if (weight<mst[j].value)                   

                    mst[j] = new Triple(tv,v,weight);

            }

        }

        

        System.out.print("\n最小生成树的边集合:");

        int mincost=0;

        for (int i=0; i<mst.length; i++)           

        {

            System.out.print(mst[i]+" ");

            mincost += mst[i].value;

        }

        System.out.println(",最小代价为"+mincost);

    }

    public void shortestPath(int i)              

    {

        int n = this.vertexCount();           

        boolean[] vset = new boolean[n];       

        vset[i] = true;                         

        int[] dist = new int[n];                

        int[] path = new int[n];                

        for (int j=0; j<n; j++)                 

        {

            dist[j] = this.weight(i,j);

            path[j] = (j!=i && dist[j]<MAX_WEIGHT) ? i : -1;

        }

//        System.out.print("\nvset数组"+toString(vset));

//        System.out.print("\tpath数组"+toString(path));

//        System.out.print("\tdist数组"+toString(dist));

        

        for (int j=(i+1)%n; j!=i; j=(j+1)%n)   

        {

            int mindist=MAX_WEIGHT, min=0;    

            for (int k=0; k<n; k++)

                if (!vset[k] && dist[k]<mindist)

                {

                    mindist = dist[k];        

                    min = k;                    

                }

            if (mindist==MAX_WEIGHT)            

                break;

            vset[min] = true;                    

            for (int k=0; k<n; k++)              

                if (!vset[k] && this.weight(min,k)<MAX_WEIGHT && dist[min]+this.weight(min,k)<dist[k])

                {

                    dist[k] = dist[min] + this.weight(min,k);

                    path[k] = min;                 

                }    

//            System.out.print("\nvset数组"+toString(vset));

//            System.out.print("\tpath数组"+toString(path));

//            System.out.print("\tdist数组"+toString(dist));

        }

        System.out.print(this.getVertex(i)+"的单源最短路径:");

        for (int j=0; j<n; j++)                           

            if (j!=i)

            {

                SinglyList<T> pathlink = new SinglyList<T>();

                pathlink.insert(0, this.getVertex(j));    

                for (int k=path[j]; k!=i && k!=j && k!=-1; k=path[k])

                    pathlink.insert(0, this.getVertex(k));

                pathlink.insert(0, this.getVertex(i));    

                System.out.print(pathlink.toString()+"长度"+(dist[j]==MAX_WEIGHT ? "∞" : dist[j])+",");

            }

        System.out.println();

    }

    private static String toString(int[] value)   

    {

        if (value!=null && value.length>0)

        {

            String str="{";

            int i=0;

            for(i=0; i<value.length-1; i++)

                str += (value[i]==MAX_WEIGHT ? "∞" : value[i])+",";

            return str+(value[i]==MAX_WEIGHT ? "∞" : value[i])+"}";

        }

        return null;        

    }

    

    public void shortestPath()                 

    {

        int n=this.vertexCount();                          

        Matrix path=new Matrix(n), dist=new Matrix(n);    

        for (int i=0; i<n; i++)                            

            for (int j=0; j<n; j++)

            {   int w=this.weight(i,j);

                dist.set(i,j,w);                          

                path.set(i,j, (i!=j && w<MAX_WEIGHT ? i : -1));

            }

        System.out.println("dist"+dist.toString()+"path"+path.toString()+"路径矩阵:");

        printPathAll(path);

        for (int k=0; k<n; k++)                     

        {

            System.out.println("\n以"+this.getVertex(k)+"作为中间顶点,替换路径如下:");

            for (int i=0; i<n; i++)                       

                if (i!=k)

                    for (int j=0; j<n; j++)

                        if (j!=k && j!=i)

                        {

                        System.out.print(toPath(path,i,j)+"路径长度"+dist.get(i,j)+",替换为"+

                            toPath(path,i,k)+","+toPath(path,k,j)+"路径长度"+(dist.get(i,k)+dist.get(k,j))+"?");

                        if (j!=k && j!=i && dist.get(i,j) > dist.get(i,k)+dist.get(k,j))

                        {

                            dist.set(i, j, dist.get(i,k)+dist.get(k,j));

                            path.set(i, j, path.get(k,j));

                            System.out.println("是,d"+i+j+"="+dist.get(i,j)+",p"+i+j+"="+path.get(i,j));

                        }

                        else

                            System.out.println("否");

                        }

            System.out.println("dist"+dist.toString()+"path"+path.toString()+"路径矩阵:");

            printPathAll(path);

        }

    

        System.out.println("\n每对顶点间的最短路径如下:");

        for (int i=0; i<n; i++)

        {

            for (int j=0; j<n; j++)

                if (i!=j)

                    System.out.print(toPath(path,i,j)+"长度"+(dist.get(i,j)==MAX_WEIGHT ? "∞" : dist.get(i,j))+",");

            System.out.println();

        }

    }

    

    private String toPath(Matrix path, int i, int j)           

    {

        SinglyList<T> pathlink = new SinglyList<T>();

        pathlink.insert(0, this.getVertex(j));     

        for (int k=path.get(i,j); k!=i && k!=j && k!=-1;  k=path.get(i,k))

            pathlink.insert(0, this.getVertex(k));

        pathlink.insert(0, this.getVertex(i));     

        return pathlink.toString();

    }

    private void printPathAll(Matrix path)                 //输出path路径矩阵中每对顶点间的路径字符串

    {

        for (int i=0; i<path.getRows(); i++)

        {

            for (int j=0; j<path.getRows(); j++)                

                System.out.print(toPath(path,i,j)+" ");

            System.out.println();

        }

    }

    public boolean equlas(Object obj)

    {

      if(obj==this)

             return true;

         if(!(obj instanceof AbstractGraph))

             return false;

         if(this.vertexCount()!=((AbstractGraph)obj).vertexCount())

          return false;

         for(int i=0;i<this.vertexCount();i++)

          {

           int one=this.weight(i, i+1);

           System.out.println("one的大小是"+one);

           int two=((AbstractGraph) obj).weight(i, i+1);

           if(one!=two)

           return false;

          }

         return true;

    }

    

    public boolean isTree()

    {

     if(this.DFS()==this.vertexCount()-1)

     return true;

     return false;

    }

    int edge=0,vertex=0;

    public int DFS()                         

    {

        boolean[] visited=new boolean[this.vertexCount()];

        int j=0;

        do

        {   if (!visited[j])                             

            {

         if((this.next(j, j+1))!=-1)

         edge++;

                this.dept(j, visited);                

            }

            j = (j+1) % this.vertexCount();               

        } while (j!=0);

        return edge;

    }

    private void dept(int i, boolean[] visited)

    {       

        visited[i] = true;                                

        for (int j=this.next(i,-1); j!=-1; j=this.next(i,j))

            if(!visited[j])                             

                dept(j, visited);                   

    }

五、实验结果及分析(计算过程与结果、数据曲线、图表等)

(1)判断一个无向图是不是一棵树:

(2)判断两个图是否相同:

猜你喜欢

转载自blog.csdn.net/weixin_45823684/article/details/122470210
今日推荐