1. 程式人生 > 其它 >圖的遍歷(深度優先和廣度優先)

圖的遍歷(深度優先和廣度優先)

圖的遍歷

定義

遍歷(Traversing Graph):從圖中某點出發訪問各頂點,每個頂點僅被訪問一次(有且僅有一次)。
深度優先遍歷(Depth First Search):也稱深度優先搜尋,簡稱DFS。從圖中某個頂點v出發做深度優先搜尋,訪問頂點v,然後從v的未被訪問的鄰接頂點出發做深度優先搜尋,直到圖中所有和v有路徑相通的頂點都被訪問到。明顯,這是個遞迴的過程。
廣度優先遍歷(Breadth First Search):也稱廣度優先搜尋,簡稱BFS。從圖中某個頂點v出發做廣度優先搜尋,先快取頂點v,從快取中取出頂點v並訪問,然後快取v的未被訪問的鄰接頂點(可理解為v的下層頂點),從快取中取出頂點,再訪問,直到圖中所有和v有路徑相通的頂點都被訪問到。

複雜度分析

從下面的程式碼可以得出,對於n個頂點e條邊的圖來說,鄰接矩陣表示的圖由於是二維陣列,所以遍歷二維陣列需要O(n2)的時間;對於鄰接表表示的圖,找鄰接點所需的時間取決於頂點和邊的數量,所以遍歷鄰接表表示的圖的時間複雜度是O(n+e)的時間。

程式碼

以下圖中的圖為例,採用不同的遍歷方式遍歷不同儲存結構的圖。

C#程式碼

using System;
using System.Collections.Generic;

