• 数据结构躬行记7_图(邻接矩阵&深度优先&广度优先)


    要点

    重点在于掌握图的基本概念和存储,以及求关键路径、最短路径、拓扑排序的方法。

    概念

    图G由两个集合V和E组成,记为G=(V,E),其中V是顶点的有穷非空集合,E是V中顶点偶对 (称为边)的有穷集合。通常,也将图G的顶点集和边集分别记为V(G)和E(G)。E(G)可以是 空集。若E(G)为空,则图G只有顶点而没有边。

    图的存储结构

    邻接矩阵

    邻接矩阵

    图的遍历

    图的遍历也是从某个顶点出发,沿着某条搜索路径对图中每个顶点各做一次且仅做一次访问, 常用的遍历算法包括以下深度优先和广度优先两种

    代码实现

      1 #include<iostream>
      2 #include<queue>
      3 #include<string.h>
      4 using namespace std;
      5 #define MaxInt 10000
      6 #define Max_V 100
      7 typedef char Vtype;//顶点数据类型是字符型
      8 typedef int Arctype;//边的权值是整形
      9 bool visited[MaxInt];
     10 //图的邻接矩阵存储方式
     11 typedef struct
     12 {
     13     Vtype Vdata[Max_V];    //顶点数据
     14     Arctype arcs[Max_V][Max_V]; //邻接矩阵
     15     int vexnum,arcnum; //顶点数和边数
     16 }AMGraph;
     17 
     18 
     19 //邻接矩阵创建无向网
     20 int LocateVex(AMGraph G,Vtype v);
     21 void CreateGraph(AMGraph &G)
     22 {
     23     cout<<"请输入无向网的顶点个数和边的条数:"<<endl;
     24     cin>>G.vexnum>>G.arcnum;
     25     cout<<"请依次输入顶点的信息:"<<endl;
     26     for(int i=0;i<G.vexnum;i++)
     27         cin>>G.Vdata[i];  //此处存放v1 v2 等等节点的名字
     28     for(int i=0;i<G.vexnum;i++)
     29         for(int j=0;j<G.vexnum;j++)
     30         G.arcs[i][j] = MaxInt;
     31 
     32     cout<<"请依次输入边的俩个顶点信息和边的权值:"<<endl;
     33     for(int k=0;k<=G.vexnum;k++)
     34     {
     35         int i,j;
     36         char v1,v2;
     37         Arctype w;
     38 
     39         cin>>v1>>v2>>w;
     40         i = LocateVex(G,v1);
     41         j = LocateVex(G,v2);
     42         G.arcs[i][j] = w;
     43         G.arcs[j][i] = G.arcs[i][j];
     44     }
     45 }
     46 void Initvisited(AMGraph G,bool v[])
     47 {
     48     for(int i=0;i<G.vexnum;i++)
     49         v[i] = false;
     50 }
     51 //深度遍历无向网
     52 void DFS_AM(AMGraph G,int v)
     53 {
     54     int j;
     55     if(!visited[v]){
     56         cout<<G.Vdata[v]<<"->";
     57         visited[v] = true;
     58     }
     59     for(j=0;j<G.vexnum;j++)
     60     {
     61         if(G.arcs[v][j]!=MaxInt&&!visited[j])
     62         {
     63             DFS_AM(G,j);
     64         }
     65     }
     66 }
     67 
     68 //广度优先遍历无向网
     69 void BFS(AMGraph G,int v)
     70 {
     71     queue<Vtype> q;
     72     int i;
     73     if(!visited[v])
     74     {
     75         cout<<G.Vdata[v]<<"->";
     76         q.push(v);
     77         visited[v] = true;
     78     }
     79     while(!q.empty())
     80     {
     81         i = q.front();
     82         q.pop();
     83         for(int j=0;j<G.vexnum;j++)
     84         {
     85             if(G.arcs[i][j]!=MaxInt&&!visited[j])
     86             {
     87                 cout<<G.Vdata[j]<<"->";
     88                 q.push(j);
     89                 visited[j] = true;
     90             }
     91         }
     92     }
     93 }
     94 
     95 int LocateVex(AMGraph G,Vtype v)
     96 {
     97     int i;
     98     for(i=0;i<G.vexnum;i++)
     99     {
    100         if(G.Vdata[i] ==v)
    101             return i;
    102     }
    103     return -1;
    104 }
    105 
    106 int main()
    107 {
    108     AMGraph m;
    109     CreateGraph(m);
    110     Initvisited(m,visited);
    111     cout<<"深度优先遍历:"<<endl;
    112     DFS_AM(m,0);
    113     Initvisited(m,visited);
    114     //memset(visited,false,sizeof(visited));
    115     cout<<endl;
    116     cout<<"广度优先遍历:"<<endl;
    117     BFS(m,0);
    118   return 0;
    119 }

    总结

    深度遍历的思想是递归,类似于先序遍历输出,广度优先遍历涉及到了栈的知识,一个节点入栈之后接下来入栈的便是上一个入栈节点的子节点(孩子),这样就实现了广度优先。

  • 相关阅读:
    VS2012 窗口布局, update1 和 英语语言包 离线安装方法
    C/C++ 笔记
    MFC学习笔记
    理解虚基类、虚函数与纯虚函数的概念
    ffmpeg使用
    gif制作 & word2007插入gif
    WIN8电脑开机怎么进入安全模式啊?
    vs2012 win8 64 visual assistX 中文 ??
    21 获取文件大小的方法
    20 线程中添加超时的方法
  • 原文地址:https://www.cnblogs.com/g414056667/p/13693854.html
Copyright © 2020-2023  润新知