数据结构总复习(3)

图的深度优先和广度优先算法。。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 数据结构
{
    public class Program
    {
        public class MatrixGraph
        {
            public string[] DingDian;//保存顶点信息
            public int[,] edges;//保存边信息
            public bool[] isTrav;
            public int vertexNum;//顶点数量
            public int edgeNum;//边数量
            public int graghType;//图类型
            //构造函数,初始化变量
            public MatrixGraph(int vertexNum, int edgeNum, int graphType1)
            {
                this.vertexNum = vertexNum;
                this.edgeNum = edgeNum;
                this.graghType = graphType1;

                DingDian = new string[vertexNum];
                edges = new int[vertexNum, vertexNum];
                isTrav = new bool[vertexNum];
            }
        }
        public static MatrixGraph CreateMatrixGraph()
        {
            Console.WriteLine("请输入图的顶点个数,边个数,是否为无向图,用0,1表示");
            var initData = Console.ReadLine().Split(',').Select(i => int.Parse(i)).ToList();
            //对象生成时,调用构造函数
            MatrixGraph graph = new MatrixGraph(initData[0], initData[1], initData[2]);
            Console.WriteLine("请输入各顶点信息:");
            for (int i = 0; i < graph.vertexNum; i++)
            {
                Console.Write("\n第"+(i+1)+"个顶点为:");
                var single = Console.ReadLine();
                //顶点信息加入到集合中
                graph.DingDian[i]= single;
            }
            Console.WriteLine("请输入构成两个顶点的边和权值,以逗号隔开:\n");
            for (int i = 0; i < graph.edgeNum; i++)
            {
                Console.WriteLine(""+(i+1)+"条边:\t");
                initData=Console.ReadLine().Split(',').Select(j=>int.Parse(j)).ToList();
                int start=initData[0];
                int end=initData[1];
                int weight = initData[2];

                graph.edges[start - 1, end - 1] = weight;
                //判断是否为无向图
                if(graph.graghType==1)
                graph.edges[end - 1, start - 1] = weight;
            }//for
            return graph;
        }

        #region 广度优先
        public static  void BFSTraverse(MatrixGraph graph)
        {
            //访问标记默认初始化
            for (int i = 0; i < graph.vertexNum; i++)
                graph.isTrav[i] = false;
            for (int i = 0; i < graph.vertexNum; i++)
                if (!graph.isTrav[i])
                    BFSM(ref graph,i);
        }
        public static void BFSM(ref MatrixGraph graph,int curvertex)
        {
            Queue<int> queue = new Queue<int>();
            queue.Enqueue(curvertex);
            Console.WriteLine("->" + graph.DingDian[curvertex]);
            graph.isTrav[curvertex] = true;
           ///当有节点入队列后,count应该不为空
           //广度优先设计的关键:
            while (queue.Count != 0)
            {
                var temp = queue.Dequeue();//此顶点出队列
                //然后取匹配其邻接点的值
                for (int i = 0; i < graph.vertexNum; i++)
                {
                    if (!graph.isTrav[i] && graph.edges[temp, i] != 0)
                    {
                        Console.WriteLine("->" + graph.DingDian[i]);
                        graph.isTrav[i] = true;
                        queue.Enqueue(i);//为方便下一层的输出
                    }
 
                }
            }
        }
        #endregion
        #region 深度优先
        //又一次用到了递归的算法,你应该很熟悉了
        public static void DFSTraverse(MatrixGraph graph)
        {
            //访问标记默认初始化
            for (int i = 0; i < graph.vertexNum; i++)
                graph.isTrav[i] = false;
            for (int i = 0; i < graph.vertexNum; i++)
                if (!graph.isTrav[i])
                    DFSM(ref graph, i);
        }
        public static void DFSM(ref MatrixGraph graph, int curvertex)
        {
            //Queue<int> queue = new Queue<int>();
            //queue.Enqueue(curvertex);
            Console.WriteLine("->" + graph.DingDian[curvertex]);
            graph.isTrav[curvertex] = true;
            //深度优先设计的关键:递归算法
                for (int i = 0; i < graph.vertexNum; i++)
                {
                    if (!graph.isTrav[i] && graph.edges[curvertex, i] != 0)
                    {
                        DFSM(ref graph,i);
                    }
                }
        }       
        #endregion
        public static void Main(string[] args)
        {
           MatrixGraph graph= CreateMatrixGraph();
           Console.WriteLine("广度优先输出为:");
           BFSTraverse(graph);
           Console.WriteLine("深度优先输出为:");
           DFSTraverse(graph);
           Console.ReadLine();
        }
    }
}
View Code

最小生成树:(prim算法)

算法思想:

假设N=(V,{E})是联通网,TE是N上最小生成树中边的集合。算法从U={u0}(u0属于v),TE={}开始,重复执行下述操作:在所有u属于U,v属于V-U的边(u,v)属于E中找一条代价最小的边(u0,v0)并入集合TE,同时v0并入U,直至U=V为止,此时TE必有n-1条边,则T(V,{TE})为最小生成树。。。

#region prim算法获取最小生成树
public void Prim(MatrixGraph graph,out int sum)
        {
            //已访问过的标志
            int used = 0;
            //非邻接顶点标志
            int noadj = -1;
            //定义一个输出总权值的变量
            sum = 0;
            //临时数组,用于保存邻结点的权值
            int[] weight = new int[graph.vertexNum];
            //临时数组,用于保存顶点信息
            int[] tempvertex = new int[graph.vertexNum];

            //取出第一个顶点和其他顶点之间的边的权值
            for (int i = 1; i < graph.vertexNum; i++)
            {
                weight[i] = graph.edges[0, i];
                //如果权重等于0则说明v1与该邻接点没有边
                if (weight[i] == short.MaxValue)
                    tempvertex[i] = noadj;
                else
                    tempvertex[i] = int.Parse(graph.DingDian[0]);
            }
            //从集合V中取出V1节点,只需要将此节点设置为以访问过,weight为0
            var index = tempvertex[0] = used;
            var min = weight[0] = short.MaxValue;

            //在V的邻接点中找权值最小的结点
            for (int i = 1; i < graph.vertexNum; i++)
            {
                index = i;
                min = short.MaxValue;
                for (int j= 1; j < graph.vertexNum; j++)
                {
                    if (weight[j] < min && tempvertex[j] != 0)
                    {
                        min = weight[j];
                        index = j;
                    }
                }
                sum += min;
                Console.Write("({0},{1})",tempvertex[index],graph.DingDian[index]);
                //将取得的最小结点标识为已访问
                weight[index] = short.MaxValue;
                tempvertex[index] = 0;

                //从最新的结点出发,将此结点的weight比较赋值
                for (int j = 0; j < graph.vertexNum; j++)
                {
                    if (graph.edges[index, j] < weight[j] && tempvertex[j] != used)
                    {
                        weight[j] = graph.edges[index, j];
                        tempvertex[j] = int.Parse(graph.DingDian[index]);
                    }
                }
            }
        }
        #endregion
View Code

最短路径:

看书的算法思想,对哪个例题很清楚怎么分析,对代码还是有点呛,虽然思想也知道,但实现。。难道这样的我只适合考试。。。这就悲剧了,不要这样。。。

posted @ 2013-10-11 21:56  wj704  阅读(204)  评论(0编辑  收藏  举报