2023数据结构考研复习-图
Posted ZSYL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2023数据结构考研复习-图相关的知识,希望对你有一定的参考价值。
2023数据结构考研复习-图(六)
综合应用题
1. 图的邻接表表示转换成邻接矩阵表示
算法的基本思想:设图的顶点分别存储在数组v[n]中。首先初始化邻接矩阵。遍历邻接表,在依次遍历顶点 v[i]的边链表时,修改邻接矩阵的第i行的元素值。若链表边结点的值为j,则置arcs[i][j]=1。遍历完邻接表时,整个转换过程结束。此算法对于无向图、有向图均适用。
void convert(ALGraph &G, int arc[M][N])
for (int i = 0; i < n; i++)
p = (G->v[i]).firstarc; // 取出顶点i的第一条出边
while (p != NULL)
arcs[i][p->adjvex] = 1;
p = p->nextarc;
2. 度为奇数的顶点个数不大于2的偶数
1)算法的基本设计思想
本算法题属于送分题,题干已经告诉我们算法的思想。对于采用邻接矩阵存储的无向图,在邻接矩阵的每一行(列)中,非零元素的个数为本行(列)对应顶点的度。可以依次计算连通图G中各顶点的度,并记录度为奇数的顶点个数,若个数为0或2,则返回1,否则返回0。
2)算法实现
int isExistEL(MGraph G)
int degree, i, j, count = 0;
for (int i = 0; i < G.numVertices; i++)
degree = 0;
for (int j = 0; j < G.numVertices; j++)
degree += G.Edge[i][j];
if (degree % 2 != 0)
count++;
if (count == 0 || count == 2)
return 1;
else
return 0;
3)时间复杂度和空间复杂度
算法需要遍历整个邻接矩阵,所以时间复杂度是 O(n2),空间复杂度是 O(1).
3. 判断一个无向图G是否为一棵树
试设计一个算法,判断一个无向图G是否为一棵树。若是一棵树,则算法返回true,否则返回false。
一个无向图G是一棵树的条件是,G必须是无回路的连通图或有n-1条边的连通图。
这里采用后者作为判断条件。对连通的判定,可用能否遍历全部顶点来实现。可以采用深度优先搜索算法在遍历图的过程中统计可能访问到的顶点个数和边的条数,若一次遍历就能访问到n个顶点和n-1条边,则可断定此图是一棵树。
算法实现如下:
bool isTree(Graph& G)
for (int i = 1; i <= G.vexnum; i++)
visited[i] = false;
int Vnum = 0, Enum = 0;
DFS(G, 1, Vnum, Enum, visited);
if (Vnum == G.Vexnum && Enum == 2*(G.vexnum-1))
return true;
else
return false;
void DFS(Graph &G, int v, int &Vnum, int &Enum, int visited[])
visited[v] = true; Vnum++;
int w = FirstNeighbor(G, v);
while (w != -1)
Enum++;
if (!visited[w])
DFS(G, w, Vnum, Enum, visited);
w = NextNeighibor(G, v, w);
4. 深度优先搜索DFS算法的非递归算法
03.写出图的深度优先搜索DFS算法的非递归算法(图采用邻接表形式)。
在深度优先搜索的非递归算法中使用了一个栈s来记忆下一步可能访问的顶点,同时使用一个访问标记数组visited[i]来记忆第i个顶点是否在栈内或曾经在栈内,若是则它以后不能再进栈。
图采用邻接表形式,算法的实现如下:
void DFS_Non_RC (AGraph &G, int v)
int w;
InitStack(S);
for (int i = 0; i < G.Vnum; i++)
vis[i] = false;
PUSH(S, v);
vis[v] = true;
while (!IsEmpty(S))
k = Pop(S);
visit(k);
for (w = FirstNeighbor(G, k); w >= 0; w = Neighbor(G, k, w))
if (!vis[w])
Push(S, w);
vis[w] = true;
5. BFS,DFS找路径
分别采用基于深度优先遍历和广度优先遍历算法判别以邻接表方式存储的有向图中是否存在由顶点v到顶点v的路径(i≠j)。
注意,算法中涉及的图的基本操作必须在此存储结构上实现。
两个不同的遍历算法都采用从顶点vi,出发,依次遍历图中每个顶点,直到搜索到顶点v,若能够搜索到vj;则说明存在由顶点vi,到顶点vj的路径。
int vis[MAXSIZE] = 0;
void dfs(ALGraph G, int i, int j, bool &can)
if (i == j)
can = true;
return;
vis[i] = true;
for (w = FirstNeighbor(G, k); w >= 0; w = Neighbor(G, k, w))
if (!vis[w] && !can)
dfs(G, w, j, can);
BFS:
int vis[MAXSIZE] = 0;
void bfs(ALGraph G, int i, int j, bool &can)
InitQueue(Q);
EnQueue(Q, i);
while (!IsEmpty(Q))
Dequeue(Q, u);
vis[u] = true;
if (u == j)
return 1;
for (w = FirstNeighbor(G, u); w >= 0; w = Neighbor(G, u, w))
if (w == j)
return 1;
if (!vis[w])
EnQueue(Q, w);
vis[w] = 1;
return 0;
本题也可以这样解答:调用以i为参数的 DFS (G,i)或 BFS (G,i),执行结束后判断visited[i]是否为TRUE,若是则说明v,已被遍历,图中必存在由v到v的路径。但此种解法每次都耗费最坏时间复杂度对应的时间,需要遍历与v连通的所有顶点。
6. u-v简单路径
假设图用邻接表表示,设计一个算法,输出从顶点u,到顶点v的所有简单路径。
void FindPath(AGraph *G, int u, int v, int path[], int d)
int w, i;
ArcNode *p;
d++;
path[d] = u; // 将当前结点添加到路径上
vis[u] = 1; // 置已访问的标记
if (u == v)
print(path[]);
p = G->adjlist[u].firstarc; // p指向u的第一个相邻点
while (p != NULL)
w = p->adjvex;
if (vis[w] == 0) // 若顶点w没有访问,递归访问
FindPath (G, w, V, path, d);
p = p->nextarc;
vis[u] = 0;
以上是关于2023数据结构考研复习-图的主要内容,如果未能解决你的问题,请参考以下文章