• 数据结构总复习(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(""+(i+1)+"个顶点为:");
                    var single = Console.ReadLine();
                    //顶点信息加入到集合中
                    graph.DingDian[i]= single;
                }
                Console.WriteLine("请输入构成两个顶点的边和权值,以逗号隔开:
    ");
                for (int i = 0; i < graph.edgeNum; i++)
                {
                    Console.WriteLine(""+(i+1)+"条边:	");
                    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

    最短路径:

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

    作者:wj704    出处:http://www.cnblogs.com/wj204/   
  • 相关阅读:
    PHP 常用命令行
    windows环境下为php打开ssh2扩展
    mysql查看和修改注释
    PHP导出excel时数字变为科学计数的解决方法
    PHP获取上周、本周、上月、本月、本季度、上季度时间方法大全
    centos 基础修改文件权限
    使用apidocJs快速生成在线文档
    封装多线程处理大量数据操作
    android 中resources管理
    Android网格视图(GridView)
  • 原文地址:https://www.cnblogs.com/wj204/p/3364251.html
Copyright © 2020-2023  润新知