数据结构 第6章 图 单元小结

弄清楚图 本章重点

1.邻接矩阵:表示顶点之间相邻关系的矩阵

邻接矩阵表示法的特点:

优点:容易实现图的操作,如:求某顶点的度、判断顶点之间是否有边、找顶点的邻接点等等。

缺点:n个顶点需要n*n个单元存储边; 空间效率为O(n2)。对稀疏图而言尤其浪费空间。

2.邻接表

(1)图的链式存储结构

(2)图的邻接表存储表示

 1 #define MVNum 100//最大顶点数
 2
 3 typedef struct ArcNode//边结点
 4
 5 {
 6
 7 int adjvex;//该边所指向的顶点的位置
 8
 9 struct ArcNode *nextarc;//指向下一条边的指针
10
11 OtherInfo info;//和边相关的信息
12
13 }ArcNode;
14
15 typedef struct VNode//顶点信息
16
17 {
18
19 VerTexType data;
20
21 ArcNode *firstarc;//指向第一条依附于边的指针
22
23 }VNode,AdjList[MVNum];//AdjList表示邻接表类型
24
25 typedef struct
26
27 {
28
29 VerTexType vexs[MVNum]; //顶点表
30
31 ArcType arcs[MVNum][MVNum]; //邻接矩阵
32
33 int vexnum,arcnum; //图的当前点数和边数
34
35 }AMGraph;

链式存储结构

3.图的遍历

图的遍历:从图中某个顶点出发游历图,访遍图中其余顶点,并且使图中的每个顶点仅被访问一次的过程。

!!!深搜和广搜

DFS:从图中某个顶点V0 出发,访问此顶点,然后依次从V0的各个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和V0有路径相通的顶点都被访问到

重点:(1)递归过程(2)为了区别顶点是否被访问,附设访问标志数组visited[n],其初值为“false”,一旦某个顶点被访问,则其相应的置被赋为“true”

BFS:在访问了起始点v之后,依次访问 v 的邻接点; 然后再依次访问这些顶点中未被访问过的邻接点; 直到所有顶点都被访问过为止。

重点:(1)分层搜索,不是递归(2)①从图中某个顶点v出发,访问v,并置visited[v]的值为true,然后将v 进队。② 只要队列不空,则重复下述处理: (1)队头顶点u出队。 (2)依次检查u的所有邻接点w,如果visited[w]的值为false,则访问w,并置visited[w]的值为true,然后将w 进队。

列出连通图

  1 #include<iostream>
  2 #include<queue>
  3
  4 using namespace std;
  5
  6 #define MAXNUM 15
  7 bool check[MAXNUM] = {false};
  8
  9 //建立邻接矩阵//Create Graph
 10 int G[MAXNUM][MAXNUM] = {0};
 11 int N,E;//N为顶点数,E为边数
 12
 13 void DFS(int );
 14 int BFS(int );
 15 void ListComponentsDFS();
 16 void ListComponentsBFS();
 17 void isvisited();
 18 void BuildGraph();
 19
 20 int main()
 21 {
 22     //建图
 23     BuildGraph();
 24     //DFS遍历连通集
 25     ListComponentsDFS();
 26     isvisited();
 27     //BFS遍历连通集
 28     ListComponentsBFS();
 29     return 0;
 30 }
 31
 32
 33 void BuildGraph()
 34 {
 35     int i,j;
 36     int v1,v2;//每一行的顶点名称
 37
 38     cin >> N >> E;//N是顶点数,E是边数
 39
 40     for(i = 0;i< E;i++)//每行输出一个连通集
 41     {
 42         cin >> v1 >> v2;//InsertEdge
 43         G[v1][v2] = 1;//联通 置为1
 44         G[v2][v1] = 1;
 45
 46      }
 47  }
 48
 49 //DFS
 50 void DFS(int v)
 51 {
 52     check[v] = true;//已被访问置为true
 53     cout << v <<" ";
 54     for(int i=0;i<N;i++)
 55     {
 56         if(G[v][i] && !check[i])//如果联通且该点没有被访问过
 57         {
 58             DFS(i);
 59      }
 60  }
 61
 62 }
 63
 64 void ListComponentsDFS()
 65 {
 66     int i;
 67     for(i=0;i<N;i++)
 68     {
 69         if(!check[i])
 70         {
 71             cout <<"{ ";
 72             DFS(i);
 73             cout << "}" << endl;
 74         }
 75     }
 76  }
 77
 78 //初始化visited
 79 void isvisited()
 80 {
 81     for(int i=0;i<N;i++)
 82     {
 83         check[i] = false;
 84     }
 85  }
 86
 87 //BFS
 88 int BFS(int v)
 89 {//队列
 90     queue <int> q;
 91     q.push(v);
 92     int x;
 93     check[v] = true;
 94     while(!q.empty())
 95     {
 96         x = q.front();//x本身被访问过
 97         q.pop();
 98         cout << x << " ";
 99         for(int i=0;i<N;i++)
100         {
101             if(!check[i]&&G[x][i]){
102                 check[i] = true;
103                 q.push(i);
104             }
105          }
106       }
107  }
108
109
110 void ListComponentsBFS()
111 {
112     int i;
113     for(i = 0;i<N;i++)
114     {
115         if(!check[i])
116         {
117             cout <<"{ ";
118             BFS(i);
119             cout << "}" <<endl;
120         }
121     }
122 }

