数据结构||第六章小结
本章主要学习了图的相关知识,图是一种复杂的非线性数据结构,因此相关内容也比较复杂。
图的重点知识
- 图的分类:无向图、有向图、完全图、连通图、强连通图、带权图、稀疏图和稠密图等。
- 图的存储方式:以边集合方式的表示法(邻接矩阵——借助二维数组来表示元素之间的关系,实现较为简单)
1 #define MaxInt 10000 //表示极大值,即∞ 2 #define MVNum 100 //最大顶点数 3 typedef char VerTexType;//假设顶点的数据类型为字符型 4 typedef int ArcType; //假设边的权值类型为整型 5 typedef struct 6 { 7 VerTexType Vexs[MVNum]; //顶点表 8 ArcType arcs[MVNum] [MVNum]; //邻接矩阵 9 int vexnum,arcnum; //图的当前点数和边数 10 }AMGraph;
和以链接方式的表示法(邻接表、十字链表、邻接多重表——属于链式存储结构,实现较为复杂)
1 #define MvNum 100 //最大顶点数 2 typedef struct ArcNode //边结点 3 { 4 int adjvex; //该边所指向的顶点的位置 5 struct ArcNode *nextarc;//指向下一条边的指针 6 }ArcNode; 7 8 typedef struct VNode //顶点信息 9 { 10 VertexType data; 11 ArcNode *firstarc; //指向第一条依附该顶点的边的指针 12 }VNode,AdjList[MvNum]; //AdjList表示邻接表类型 13 14 typedef struct 15 { 16 AdjList Vertices; //一维数组 17 int vexnum,arcnum; //图的当前顶点数和边数 18 }Graph;
- 图的遍历算法:深度优先搜索遍历(类似于树的先序遍历,借助栈结构来实现)
1 void DFS(Graph a,int b) //深度优先搜索 2 { 3 visited[b]=true; //令顶点对应的visited数组为true,表示该顶点已被访问过 4 cout<<b<<" "; //输出顶点编号及空格 5 6 for(int i=0;i<a.vexnum;i++) 7 { 8 if(a.arcs[b][i]==1 && visited[i]==false)DFS(a,i); //若顶点对应的邻接点未被访问,则递归调用DFS函数 9 } 10 }
1 void BFS(Graph a,int b) //广度优先搜索 2 { 3 int temp; //定义参数 4 5 while(!q.empty()) //若队列不为空 6 { 7 temp=q.front(); //取队头元素值为temp 8 q.pop(); //队头元素出队 9 10 cout<<temp<<" "; //输出temp值及空格 11 12 for(int i=0;i<a.vexnum;i++) 13 { 14 if(a.arcs[temp][i]==1 && visited[i]==false) //若顶点对应的邻接点未被访问,则邻接点入队 15 { 16 q.push(i); //邻接点入队 17 visited[i]=true; //邻接点对应的visited数组取true,表示已被访问 18 } 19 } 20 visited[b]=true; //第一次入队的顶点对应的visited数组值取true,表示已被访问 21 } 22 }
- 图的其他算法
- 构造最小生成树:普里姆算法(归并点,时间复杂度O(n2),适用于稠密图)和克鲁斯卡尔算法(归并边,时间复杂度O(elog2e),适用于稀疏图)
- 最短路径算法:迪杰斯特拉算法(求从某个源点到其余各顶点的最短路径,按路径长度递增的次序产生最短路径,时间复杂度O(n2))和弗洛伊德算法(求每一对顶点之间的最短路径,时间复杂度O(n3))