• Adjacency matrix based Graph


    Interface

    AddVertex(T data)

    AddEdge(int from, int to)

    DFS

    BFS

    MST

    TopSort

    PrintGraph


    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace TestCase1.TestCase.GraphMatrix
    {
        public class Vertex<T>
        {
            public T Data
            {
                get;
                set;
            }
    
            public bool Visited
            {
                get;
                set;
            }
    
            public Vertex(T data)
            {
                this.Data = data;
                this.Visited = false;
            }
        }
    
        public class GraphMatrix<T>
        {
            private int GraphSize = 0;
    
            private List<Vertex<T>> Vertices
            {
                get;
                set;
            }
    
            private int[,] adjMatrix
            {
                get;
                set;
            }
    
            private int Capacity
            {
                get;
                set;
            }
    
            public GraphMatrix(int capacity)
            {
                this.Vertices = new List<Vertex<T>>();
                this.Capacity = capacity;
                this.adjMatrix = new int[capacity, capacity];
                for (int i = 0; i < capacity; i++)
                {
                    for (int j = 0; j < capacity; j++)
                    {
                        this.adjMatrix[i, j] = 0;
                    }
                }
            }
    
            public void AddVertex(T data)
            {
                // ? need check
                var result = this.Vertices.Where(t => t.Data.Equals(data));
    
                if (result == null || !result.Any())
                {
                    this.Vertices.Add(new Vertex<T>(data));
                    this.GraphSize++;
                }
            }
    
            public void AddEdge(int from, int to)
            {
                if (from >= this.GraphSize || to >= this.GraphSize)
                {
                    throw new ArgumentException("index is out of graph size!");
                }
    
                this.adjMatrix[from, to] = 1;
                this.adjMatrix[to, from] = 1;
            }
    
            public void AddDirectedEdge(int from, int to)
            {
                if (from >= this.GraphSize || to >= this.GraphSize)
                {
                    throw new ArgumentException("index is out of graph size!");
                }
    
                this.adjMatrix[from, to] = 1;
            }
    
            public void ShowVertex(Vertex<T> ver)
            {
                Console.WriteLine("Show vertext = {0}", ver.Data);
            }
    
            public void InitVisit()
            {
                foreach (var v in this.Vertices)
                {
                    v.Visited = false;
                }
            }
    
            public void PrintGraph()
            {
                for (int i = 0; i < this.GraphSize; i++)
                {
                    Console.WriteLine();
                    Console.Write("Vertex is {0}: ", this.Vertices[i].Data);
                    for (int j = 0; j < this.GraphSize; j++)
                    {
                        if (this.adjMatrix[i, j] == 1)
                        {
                            Console.Write(this.Vertices[j].Data);
                            Console.Write(" ");
                        }
                    }
                }
            }
    
            public int FindVertexWithoutSuccssor()
            {
                for (int i = 0; i < this.GraphSize; i++)
                {
                    bool hasSuccessor = false;
                    for (int j = 0; j < this.GraphSize; j++)
                    {
                        if (this.adjMatrix[i, j] == 1)
                        {
                            hasSuccessor = true;
                            break;
                        }
                    }
    
                    if (!hasSuccessor)
                    {
                        return i;
                    }
                }
    
                return -1;
            }
    
            public void MoveColumn(int column)
            {
                for (int row = 0; row < this.GraphSize; row++)
                {
                    for (int j = column + 1; j < this.GraphSize; j++)
                    {
                        this.adjMatrix[row, j - 1] = this.adjMatrix[row, j];
                    }
                }
            }
    
            public void MoveRow(int row)
            {
                for (int column = 0; column < this.GraphSize; column++)
                {
                    for (int j = row + 1; j < this.GraphSize; j++)
                    {
                        this.adjMatrix[j - 1, column] = this.adjMatrix[j, column];
                    }
                }
            }
    
            public void RemoveVertex(int index)
            {
                this.Vertices.RemoveAt(index);
                this.GraphSize--; // important here.
            }
    
            public void TopSort()
            {
                Stack<Vertex<T>> stack = new Stack<Vertex<T>>();
    
                while (this.GraphSize > 0)
                {
                    int vertex = FindVertexWithoutSuccssor();
                    if (vertex == -1)
                    {
                        throw new Exception("The graph has cycle!");
                    }
    
                    stack.Push(this.Vertices[vertex]);
    
                    this.MoveRow(vertex);
                    this.MoveColumn(vertex);
                    this.RemoveVertex(vertex);
                }
    
                while (stack.Count != 0)
                {
                    var ret = stack.Pop();
                    Console.WriteLine(ret.Data);
                }
            }
    
            public void DFS()
            {
                Stack<int> stack = new Stack<int>();
    
                // validation
                if (this.GraphSize == 0)
                {
                    Console.WriteLine("graph is empty, no op!");
                    return;
                }
    
                stack.Push(0);
                this.Vertices[0].Visited = true;
                ShowVertex(this.Vertices[0]);
    
                while (stack.Count != 0)
                {
                    int index = stack.Peek();
                    
                    // find next un-visited edge
                    int v = this.GetNextUnVisitedAdjancentNode(index);
                    if (v == -1)
                    {
                        stack.Pop();
                    }
                    else
                    {
                        this.ShowVertex(this.Vertices[v]);
                        this.Vertices[v].Visited = true;
                        stack.Push(v);
                    }
                }
    
                // reset ALL VISIT flags
                this.InitVisit();
            }
    
            public void BFS()
            {
                Queue<int> queue = new Queue<int>();
    
                // validation
                if (this.GraphSize == 0)
                {
                    return;
                }
    
                // logic
                queue.Enqueue(0);
                ShowVertex(this.Vertices[0]);
                this.Vertices[0].Visited = true;
    
                while (queue.Count > 0)
                {
                    int result = queue.Dequeue();
    
                    // find adjacent nodes and enqueue them
                    for (int j = 0; j < this.GraphSize; j++)
                    {
                        if (adjMatrix[result, j] == 1 && this.Vertices[j].Visited == false)
                        {
                            // print all adjacent nodes
                            ShowVertex(this.Vertices[j]);
                            this.Vertices[j].Visited = true;
    
                            queue.Enqueue(j);
                        }
                    }
                }
    
                // reset
                this.InitVisit();
            }
    
            public void MST()
            {
                // validation
                if (this.GraphSize == 0)
                {
                    return;
                }
    
                // init
                Stack<int> stack = new Stack<int>();
                stack.Push(0);
                int currentVertex = 0;
                int vertex = 0;
    
                this.Vertices[0].Visited = true;
    
                while (stack.Count > 0)
                {
                    currentVertex = stack.Peek();
    
                    vertex = this.GetNextUnVisitedAdjancentNode(currentVertex);
                    if (vertex == -1)
                    {
                        stack.Pop();
                    }
                    else
                    {
                        this.Vertices[vertex].Visited = true;
    
                        // print
                        Console.Write(this.Vertices[currentVertex].Data.ToString() + this.Vertices[vertex].Data.ToString());
                        Console.Write("-> ");
                        stack.Push(vertex);
                    }
                }
    
                // clean up
                this.InitVisit();
            }
    
            private int GetNextUnVisitedAdjancentNode(int v)
            {
                // validation
                if (v >= this.GraphSize)
                {
                    throw new Exception("v is out of graph size!");
                }
    
                for (int i = 0; i < this.GraphSize; i++)
                {
                    if (adjMatrix[v, i] == 1 && !this.Vertices[i].Visited)
                    {
                        return i;
                    }
                }
    
                return -1;
            }
    
            public void DepthFirstSearch()
            {
                DFSUtil(0);
                this.InitVisit();
            }
    
            private void DFSUtil(int vertex)
            {
                // validation
                if (vertex >= this.GraphSize)
                {
                    throw new ArgumentException("out of graph size!");
                }
    
                int ver = this.GetNextUnVisitedAdjancentNode(vertex);
                if (ver == -1)
                {
                    return;
                }
                else
                {
                    // print current node
                    ShowVertex(this.Vertices[ver]);
                    this.Vertices[ver].Visited = true;
    
                    DFSUtil(ver);
                }
            }
        }
    }
  • 相关阅读:
    Java入门
    Java入门
    Java入门
    Java入门
    Java入门
    Java入门
    Java入门
    Java入门
    leyou_04_vue.js的ajax请求方式
    leyou_03_cors解决ajax的跨域请求问题
  • 原文地址:https://www.cnblogs.com/xuyanran/p/8543209.html
Copyright © 2020-2023  润新知