列出连通图 完整代码

1.列出连通图的思路:

①先将连通图的构造出来

 1 void BuildGraph()
 2 {
 3     int i,j;
 4     int v1,v2;//每一行的顶点名称
 5
 6     cin >> N >> E;
 7
 8     for(i = 0;i< E;i++)
 9     {
10         cin >> v1 >> v2;//InsertEdge
11         G[v1][v2] = 1;//联通 置为1
12         G[v2][v1] = 1;
13
14      }
15  } 

BuildGraph

②先是DFS

 1 void DFS(int v)
 2 {
 3     check[v] = true;//已被访问置为true
 4     cout << v <<" ";
 5     for(int i=0;i<N;i++)
 6     {
 7         if(G[v][i] && !check[i])//如果联通且该点没有被访问过
 8         {
 9             DFS(i);
10      }
11  }
12
13 }
14
15 void ListComponentsDFS()
16 {
17     int i;
18     for(i=0;i<N;i++)
19     {
20         if(!check[i])
21         {
22             cout <<"{ ";
23             DFS(i);
24             cout << "}" << endl;
25         }
26     }
27  }
28  

DFS

ListComponentsDFS() :用for循环判断结点是否被访问过,若被访问了

DFS:则是用for循环判断结点之间是否连通,并且输出连通的结点

③isvisited

1 void isvisited()
2 {
3     for(int i=0;i<N;i++)
4     {
5         check[i] = false;
6     }
7  }
8  

isvisited()

因为之后要用BFS再进行一次遍历,所以要将之前置为访问过的全部置为未被访问的,这一步还挺关键的

④最后BFS

其实这个地方跟上一章的树有点相似,是用了队列的方法,将头元素入队又出队

 1 int BFS(int v)
 2 {//队列
 3     queue <int> q;
 4     q.push(v);
 5     int x;
 6     check[v] = true;
 7     while(!q.empty())
 8     {
 9         x = q.front();//x本身被访问过
10         q.pop();
11         cout << x << " ";
12         for(int i=0;i<N;i++)
13         {
14             if(!check[i]&&G[x][i]){
15                 check[i] = true;
16                 q.push(i);
17             }
18          }
19       }
20  }
21
22
23 void ListComponentsBFS()
24 {
25     int i;
26     for(i = 0;i<N;i++)
27     {
28         if(!check[i])
29         {
30             cout <<"{ ";
31             BFS(i);
32             cout << "}" <<endl;
33         }
34     }
35 }

BFS

遇到的困难:

