zoukankan      html  css  js  c++  java
  • C++编程练习(9)----“图的存储结构以及图的遍历“(邻接矩阵、深度优先遍历、广度优先遍历)

    图的存储结构

    1)邻接矩阵

    用两个数组来表示图,一个一维数组存储图中顶点信息,一个二维数组(邻接矩阵)存储图中边或弧的信息。

    2)邻接表

    3)十字链表

    4)邻接多重表

    5)边集数组

    本文只用代码实现用邻接矩阵方式存储图。忘见谅。

    图的遍历

    1)深度优先遍历(Depth_First_Search,DFS)

    从图中某个顶点 v 出发,访问此顶点,然后从 v 的未被访问的邻接点出发深度优先遍历图,直至图中所有和 v 有路径相通的顶点都被访问到。--------递归思想

    2)广度优先遍历(Breadth_First_Search,BFS)

    类似于树的层序遍历-----------非递归,而是逐层遍历

    区别:深度优先遍历更适合目标比较明确,以找到目标为主要目的的情况,而广度优先更适合在不断扩大遍历范围时找到相对最优解的情况

    具体实现代码如下:

    /* Graph.h头文件 */
    #include<iostream>
    #include"LinkQueue.h"
    #define MAXVEX 100
    #define INFINITY 65535
    #define TRUE 1
    #define FALSE 0
    typedef char VertexType;
    typedef int EdgeType;
    typedef int Boolean;
    using namespace std;
    
    /*邻接矩阵方式建立图*/
    class MGraph{
    public:
    	VertexType vexs[MAXVEX];
    	EdgeType arc[MAXVEX][MAXVEX];
    	int numVertexes,numEdges;
    };
    
    /*建立无向网图的邻接矩阵表示*/
    void CreateMGraph(MGraph *G)
    {
    	int i,j,k,w;
    	cout<<"输入顶点数和边数:"<<endl;
    	cin>>G->numVertexes>>G->numEdges;
    	cin.clear();
    	cout<<"输入顶点信息:"<<endl;
    	for(i=0;i<G->numVertexes;i++)
    	{
    		cin>>G->vexs[i];
    		cin.clear();
    	}
    	for(i=0;i<G->numVertexes;i++)
    		for(j=0;j<G->numVertexes;j++)
    			G->arc[i][j]=INFINITY;
    	for(k=0;k<G->numEdges;k++)
    	{
    		cout<<"输入边(vi,vj)上的下标i,下标j和权w:"<<endl;
    		cin>>i>>j>>w;
    		cin.clear();
    		G->arc[i][j]=w;
    		G->arc[j][i]=G->arc[i][j];
    	}
    }
    
    /*邻接矩阵的深度优先递归算法*/
    Boolean visited[MAXVEX];	/*访问标志的数组*/
    void DFS(MGraph G,int i)
    {
    	int j;
    	visited[i]=TRUE;
    	cout<<G.vexs[i];	/*打印顶点,也可以其他操作*/
    	for(j=0;j<G.numVertexes;j++)
    		if(G.arc[i][j]==1 && !visited[j])
    			DFS(G,j);	/*对为访问的邻接顶点递归调用*/
    }
    /*邻接矩阵的深度优先遍历操作*/
    void DFSTraverse(MGraph G)
    {
    	cout<<"
    深度优先遍历结果为:"<<endl;
    	int i;
    	for(i=0;i<G.numVertexes;i++)
    		visited[i]=FALSE;	/*初始化所有顶点状态都是未访问过状态*/
    	for(i=0;i<G.numVertexes;i++)
    		if(!visited[i])	/*对未访问过的顶点调用DFS,若是连通图,只会执行一次*/
    			DFS(G,i);
    	cout<<endl;
    }
    
    /*邻接矩阵的广度遍历算法*/
    void BFSTraverse(MGraph G)
    {
    	cout<<"广度优先遍历结果为:"<<endl;
    	int i,j;
    	LinkQueue Q;
    	for(i=0;i<G.numVertexes;i++)
    		visited[i]=FALSE;
    	for(i=0;i<G.numVertexes;i++)
    	{
    		if(!visited[i])
    		{
    			visited[i]=TRUE;
    			cout<<G.vexs[i];
    			Q.EnQueue(i);
    			while(!Q.QueueEmpty())
    			{
    				Q.DeQueue(&i);
    				for(j=0;j<G.numVertexes;j++)
    				{
    					if(G.arc[i][j]==1 && !visited[j])
    					{
    						visited[j]=TRUE;
    						cout<<G.vexs[j];
    						Q.EnQueue(j);
    					}
    				}
    			}
    		}
    	}
    	cout<<endl;
    }

    对于如下图这样的一个简单的图结构:


    运行程序,结果如下:


  • 相关阅读:
    Android游戏开发22:Android动画的实现J2me游戏类库用于Android开发
    android sqlite SQLiteDatabase 操作大全 不看后悔!必收藏!看后精通SQLITE (第三部分,完整代码)
    使用OGR创建dxf格式矢量数据
    mysql 数据库引擎 MyISAM InnoDB 大比拼 区别
    android sqlite SQLiteDatabase 操作大全 不看后悔!必收藏!看后精通SQLITE (第二部分)
    mysql 更改数据库引擎
    android sqlite SQLiteDatabase 操作大全 不看后悔!必收藏!看后精通SQLITE (第一部分)
    android 数字键盘使用
    MySQL Innodb数据库性能实践
    eclipse : Error while performing database login with the driver null
  • 原文地址:https://www.cnblogs.com/fengty90/p/3768882.html
Copyright © 2011-2022 走看看