namespace GraphDfs
{
    class Program
    {
        static void Main(string[] args)
        {
            // 建立圖(鄰接矩陣表示法)
            int self = GraphAjacencyMatrix.SelfToSelf,
                noedge = GraphAjacencyMatrix.NoEdge;

            AjacentVertex[] vertexes = new AjacentVertex[] {
                new AjacentVertex(){ Data = "A" },  // 0
                new AjacentVertex(){ Data = "B" },  // 1
                new AjacentVertex(){ Data = "C" },  // 2
                new AjacentVertex(){ Data = "D" },  // 3
                new AjacentVertex(){ Data = "E" },  // 4
                new AjacentVertex(){ Data = "F" },  // 5
                new AjacentVertex(){ Data = "G" },  // 6
                new AjacentVertex(){ Data = "H" },  // 7
                new AjacentVertex(){ Data = "I" },  // 8
            };

            int[][] edges = new int[][] {
                new int[]{ self, 1, noedge, noedge, noedge, 1, noedge, noedge, noedge },  // A
                new int[]{ 1, self, 1, noedge, noedge, noedge, 1, noedge, 1 },  // B
                new int[]{ noedge, 1, self, 1, noedge, noedge, noedge, noedge, 1 },  // C
                new int[]{ noedge, noedge, 1, self, 1, noedge, 1, 1, 1 },  // D
                new int[]{ noedge, noedge, noedge, 1, self, 1, noedge, 1, noedge },  // E
                new int[]{ 1, noedge, noedge, noedge, 1, self, 1, noedge, noedge },  // F
                new int[]{ noedge, 1, noedge, 1, noedge, 1, self, 1, noedge },  // G
                new int[]{ noedge, noedge, noedge, 1, 1, noedge, 1, self, noedge },  // H
                new int[]{ noedge, 1, 1, 1, noedge, noedge, noedge, noedge, self },  // I
            };

            GraphAjacencyMatrix graph = new GraphAjacencyMatrix(vertexes, edges);

            // 建立圖(鄰接表表示法)
            Vertex[] vertexesAjacencyList = new Vertex[] {
                new Vertex("A", new Edge[]{ new Edge(1, "<A, B>"), new Edge(5, "<A, F>") }),  // 0
                new Vertex("B", new Edge[]{ new Edge(0, "<B, A>"), new Edge(2, "<B, C>"), new Edge(6, "<B, G>"), new Edge(8, "<B, I>")}),  // 1
                new Vertex("C", new Edge[]{ new Edge(1, "<C, B>"), new Edge(3, "<C, D>"), new Edge(8, "<C, I>")}),  // 2
                new Vertex("D", new Edge[]{ new Edge(2, "<D, C>"), new Edge(4, "<D, E>"), new Edge(6, "<D, G>"), new Edge(7, "<D, H>"), new Edge(8, "<D, I>")}),  // 3
                new Vertex("E", new Edge[]{ new Edge(3, "<E, D>"), new Edge(5, "<E, F>"), new Edge(7, "<E, H>")}),  // 4
                new Vertex("F", new Edge[]{ new Edge(0, "<F, A>"), new Edge(4, "<F, E>"), new Edge(6, "<F, G>")}),  // 5
                new Vertex("G", new Edge[]{ new Edge(1, "<G, B>"), new Edge(3, "<G, D>"), new Edge(5, "<G, F>"), new Edge(7, "<G, H>")}),  // 6
                new Vertex("H", new Edge[]{ new Edge(3, "<H, D>"), new Edge(4, "<H, E>"), new Edge(6, "<H, G>"),}),  // 7
                new Vertex("I", new Edge[]{ new Edge(1, "<I, B>"), new Edge(2, "<I, C>"), new Edge(3, "<I, D>"),}),  // 8
            };

            GraphAjacencyList graphAjacencyList = new GraphAjacencyList(vertexesAjacencyList);

            Console.WriteLine("圖的深度優先搜尋(鄰接矩陣表示法):");
            Dfs1(graph);
            /**
             執行結果:
            圖的深度優先搜尋(鄰接矩陣表示法):
            V0 = A
            V1 = B
            V2 = C
            V3 = D
            V4 = E
            V7 = H
            V6 = G
            V8 = I
            V5 = F
             */

            Console.WriteLine("圖的深度優先搜尋(鄰接表表示法):");
            Dfs2(graphAjacencyList);
            /**
             執行結果:
            圖的深度優先搜尋(鄰接表表示法):
            V0 = A
            V1 = B
            V2 = C
            V3 = D
            V4 = E
            V7 = H
            V6 = G
            V8 = I
            V5 = F
             */

            Console.WriteLine("圖的廣度優先搜尋(鄰接矩陣表示法):");
            Bfs1(graph);
            /**
             執行結果:
            圖的廣度優先搜尋(鄰接矩陣表示法):
            V0 = A
            V1 = B
            V5 = F
            V2 = C
            V6 = G
            V8 = I
            V4 = E
            V3 = D
            V7 = H
             */

            Console.WriteLine("圖的廣度優先搜尋(鄰接表表示法):");
            Bfs2(graphAjacencyList);
            /**
             執行結果:
            圖的廣度優先搜尋(鄰接表表示法):
            V0 = A
            V5 = F
            V1 = B
            V6 = G
            V4 = E
            V8 = I
            V2 = C
            V7 = H
            V3 = D
             */
        }

