數據結構(C#)--圖結構的實現輸出以及圖結構的深度和廣度優先搜索和Dijkstra 算法的最小路徑以及最小生成樹的實現

// 實驗小結 吳新強於2013年3月19日18:45:59 桂電 2507實驗室
// 主要學習圖結構的實現輸出以及圖結構的深度和廣度優先搜索和Dijkstra 算法的最小路徑以及最小生成樹的實現
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace Chapter16
{
    class Program
    {
        static void Main(string[] args)
        {
            // 簡單的圖輸出
            Console.WriteLine("簡單的圖輸出:");
            Graph the1Graph = new Graph(4);
            the1Graph.AddVertex("A");
            the1Graph.AddVertex("B");
            the1Graph.AddVertex("C");
            the1Graph.AddVertex("D");
            the1Graph.AddEdge(0, 1);
            the1Graph.AddEdge(1, 2);
            the1Graph.AddEdge(2, 3);
            the1Graph.TopSort();
            Console.WriteLine();
            Console.WriteLine("完成.");
            Console.WriteLine();


            Graph theGraph = new Graph(6);
            theGraph.AddVertex("CS1");
            theGraph.AddVertex("CS2");
            theGraph.AddVertex("DS");
            theGraph.AddVertex("OS");
            theGraph.AddVertex("ALG");
            theGraph.AddVertex("AL");
            theGraph.AddEdge(0, 1);
            theGraph.AddEdge(1, 2);
            theGraph.AddEdge(1, 5);
            theGraph.AddEdge(2, 3);
            theGraph.AddEdge(2, 4);
            theGraph.TopSort();
            Console.WriteLine();
            Console.WriteLine("完成.");
            // theGraph.ShowVertex(4);
            Console.WriteLine("輸出沒有後繼結點頂點:" + theGraph.NoSuccessors());
            theGraph.DelVertex(1);
            // theGraph.TopSort();
            Console.WriteLine();

            //圖的深度優先搜索
            Console.WriteLine("圖的深度優先搜索:");
            Graph aGraph = new Graph(13);
            aGraph.AddVertex("A");
            aGraph.AddVertex("B");
            aGraph.AddVertex("C");
            aGraph.AddVertex("D");
            aGraph.AddVertex("E");
            aGraph.AddVertex("F");
            aGraph.AddVertex("G");
            aGraph.AddVertex("H");
            aGraph.AddVertex("I");
            aGraph.AddVertex("J");
            aGraph.AddVertex("K");
            aGraph.AddVertex("L");
            aGraph.AddVertex("M");
            aGraph.AddEdge(0, 1);
            aGraph.AddEdge(1, 2);
            aGraph.AddEdge(2, 3);
            aGraph.AddEdge(0, 4);
            aGraph.AddEdge(4, 5);
            aGraph.AddEdge(5, 6);
            aGraph.AddEdge(0, 7);
            aGraph.AddEdge(7, 8);
            aGraph.AddEdge(8, 9);
            aGraph.AddEdge(0, 10);
            aGraph.AddEdge(10, 11);
            aGraph.AddEdge(11, 12);
            Console.WriteLine();
            aGraph.DepthFirstSearch();
            Console.WriteLine();

            //圖的深度優先搜索
            Console.WriteLine("圖的廣度優先搜索:");
            Graph bGraph = new Graph(13);
            bGraph.AddVertex("A");
            bGraph.AddVertex("B");
            bGraph.AddVertex("C");
            bGraph.AddVertex("D");
            bGraph.AddVertex("E");
            bGraph.AddVertex("F");
            bGraph.AddVertex("G");
            bGraph.AddVertex("H");
            bGraph.AddVertex("I");
            bGraph.AddVertex("J");
            bGraph.AddVertex("K");
            bGraph.AddVertex("L");
            bGraph.AddVertex("M");
            bGraph.AddEdge(0, 1);
            bGraph.AddEdge(1, 2);
            bGraph.AddEdge(2, 3);
            bGraph.AddEdge(0, 4);
            bGraph.AddEdge(4, 5);
            bGraph.AddEdge(5, 6);
            bGraph.AddEdge(0, 7);
            bGraph.AddEdge(7, 8);
            bGraph.AddEdge(8, 9);
            bGraph.AddEdge(0, 10);
            bGraph.AddEdge(10, 11);
            bGraph.AddEdge(11, 12);
            Console.WriteLine();
            bGraph.BreadthFirstSearch();
            Console.WriteLine();
            // 最小生成樹
            Console.WriteLine("最新生成樹:");
            Console.WriteLine();
            Graph cGraph = new Graph(7);
            cGraph.AddVertex("A");
            cGraph.AddVertex("B");
            cGraph.AddVertex("C");
            cGraph.AddVertex("D");
            cGraph.AddVertex("E");
            cGraph.AddVertex("F");
            cGraph.AddVertex("G");
            cGraph.AddEdge(0, 1);
            cGraph.AddEdge(0, 2);
            cGraph.AddEdge(0, 3);
            cGraph.AddEdge(1, 2);
            cGraph.AddEdge(1, 3);
            cGraph.AddEdge(1, 4);
            cGraph.AddEdge(2, 3);
            cGraph.AddEdge(2, 5);
            cGraph.AddEdge(3, 5);
            cGraph.AddEdge(3, 4);
            cGraph.AddEdge(3, 6);
            cGraph.AddEdge(4, 5);
            cGraph.AddEdge(4, 6);
            cGraph.AddEdge(5, 6);
            //   Console.WriteLine();
            cGraph.Mst();
            Console.WriteLine();

            /*
                        // Dijkstra 查找最短路徑
                        Graph dGraph = new Graph();
                        dGraph.AddVertex("A");
                        dGraph.AddVertex("B");
                        dGraph.AddVertex("C");
                        dGraph.AddVertex("D");
                        dGraph.AddVertex("E");
                        dGraph.AddVertex("F");
                        dGraph.AddVertex("G");
                        dGraph.AddEdge(0, 1, 2);
                        dGraph.AddEdge(0, 3, 1);
                        dGraph.AddEdge(1, 3, 3);
                        dGraph.AddEdge(1, 4, 10);
                        dGraph.AddEdge(2, 5, 5);
                        dGraph.AddEdge(2, 0, 4);
                        dGraph.AddEdge(3, 2, 2);
                        dGraph.AddEdge(3, 5, 8);
                        dGraph.AddEdge(3, 4, 2);
                        dGraph.AddEdge(3, 6, 4);
                        dGraph.AddEdge(4, 6, 6);
                        dGraph.AddEdge(6, 5, 1);
                        Console.WriteLine();
                        Console.WriteLine("最短路徑:");//Shortest paths
                        Console.WriteLine();
                       // dGraph.Path();
                        Console.WriteLine();
             */
        }
    }

    public class Vertex
    {
        public bool wasVisited;
        public bool isinTree;
        public string label;
        public Vertex(string label)
        {
            this.label = label;
            //     label = label;
            wasVisited = false;
            // isinTree = false;
        }
    }
    public class Graph
    {
        private int NUM_VERTICES = 6;
        private Vertex[] vertices;
        private int[,] adjMatrix;
        int numVerts;
        /*      private const int max_verts = 20;
          //    int infinity = 1000000;
          //    Vertex[] vertexList;
          //    int[,] adjMat;
           //   int nVerts;
         //     int nTree;
         //     DistOriginal[] sPath;
         //     int currentVert;
         //     int startToCurrent;
         */
        /*     public Graph()
             {
                 vertexList = new Vertex[max_verts];
                 adjMat = new int[max_verts, max_verts];
                 nVerts = 0;
                 nTree = 0;
                 for (int j = 0; j <= max_verts - 1; j++)
                     for (int k = 0; k <= max_verts - 1; k++)
                         adjMat[j, k] = infinity;
          //       sPath = new DistOriginal[max_verts];
             }
         */
        public Graph(int numvertices)
        {
            NUM_VERTICES = numvertices;
            vertices = new Vertex[NUM_VERTICES];
            adjMatrix = new int[NUM_VERTICES, NUM_VERTICES];
            numVerts = 0;
            for (int j = 0; j <= NUM_VERTICES - 1; j++)
                for (int k = 0; k <= NUM_VERTICES - 1; k++)
                    adjMatrix[j, k] = 0;
        }
        public void AddVertex(string label)
        {
            vertices[numVerts] = new Vertex(label);
            numVerts++;
            // vertexList[nVerts] = new Vertex(label);
            //  nVerts++;
        }
        public void AddEdge(int start, int eend)
        {
            adjMatrix[start, eend] = 1;
        }
        //    public void AddEdge(int start, int theEnd, int weight)
        //   {
        //        adjMat[start, theEnd] = weight;
        //    }
        public void ShowVertex(int v)
        {
            Console.Write(vertices[v].label + " ");
        }


        public int NoSuccessors()
        {
            bool isEdge;
            for (int row = 0; row <= NUM_VERTICES - 1; row++)
            {
                isEdge = false;
                for (int col = 0; col <= NUM_VERTICES - 1; col++)
                {
                    if (adjMatrix[row, col] > 0)
                    {
                        isEdge = true;
                        break;
                    }
                }
                if (!isEdge)
                    return row;
            }
            return -1;
        }

        public void DelVertex(int vert)
        {
            if (vert != NUM_VERTICES - 1)
            {
                for (int j = vert; j < NUM_VERTICES - 1; j++)
                    vertices[j] = vertices[j + 1];
                for (int row = vert; row < NUM_VERTICES - 1; row++)
                    MoveRow(row, NUM_VERTICES);
                for (int col = vert; col < NUM_VERTICES - 1; col++)
                    MoveCol(col, NUM_VERTICES);
            }
            NUM_VERTICES--;
        }
        private void MoveRow(int row, int length)
        {
            for (int col = 0; col <= length - 1; col++)
                adjMatrix[row, col] = adjMatrix[row + 1, col];
        }
        private void MoveCol(int col, int length)
        {
            for (int row = 0; row <= length - 1; row++)
                adjMatrix[row, col] = adjMatrix[row, col + 1];
        }

        public void TopSort()
        {
            Stack<string> gStack = new Stack<string>();
            while (NUM_VERTICES > 0)
            {
                int currVertex = NoSuccessors();
                if (currVertex == -1)
                {
                    Console.WriteLine("錯誤:圖中存在環路!");//Error: graph has cycles.
                    return;
                }
                gStack.Push(vertices[currVertex].label);
                DelVertex(currVertex);
            }
            Console.Write("圖的順序: ");//Topological sorting order
            while (gStack.Count > 0)
                Console.Write(gStack.Pop() + " ");
        }

        private int GetAdjUnvisitedVertex(int v)
        {
            for (int j = 0; j <= NUM_VERTICES - 1; j++)
                if ((adjMatrix[v, j] == 1) && (vertices[j].wasVisited == false))
                    return j;
            return -1;
        }
        //圖的深度優先搜索
        public void DepthFirstSearch()
        {
            Stack<int> gStack = new Stack<int>();
            vertices[0].wasVisited = true;
            ShowVertex(0);
            gStack.Push(0);
            int v;
            while (gStack.Count > 0)
            {
                v = GetAdjUnvisitedVertex(gStack.Peek());
                if (v == -1)
                    gStack.Pop();
                else
                {
                    vertices[v].wasVisited = true;
                    ShowVertex(v);
                    gStack.Push(v);
                }
            }
            for (int j = 0; j <= NUM_VERTICES - 1; j++)
                vertices[j].wasVisited = false;
        }
        //圖的廣度優先搜索
        public void BreadthFirstSearch()
        {
            Queue<int> gQueue = new Queue<int>();
            vertices[0].wasVisited = true;
            ShowVertex(0);
            gQueue.Enqueue(0);
            int vert1, vert2;
            while (gQueue.Count > 0)
            {
                vert1 = gQueue.Dequeue();
                vert2 = GetAdjUnvisitedVertex(vert1);
                while (vert2 != -1)
                {
                    vertices[vert2].wasVisited = true;
                    ShowVertex(vert2);
                    gQueue.Enqueue(vert2);
                    vert2 = GetAdjUnvisitedVertex(vert1);
                }
            }
            for (int i = 0; i <= NUM_VERTICES - 1; i++)
                vertices[i].wasVisited = false;
        }
        //  最小生成樹
        public void Mst()
        {
            Stack<int> gStack = new Stack<int>();
            vertices[0].wasVisited = true;
            gStack.Push(0);
            int currVertex, ver;
            while (gStack.Count > 0)
            {
                currVertex = gStack.Peek();
                ver = GetAdjUnvisitedVertex(currVertex);
                if (ver == -1)
                    gStack.Pop();
                else
                {
                    vertices[ver].wasVisited = true;
                    gStack.Push(ver);
                    ShowVertex(currVertex);
                    ShowVertex(ver);
                    Console.Write(" ");
                }
            }
            for (int j = 0; j <= NUM_VERTICES - 1; j++)
                vertices[j].wasVisited = false;
        }
        // Dijkstra 查找最短路徑
        /*   public void Path()
           {
               int startTree = 0;
              // vertexList[startTree].isInTree = true;
               nTree = 1;
               for (int j = 0; j <= nVerts; j++)
               {
                   int tempDist = adjMat[startTree, j];
                   sPath[j] = new DistOriginal(startTree, tempDist);
               }
               while (nTree < nVerts)
               {
                   int indexMin = GetMin();
                   int minDist = sPath[indexMin].distance;
                   currentVert = indexMin;
                   startToCurrent = sPath[indexMin].distance;
           //        vertexList[currentVert].isInTree = true;
                   nTree++;
                   AdjustShortPath();
               }
               DisplayPaths();
               nTree = 0;
              // for (int j = 0; j <= nVerts - 1; j++)
           //        vertexList[j].isInTree = false;
           }
           public int GetMin()
           {
               int minDist = infinity;
               int indexMin = 0;
               for (int j = 1; j <= nVerts - 1; j++)
              //     if (!(vertexList[j].isInTree) && sPath[j].distance < minDist)
                   {
                       minDist = sPath[j].distance;
                       indexMin = j;
                   }
               return indexMin;
           }
           public void AdjustShortPath()
           {
               int column = 1;
               while (column < nVerts)
              //     if (vertexList[column].isInTree)
              //         column++;
             //      else
                   {
                       int currentToFring = adjMat[currentVert, column];
                       int startToFringe = startToCurrent + currentToFring;
                       int sPathDist = sPath[column].distance;
                       if (startToFringe < sPathDist)
                       {
                           sPath[column].parentVert = currentVert;
                           sPath[column].distance = startToFringe;
                       }
                       column++;
                   }
           }
           public void DisplayPaths()
           {
               for (int j = 0; j <= nVerts - 1; j++)
               {
                   Console.Write(vertexList[j].label + "=");
                   if (sPath[j].distance == infinity)
                       Console.Write("inf");
                   else
                       Console.Write(sPath[j].distance);
                   string parent = vertexList[sPath[j].parentVert].
                   label;
                   Console.Write("(" + parent + ") ");
               }
           }
       }
       public class DistOriginal
       {
           public int distance;
           public int parentVert;
           public DistOriginal(int pv, int d)
           {
               distance = d;
               parentVert = pv;
           }
       }

   */

    }
}結果截圖:

發佈了50 篇原創文章 · 獲贊 4 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章