第6章 图

3. 克鲁斯卡尔(Kruskal) 算法

 克鲁斯卡尔算法的基本思想是:对一个有n个顶点的无向连通图,将图中的边按权值大小依次选取,若选取的边使生成树不形成回路,则把它加入到树中;若形成回路,则将它舍弃。如此进行下去,直到树中包含有n-1条边为止。(当整个图为连通图时为n-1条边)

 

根据邻接矩阵存储结构实现Kruskal算法:(邻接链表的实现在前面的博客)

        public void Kruskal()

        {

            bool[,] markers = new bool[NodeNum, NodeNum];

            Dictionary<AdjListNode<T>, VexListNode<T>> dic = new Dictionary<AdjListNode<T>, VexListNode<T>>();



            while (true)

            {

                AdjListNode<T> adjNode = null;

                VexListNode<T> vexNode = null;



                AdjListNode<T> currentAdjNode = null;

                VexListNode<T> currentVexNode = null;

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

                {

                    currentVexNode = vexList[j];

                    currentAdjNode = currentVexNode.FirstAdj;



                    while (currentAdjNode != null)

                    {

                        if (markers[j, currentAdjNode.AdjVexIndex] == false)

                        {

                            if (adjNode == null || currentAdjNode.Weight < adjNode.Weight)

                            {

                                vexNode = currentVexNode;

                                adjNode = currentAdjNode;

                            }

                        }



                        currentAdjNode = currentAdjNode.Next;

                    }

                }



                if (adjNode == null)

                    break;



                dic.Add(adjNode, vexNode);



                markers[IsNode(vexNode.Node), adjNode.AdjVexIndex] = true;

                markers[adjNode.AdjVexIndex, IsNode(vexNode.Node)] = true;





                bool ifCycle = true;



                while (ifCycle)

                {

                    ifCycle = false;



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

                    {

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

                        {

                            if (markers[j, k] == true)

                            {

                                for (int m = 0; m < NodeNum; m++)

                                {

                                    if (m == k)

                                        continue;

                                    if (markers[k, m] == true && markers[j, m] == false)

                                    {

                                        markers[j, m] = true;

                                        markers[m, j] = true;

                                        ifCycle = true;

                                    }

                                }

                            }

                        }

                    }

                }

            }



            foreach (var i in dic.Keys)

            {

                Console.WriteLine(dic[i].Node.Value.ToString() + " -> " + i.Weight + " -> " + vexList[i.AdjVexIndex].Node.Value.ToString());

            }

        }

 

调用代码:

            GraphAdjList<int> adjList = new GraphAdjList<int>(100);



            //Inial graph object

            GraphNode<int> node1 = new GraphNode<int>(1);

            GraphNode<int> node2 = new GraphNode<int>(2);

            GraphNode<int> node3 = new GraphNode<int>(3);

            GraphNode<int> node4 = new GraphNode<int>(4);

            GraphNode<int> node5 = new GraphNode<int>(5);

            GraphNode<int> node6 = new GraphNode<int>(6);

            GraphNode<int> node7 = new GraphNode<int>(7);

            GraphNode<int> node8 = new GraphNode<int>(8);



            adjList.SetNode(node1);

            adjList.SetNode(node2);

            adjList.SetNode(node3);

            adjList.SetNode(node4);

            adjList.SetNode(node5);

            adjList.SetNode(node6);

            adjList.SetNode(node7);

            adjList.SetNode(node8);



            adjList.SetEdge(0, node2, node1, 2);

            adjList.SetEdge(1,node1, node3, 4);

            adjList.SetEdge(2,node1, node4, 4);

            adjList.SetEdge(3, node1, node5, 3);

            adjList.SetEdge(4, node2, node3, 3);

            adjList.SetEdge(5, node2, node4, 1);

            adjList.SetEdge(6, node2, node5, 2);

            adjList.SetEdge(7, node3, node4, 4);

            adjList.SetEdge(8, node3, node5, 4);

            adjList.SetEdge(9, node5, node4, 2);

            adjList.SetEdge(10, node6, node7, 3);

            adjList.SetEdge(11, node8, node6, 2);

            adjList.SetEdge(12, node7, node8, 3);



            adjList.Kruskal();

            System.Console.ReadKey();


输出为:

2 -> 1 -> 4
2 -> 2 -> 5
2 -> 2 -> 1
8 -> 2 -> 6
2 -> 3 -> 3
6 -> 3 -> 7

 

你可能感兴趣的:(图)