在这次的列出连通图中遇到困难有的①“void value not ignored as it ought to be”刚开始我不知道这句话是什么意思我就上网百度了一下,后面发现是因为在BFS函数中本来我是定义为void的,但是后来我又在后面对它了值,最后需要输出队头元素,所以我就将其改成了int类型就搞定了

②“a function-definition is not allowed here before ‘{‘ token”这个问题就是括号没有匹配对的问题 只要细心一点就可以检查出来了,但是刚开始看到function-definition is not allowed 我以为是我没有申明函数,就将main函数和其他函数的位置调换了一下,又在前面申明了函数,但是后来发现还是不行,就开始从{这个问题下手,终于找到了问题所在

③遇到最最最大的困难就是BFS和DFS的区别

刚开始我没有弄清楚BFS和DFS的概念,在画BFS的输出表示时,我觉得很奇怪因为按我的想法是输出{0 1 7 4 2}因为我认为7在4之前入队,是遍历完0的所有连接点再遍历1的连接点,所以7比4先入队

我甚至画了一张图但是是错误的,

后来我明白了,遍历了0的一个连接点后,再接着遍历1 的连接点,所以7在4 之后入队,正确的应该是这样的

所以我们一定要弄清楚概念:深搜:一个节点的所有邻接点都访问完了之后,再访问下一个邻接点

广搜:一个节点的一个邻接点访问完后,就可访问下一个邻接点

目标完成情况:

1.上次是希望pta上的题能够在ddl前比较久的时间完成,这次是做到了,但是我觉得不是很好,因为其实这一章图我觉得很难,我有些懵讲真的,所以这章的两道编程题我都是在网上搜到答案后,搞懂,然后改了一些方法写的,特别是列出连通图的BFS那个地方,网上大部分方法是构造了一个叫quene的数组,来进行队列的功能,但是我觉得上章老师教的方法queue<int>q很好,所以我就改了这部分,用了这个方法来写。

2.下次的目标:我觉得老是从网上参考现有程序这样对自己的能力可能提升不够,希望下次的编程题能够先有自己的思路,而不是急着在网上在答案,来看别人的思路,而是真的能够将自己的思路写成代码实现

PS:这次我改了一下图片的格式,不知道会不会清楚一点,希望能够比上次有进步啦~

原文地址:https://www.cnblogs.com/snowlxy/p/10886829.html

时间: 2024-11-06 16:51:29

数据结构 第6章 图 单元小结的相关文章

数据结构——第六章 图

图是由顶点集V和顶点间的关系集合E(边的集合)组成的一种数据结构.可以用二元组定义为:G=(V,E) 1. 有向图和无向图: 若用箭头表明了边是有方向性的,则称这样的图为有向图. 否则称为无向图. 2.完全图.稠密图.稀疏图 具有n个顶点,n(n-1)/2条边的图,被称为完全无向图,具有n个顶点,n(n-1)条弧的有向图, 称为完全有向图,完全无向图和完全有向图都称为完全图. 3.度,入度,出度 在图中,一个顶点依附的边或弧的数目,称为该顶点的度. 对有向图来说,进入或出去...的个数被称为入度

数据结构——第四章图:01图相关定义

1.图的定义:图是一种网状数据结构,形式化定义如下:图Graph = (V, R),V = {x | x ∈ DataObject},R = {VR},VR = {<x, y> | P(x, y) ∧ (x, y ∈ V)}.集合DataObject中的所有元素具有相同的特性.V中的数据元素通常为顶点(vertex),VR是两个顶点之间关系的集合,P(x, y)表示x和y之间有特定的关系属性P. (1)若<x, y> ∈ VR,则<x, y>表示从顶点x到顶点y的一条弧

数据结构-王道2017-第5章 图

1.图的基本概念 1)图的定义 图G由顶点集V和边集E组成,记为G=(V,E),其中V(G)表示图G中定点的有限非空集:E(G)表示图G中顶点之间的关系(边)集合.V={v1,v2,..,vn},用|V|表示图G中顶点的个数,也称为图G的阶,E={(u,v)| u ∈ V,v ∈ V},用|E|表示图G中边的条数. 注意:线性表可以是空表,树可以是空树,但图不可一世空图.就是说图中不能一个顶点也没有,图的顶点集一定非空,但边集E可以为空,此时图中只有顶点没有边 2)简单图:不存在重复边:不存在顶