        /// <summary>
        /// 圖的深度優先搜尋(Depth-First-Search)演算法(非遞迴)。
        /// 圖用鄰接矩陣表示。
        /// </summary>
        /// <param name="g">用鄰接矩陣表示的圖。</param>
        public static void Dfs1(GraphAjacencyMatrix g)
        {
            bool[] isDiscovered = new bool[g.NumberOfVertex];

            for (int i = 0; i < isDiscovered.Length; i++)
            {
                isDiscovered[i] = false;
            }

            Stack<int> s = new Stack<int>();

            for (int i = 0; i < g.NumberOfVertex; i++)
            {
                if (isDiscovered[i] == false)
                {
                    s.Push(i);
                    isDiscovered[i] = true;
                }

                while (s.Count != 0)
                {
                    int v = s.Pop();

                    // visit node operation
                    Console.WriteLine($"V{v} = {g.Vertexes[v].Data}");

                    for (int j = g.NumberOfVertex - 1; j >= 0; j--)
                    //for (int j = 0; j < g.NumberOfVertex; j++)
                    {
                        if (g.Edges[v][j] != GraphAjacencyMatrix.SelfToSelf &&
                            g.Edges[v][j] != GraphAjacencyMatrix.NoEdge &&
                            isDiscovered[j] == false)
                        {
                            s.Push(j);
                            isDiscovered[j] = true;
                        }
                    }
                }
            }
        }
        /// <summary>
        /// 圖的深度優先搜尋(Depth-First-Search)演算法(非遞迴)。
        /// 圖用鄰接表表示。
        /// </summary>
        /// <param name="g">用鄰接矩陣表示的圖。</param>
        public static void Dfs2(GraphAjacencyList g)
        {
            bool[] isDiscovered = new bool[g.NumberOfVertex];

            for (int i = 0; i < isDiscovered.Length; i++)
            {
                isDiscovered[i] = false;
            }

            Stack<int> s = new Stack<int>();

            for (int i = 0; i < g.NumberOfVertex; i++)
            {
                if (isDiscovered[i] == false)
                {
                    s.Push(i);
                    isDiscovered[i] = true;
                }

                while (s.Count != 0)
                {
                    int v = s.Pop();

                    // visit node operation
                    Console.WriteLine($"V{v} = {g.Vertexes[v].Data}");

                    Edge e = g.Vertexes[v].Edge;

                    while (e != null)
                    {
                        int j = e.HeadVertex;

                        if (isDiscovered[j] == false)
                        {
                            s.Push(j);
                            isDiscovered[j] = true;
                        }
                        e = e.Next;
                    }
                }
            }
        }
        /// <summary>
        /// 圖的廣度優先搜尋(Depth-First-Search)演算法。
        /// 圖用鄰接矩陣表示。
        /// </summary>
        /// <param name="g">用鄰接矩陣表示的圖。</param>
        public static void Bfs1(GraphAjacencyMatrix g)
        {
            bool[] isDiscovered = new bool[g.NumberOfVertex];

            for (int i = 0; i < isDiscovered.Length; i++)
            {
                isDiscovered[i] = false;
            }

            Queue<int> q = new Queue<int>();

            for (int i = 0; i < g.NumberOfVertex; i++)
            {
                if (isDiscovered[i] == false)
                {
                    q.Enqueue(i);
                    isDiscovered[i] = true;
                }

                while (q.Count != 0)
                {
                    int v = q.Dequeue();

                    // visit node operation
                    Console.WriteLine($"V{v} = {g.Vertexes[v].Data}");

                    for (int j = 0; j < g.NumberOfVertex; j++)
                    {
                        if (g.Edges[v][j] != GraphAjacencyMatrix.SelfToSelf &&
                            g.Edges[v][j] != GraphAjacencyMatrix.NoEdge &&
                            isDiscovered[j] == false)
                        {
                            q.Enqueue(j);
                            isDiscovered[j] = true;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 圖的廣度優先搜尋(Breadth-First-Search)演算法。
        /// 圖用鄰接表表示。
        /// </summary>
        /// <param name="g">用鄰接矩陣表示的圖。</param>
        public static void Bfs2(GraphAjacencyList g)
        {
            bool[] isDiscovered = new bool[g.NumberOfVertex];

            for (int i = 0; i < isDiscovered.Length; i++)
            {
                isDiscovered[i] = false;
            }

            Queue<int> q = new Queue<int>();

            for (int i = 0; i < g.NumberOfVertex; i++)
            {
                if (isDiscovered[i] == false)
                {
                    q.Enqueue(i);
                    isDiscovered[i] = true;
                }

                while (q.Count != 0)
                {
                    int v = q.Dequeue();
                    // visit node operation
                    Console.WriteLine($"V{v} = {g.Vertexes[v].Data}");

                    Edge e = g.Vertexes[v].Edge;
                    while (e != null)
                    {
                        int j = e.HeadVertex;
                        if (isDiscovered[j] == false)
                        {
                            q.Enqueue(j);
                            isDiscovered[j] = true;
                        }
                        e = e.Next;
                    }
                }
            }
        }
    }

    /// <summary>
    /// 用鄰接矩陣表示的圖的頂點類。
    /// </summary>
    public class AjacentVertex
    {
        /// <summary>
        /// 頂點的資料域。
        /// </summary>
        public string Data { get; set; } = "";
    }

    /// <summary>
    /// 鄰接矩陣表示的圖類。
    /// </summary>
    public class GraphAjacencyMatrix
    {
        /// <summary>
        /// 用系統能夠表示的最大整數表示無窮。
        /// </summary>
        public static int Inifinity = int.MaxValue;
        /// <summary>
        /// 用無窮表示不存在邊(Vi, Vj)或弧<Vi, Vj>
        /// </summary>
        public static int NoEdge = Inifinity;
        /// <summary>
        /// 用於在鄰接矩陣中表示頂點Vi到頂點Vi的情形。
        /// </summary>
        public static int SelfToSelf = 0;
        /// <summary>
        /// 圖中的所有頂點構成的頂點陣列。
        /// </summary>
        public AjacentVertex[] Vertexes { get; private set; }
        /// <summary>
        /// 圖中的所有邊。用一個二維整型陣列表示。
        /// 例如:Edges[1][2] == 2表示Vertexes陣列中
        /// 索引為1的頂點到索引為2的頂點<V1, V2>弧的權值為2。
        /// </summary>
        public int[][] Edges { get; private set; }
        /// <summary>
        /// 圖的頂點數量。
        /// </summary>
        public int NumberOfVertex { get => Vertexes.Length; }
        /// <summary>
        /// 提供圖的所有頂點及邊,用於建立圖類例項。
        /// </summary>
        /// <param name="vertexes">圖中的所有頂點。</param>
        /// <param name="edges">圖中的所有邊。</param>
        public GraphAjacencyMatrix(AjacentVertex[] vertexes, int[][] edges)
        {
            Vertexes = vertexes;
            Edges = edges;
        }
    }

    /// <summary>
    /// 圖G的頂點。用鄰接表來表示頂點的出邊。
    /// </summary>
    public class Vertex
    {
        /// <summary>
        /// 儲存的資料。
        /// </summary>
        public string Data { get; set; } = "";
        /// <summary>
        /// 出邊。
        /// </summary>
        public Edge Edge { get; set; } = null;

        public Vertex(string data, Edge[] adjacentEdges)
        {
            this.Data = data;

            Edge e = null;

            for (int i = 0; i < adjacentEdges.Length; i++)
            {
                e = new Edge(adjacentEdges[i].HeadVertex, adjacentEdges[i].Data);
                e.Next = (Edge == null ? null : Edge);
                Edge = e;
            }
        }
    }

    /// <summary>
    /// 圖G的邊。以鄰接表表示頂點的出邊。
    /// </summary>
    public class Edge
    {
        /// <summary>
        /// 邊的弧頭頂點在頂點陣列中的索引。
        /// </summary>
        public int HeadVertex { get; set; } = -1;
        /// <summary>
        /// 邊的弧尾頂點的下一條出邊。
        /// </summary>
        public Edge Next { get; set; } = null;
        /// <summary>
        /// 邊的描述/資料。
        /// </summary>
        public string Data { get; set; } = string.Empty;

        public Edge(int vertex = -1, string data = "", Edge edge = null)
        {
            this.HeadVertex = vertex;
            this.Next = edge;
            this.Data = data;
        }
    }

    /// <summary>
    /// 鄰接表表示的圖類。
    /// </summary>
    public class GraphAjacencyList
    {
        /// <summary>
        /// 圖中的所有頂點構成的頂點陣列。
        /// </summary>
        public Vertex[] Vertexes { get; private set; }
        /// <summary>
        /// 圖的頂點數量。
        /// </summary>
        public int NumberOfVertex { get => Vertexes.Length; }
        /// <summary>
        /// 提供圖的所有頂點及邊,用於建立圖類例項。
        /// </summary>
        /// <param name="vertexes">圖中的所有頂點。</param>
        public GraphAjacencyList(Vertex[] vertexes)
        {
            Vertexes = vertexes;
        }
    }

}

TypeScript程式碼

/**
 * 用鄰接矩陣表示的圖的頂點類。
 */
class AjacentVertex {
    /**
     * 頂點的資料域。
    */
    data: string = "";
}

/**
 * 鄰接矩陣表示的圖類。
 */
class GraphAjacencyMatrix {
    /**
     * 用系統能夠表示的最大整數表示無窮。
     */
    static inifinity: number = Number.MAX_VALUE;

    /**
     * 用無窮表示不存在邊(Vi, Vj)或弧<Vi, Vj>
     */
    static noEdge: number = GraphAjacencyMatrix.inifinity;

    /**
     * 用於在鄰接矩陣中表示頂點Vi到頂點Vi的情形。
     */
    static selfToSelf: number = 0;

    /**
     * 圖中的所有頂點構成的頂點陣列。
     */
    vertexes: AjacentVertex[];

    /**
     * 圖中的所有邊。用一個二維整型陣列表示。
     * 例如:Edges[1][2] == 2表示Vertexes陣列中
     * 索引為1的頂點到索引為2的頂點<V1, V2>弧的權值為2。
     */
    edges: number[][];

    /**
     * 圖的頂點數量。
     */
    get numberOfVertex(): number {
        return this.vertexes.length;
    }

    /**
     * 提供圖的所有頂點及邊,用於建立圖類例項。
     * @param vertexes 圖中的所有頂點。
     * @param edges 圖中的所有邊。
     */
    constructor(vertexes: AjacentVertex[], edges: number[][]) {
        this.vertexes = vertexes;
        this.edges = edges;
    }
}

/**
 * 圖G的頂點。用鄰接表來表示頂點的出邊。
 */
class Vertex {

    /**
     * 儲存的資料。
     */
    data: string = "";

    /**
     * 出邊。
     */
    edge: Edge = null;

    constructor(data: string, adjacentEdges: Edge[]) {

        this.data = data;

        let e: Edge = null;

        for (let i: number = 0; i < adjacentEdges.length; i++) {
            e = new Edge(adjacentEdges[i].headVertex, adjacentEdges[i].data);
            e.next = (this.edge == null ? null : this.edge);
            this.edge = e;
        }
    }
}

/**
 * 圖G的邊。以鄰接表表示頂點的出邊。
 */
class Edge {

    /**
     * 邊的弧頭頂點在頂點陣列中的索引。
     */
    headVertex: number = -1;

    /**
     * 邊的弧尾頂點的下一條出邊。
     */
    next: Edge = null;

    /**
     * 邊的描述/資料。
     */
    data: string = "";

    constructor(vertex: number = -1, data: string = "", edge: Edge = null) {
        this.headVertex = vertex;
        this.next = edge;
        this.data = data;
    }
}

/**
 * 鄰接表表示的圖類。
 */
class GraphAjacencyList {

    /**
     * 圖中的所有頂點構成的頂點陣列。
     */
    vertexes: Vertex[];

    /**
     * 圖的頂點數量。
     */
    get numberOfVertex(): number {
        return this.vertexes.length;
    }

    /**
     * 提供圖的所有頂點及邊,用於建立圖類例項。
     * @param vertexes 圖中的所有頂點。
     */
    constructor(vertexes: Vertex[]) {
        this.vertexes = vertexes;
    }
}

/**
 * 圖的深度優先搜尋(Depth-First-Search)演算法(非遞迴)。
 * 圖用鄰接矩陣表示。
 * @param g 用鄰接矩陣表示的圖。
 */
function dfs1(g: GraphAjacencyMatrix): void {
    let isDiscovered: boolean[] = [];

    isDiscovered.length = g.numberOfVertex;

    for (let i: number = 0; i < isDiscovered.length; i++) {
        isDiscovered[i] = false;
    }

    let s: number[] = [];

    for (let i: number = 0; i < g.numberOfVertex; i++) {
        if (isDiscovered[i] == false) {
            s.push(i);
            isDiscovered[i] = true;
        }

        while (s.length != 0) {
            let v: number = s.pop();

            // visit node operation
            console.log(`V${v} = ${g.vertexes[v].data}`);

            for (let j: number = g.numberOfVertex - 1; j >= 0; j--)
            //for (int j = 0; j < g.NumberOfVertex; j++)
            {
                if (g.edges[v][j] != GraphAjacencyMatrix.selfToSelf &&
                    g.edges[v][j] != GraphAjacencyMatrix.noEdge &&
                    isDiscovered[j] == false) {
                    s.push(j);
                    isDiscovered[j] = true;
                }
            }
        }
    }
}

/**
 * 圖的深度優先搜尋(Depth-First-Search)演算法(非遞迴)。
 * 圖用鄰接表表示。
 * @param g 用鄰接矩陣表示的圖。
 */
function dfs2(g: GraphAjacencyList): void {
    let isDiscovered: boolean[] = [];

    isDiscovered.length = g.numberOfVertex;

    for (let i: number = 0; i < isDiscovered.length; i++) {
        isDiscovered[i] = false;
    }

    let s: number[] = [];

    for (let i: number = 0; i < g.numberOfVertex; i++) {
        if (isDiscovered[i] == false) {
            s.push(i);
            isDiscovered[i] = true;
        }

        while (s.length != 0) {
            let v: number = s.pop();

            // visit node operation
            console.log(`V${v} = ${g.vertexes[v].data}`);

            let e: Edge = g.vertexes[v].edge;

            while (e != null) {
                let j: number = e.headVertex;

                if (isDiscovered[j] == false) {
                    s.push(j);
                    isDiscovered[j] = true;
                }
                e = e.next;
            }
        }
    }
}

/**
 * 圖的廣度優先搜尋(Depth-First-Search)演算法。
 * 圖用鄰接矩陣表示。
 * @param g 用鄰接矩陣表示的圖。
 */
function bfs1(g: GraphAjacencyMatrix): void {
    let isDiscovered: boolean[] = [];

    isDiscovered.length = g.numberOfVertex;

    for (let i: number = 0; i < isDiscovered.length; i++) {
        isDiscovered[i] = false;
    }

    let q: number[] = [];

    for (let i: number = 0; i < g.numberOfVertex; i++) {
        if (isDiscovered[i] == false) {
            q.push(i);
            isDiscovered[i] = true;
        }

        while (q.length != 0) {
            let v: number = q.shift();

            // visit node operation
            console.log(`V${v} = ${g.vertexes[v].data}`);

            for (let j: number = 0; j < g.numberOfVertex; j++) {
                if (g.edges[v][j] != GraphAjacencyMatrix.selfToSelf &&
                    g.edges[v][j] != GraphAjacencyMatrix.noEdge &&
                    isDiscovered[j] == false) {
                    q.push(j);
                    isDiscovered[j] = true;
                }
            }
        }
    }
}

/**
 * 圖的廣度優先搜尋(Breadth-First-Search)演算法。
 * 圖用鄰接表表示。
 * @param g 用鄰接矩陣表示的圖。
 */
function bfs2(g: GraphAjacencyList): void {
    let isDiscovered: boolean[] = [];

    isDiscovered.length = g.numberOfVertex;

    for (let i: number = 0; i < isDiscovered.length; i++) {
        isDiscovered[i] = false;
    }

    let q: number[] = [];

    for (let i: number = 0; i < g.numberOfVertex; i++) {
        if (isDiscovered[i] == false) {
            q.push(i);
            isDiscovered[i] = true;
        }

        while (q.length != 0) {
            let v: number = q.shift();

            // visit node operation
            console.log(`V${v} = ${g.vertexes[v].data}`);

            let e: Edge = g.vertexes[v].edge;
            while (e != null) {
                let j: number = e.headVertex;
                if (isDiscovered[j] == false) {
                    q.push(j);
                    isDiscovered[j] = true;
                }
                e = e.next;
            }
        }
    }
}

function main(): void {
    // 建立圖(鄰接矩陣表示法)
    let self: number = GraphAjacencyMatrix.selfToSelf,
        noedge = GraphAjacencyMatrix.noEdge;

    let vertexes: AjacentVertex[] = [
        { data: "A" },  // 0
        { data: "B" },  // 1
        { data: "C" },  // 2
        { data: "D" },  // 3
        { data: "E" },  // 4
        { data: "F" },  // 5
        { data: "G" },  // 6
        { data: "H" },  // 7
        { data: "I" },  // 8
    ];

    let edges: number[][] = [
        [self, 1, noedge, noedge, noedge, 1, noedge, noedge, noedge],  // A
        [1, self, 1, noedge, noedge, noedge, 1, noedge, 1],  // B
        [noedge, 1, self, 1, noedge, noedge, noedge, noedge, 1],  // C
        [noedge, noedge, 1, self, 1, noedge, 1, 1, 1],  // D
        [noedge, noedge, noedge, 1, self, 1, noedge, 1, noedge],  // E
        [1, noedge, noedge, noedge, 1, self, 1, noedge, noedge],  // F
        [noedge, 1, noedge, 1, noedge, 1, self, 1, noedge],  // G
        [noedge, noedge, noedge, 1, 1, noedge, 1, self, noedge],  // H
        [noedge, 1, 1, 1, noedge, noedge, noedge, noedge, self],  // I
    ];

    let graph: GraphAjacencyMatrix = new GraphAjacencyMatrix(vertexes, edges);

    // 建立圖(鄰接表表示法)
    let vertexesAjacencyList: Vertex[] = [
        new Vertex("A", [new Edge(1, "<A, B>"), new Edge(5, "<A, F>")]),  // 0
        new Vertex("B", [new Edge(0, "<B, A>"), new Edge(2, "<B, C>"), new Edge(6, "<B, G>"), new Edge(8, "<B, I>")]),  // 1
        new Vertex("C", [new Edge(1, "<C, B>"), new Edge(3, "<C, D>"), new Edge(8, "<C, I>")]),  // 2
        new Vertex("D", [new Edge(2, "<D, C>"), new Edge(4, "<D, E>"), new Edge(6, "<D, G>"), new Edge(7, "<D, H>"), new Edge(8, "<D, I>")]),  // 3
        new Vertex("E", [new Edge(3, "<E, D>"), new Edge(5, "<E, F>"), new Edge(7, "<E, H>")]),  // 4
        new Vertex("F", [new Edge(0, "<F, A>"), new Edge(4, "<F, E>"), new Edge(6, "<F, G>")]),  // 5
        new Vertex("G", [new Edge(1, "<G, B>"), new Edge(3, "<G, D>"), new Edge(5, "<G, F>"), new Edge(7, "<G, H>")]),  // 6
        new Vertex("H", [new Edge(3, "<H, D>"), new Edge(4, "<H, E>"), new Edge(6, "<H, G>"),]),  // 7
        new Vertex("I", [new Edge(1, "<I, B>"), new Edge(2, "<I, C>"), new Edge(3, "<I, D>"),]),  // 8
    ];

    let graphAjacencyList: GraphAjacencyList = new GraphAjacencyList(vertexesAjacencyList);

    console.log("圖的深度優先搜尋(鄰接矩陣表示法):");
    dfs1(graph);

    console.log("圖的深度優先搜尋(鄰接表表示法):");
    dfs2(graphAjacencyList);

    console.log("圖的廣度優先搜尋(鄰接矩陣表示法):");
    bfs1(graph);

    console.log("圖的廣度優先搜尋(鄰接表表示法):");
    bfs2(graphAjacencyList);
}

main();

注意:對於tsc編譯器可使用下面的命令來編譯上面的TypeScript程式碼,否則會報錯誤:TS1056: Accessors are only available when targeting ECMAScript 5 and higher.更早版本的ES不支援訪問器(getter/setter)。

tsc graphDfsBfs.ts -t es6

在終端中使用node來執行被tsc編譯成js後的程式碼。

node graphDfsBfs.js

參考資料:

《大話資料結構》(溢彩加強版) - 程傑 著 - 清華大學出版社 - P203