图神经网络小结

图神经网络小结 图神经网络小结 图神经网络分类 GCN: 由谱方法到空域方法 GCN概述 GCN的输出机制 GCN的不同方法 基于谱方法的GCN 初始 切比雪夫K阶截断: ChebNet 一阶ChebNet 自适应图卷积网络AGCN 谱方法小结 基于空域方法GCN 基于递归的空间GCN(Recurrent-based Spatial GCNs) 图神经网络GNN(特指早期的一种结构) 门控图神经网络(GGNN) 随机稳态嵌入SSE 基于合成的空间GCN(Composition Based Spa

深入Linux内核架构 - 内核之中数据结构之间的关系图 &amp; 设备驱动程序(转)

内核之中数据结构之间的关系图 设备驱动程序

离散数学--第6章 图

第6章 图• 6.1 图的基本概念• 6.2 图的连通性• 6.3 图的矩阵表示• 6.4 几种特殊的图 6.1 图的基本概念• 6.1.1 无向图与有向图• 6.1.2 顶点的度数与握手定理• 6.1.3 简单图.完全图.正则图.圈图.轮图.方体图• 6.1.4 子图.补图• 6.1.5 图的同构 握手定理 定理6.1 任何图(无向图和有向图)的所有顶点度数之和都等于边数的2倍. 证 图中每条边(包括环)均有两个端点, 所以在计算各顶点度数之和时, 每条边均提供2度, m条边共提供2m度. 推

41 蛤蟆的数据结构笔记之四十一图的遍历之深度优先

41  蛤蟆的数据结构笔记之四十一图的遍历之深度优先 本篇名言:"对于我来说 , 生命的意义在于设身处地替人着想 , 忧他人之忧 , 乐他人之乐. -- 爱因斯坦" 上篇我们实现了图的邻接多重表表示图,以及深度遍历和广度遍历的代码,这次我们先来看下图的深度遍历. 欢迎转载,转载请标明出处: 1.  原理 图遍历又称图的遍历,属于数据结构中的内容.指的是从图中的任一顶点出发,对图中的所有顶点访问一次且只访问一次.图的遍历操作和树的遍历操作功能相似.图的遍历是图的一种基本操作,图的许多其它

数据结构 【实验9 图的基本操作】

实验9  图的基本操作 实验目的 1.  掌握图的各种存储结构,特别要熟练掌握邻接矩阵和邻接表存储结构. 2.遍历是图各种应用的算法的基础,要熟练掌握图的深度优先遍历和广度优先遍历算法,复习栈和队列的应用. 实验内容 程序1 /* 定义邻接矩阵类型 */ typedef int  adjmatrix[n+1][n+1]; /* 建立图的邻接矩阵 */ void CreatMatrix(adjmatrix GA) /* 从初始点v出发深度优先遍历邻接矩阵GA表示的图 */ void DfsMatr

37. 蛤蟆的数据结构笔记之三十七图的概念

37. 蛤蟆的数据结构笔记之三十七图的概念 本篇名言:"宿命论是那些缺乏意志力的弱者的借口.--罗曼? 罗兰" 又到了一个新概念,这次咱们来看 这个图,图一看给人一种凌乱的感觉.那么它在数据结构中又是什么呢? 欢迎转载,转载请标明出处: 1.  图的概念 图(graph)是一种比线性表.树更为复杂的数据结构.在线性表中,数据元素之间呈线性关系,即每个元素只有一个直接前驱和一个直接后继.在树型结构中,数据元素之间有明显的的层次关系,即每个结点只有一个直接前驱,但可有多个直接后继,而在图结