1. 图的深度优先遍历
深度优先搜索算法:数据结构是栈。通过将顶点存入栈中,沿着路径探索顶点,存在新的相邻顶点就去访问
邻接矩阵深度遍历思路:
1.将图的顶点和边的信息输入到图结构中
2.创建一个数组,用来标识顶点是否已经被遍历过
3.初始化数组,将数组中元素置位 False
4.选择顶点开始遍历(注意非连通图的情况)
5.进入递归,打印 i 对应的顶点信息,并将该顶点标识为已遍历
6.循环遍历边表,判断当前边表中两个顶点是否有边(arc[i][j] 是否等 1),并且当前顶点没有遍历过,则继续递归遍历
邻接矩阵深度遍历代码实现:
// 深度优先
int visited[MAXVEX]; // 访问标志的数组
void DFS(MGraph G,int i){
// ✅ 修改标志
visited[i] = TRUE;
printf("%c",G.vers[i]);
// ✅ 递归遍历
for (int j = 0; j <= G.numNodes; j++) {
if (G.arc[i][j] == 1 && !visited[j]) {
DFS(G, j);
}
}
}
void DFSTravese(MGraph G){
// ✅ 初始化标志数组
for (int i = 0; i < G.numNodes; i++) {
visited[i] = FALSE;
}
// ✅ 某一个顶点(防止非连通图)
for (int i = 0; i <= G.numNodes; i++) {
// 判断是否已经访问
if (!visited[i]) {
DFS(G, i);
}
}
}
邻接表深度遍历代码:
// 深度优先
int visited[MAXVEX]; // 访问标志的数组
void DFS(MGraph G,int i){
// 修改标志
visited[i] = TRUE;
EdgeNode *p;
// 打印顶点 A
printf("%c",G.adjlist[i].data);
p = G.adjlist[i].firstedge;
while (p) {
if (!visited[p->adj_vex_index]) {
DFS(G, p->adj_vex_index);
}
p = p->next;
}
}
void DFSTravese(MGraph G){
// 初始化标志数组
for (int i = 0; i < G.numNodes; i++) {
visited[i] = FALSE;
}
// 某一个顶点(防止非连通图)
for (int i = 0; i <= G.numNodes; i++) {
// 判断是否已经访问
if (!visited[i]) {
DFS(G, i);
}
}
}
2. 图的广度优先遍历
广度优先搜索算法:数据结构是队列。通过将顶点存入队列中,最先入队列的顶点先被探索。
思路: 先把 图 旋转,看成树 1.把根节点放到队列的末尾 2.每次从队列的头部取出一个元素,检测这个元素是否有下一级,有则全部放到队尾 3.找到所有要找的元素是结束程序 4.如果遍历整个树还没有找到,结束程序。
广度优先遍历,需要用到队列,我们先定义队列的方法
// 定义队列
typedef struct {
int data[MAXVEX];
int front;
int rear;
}Queue;
// 初始化
Status InitQueue(Queue *Q) {
Q->front = 0;
Q->rear = 0;
return OK;
}
// 判断空
Status QueueEmpty(Queue Q) {
if (Q.front == Q.rear) {
return TRUE;
}
return FALSE;
}
//入队
Status EnQueue(Queue *Q, int e) {
if ((Q->rear+1)%MAXVEX == Q->front) {
return ERROR;
}
Q->data[Q->rear] = e;
Q->rear = (Q->rear + 1)%MAXVEX;
return OK;
}
// 出队
Status DeQueue(Queue *Q, int *e) {
if (Q->front == Q->rear) /* 队列空的判断 */
return ERROR;
*e = Q->data[Q->front];
Q->front = (Q->front+1)%MAXVEX;
return OK;
}
邻接矩阵广度优先遍历
int visited[MAXVEX]; /* 访问标志的数组 */
void BFSTraverse(MGraph G){
Queue Q;
InitQueue(&Q);
// 将访问标志数组全部置为"未访问状态FALSE"
for (int i = 0 ; i < G.numVertexes; i++) {
visited[i] = FALSE;
}
// 将访问标志数组全部置为"未访问状态FALSE"
for (int i = 0; i < G.numNodes; i++) {
if (!visited[i]) {
visited[i] = TRUE;
printf("%c ",G.vers[i]);
// 入队
EnQueue(&Q, i);
while (!QueueEmpty(Q)) {
// 出队
DeQueue(&Q, &i);
for (int j = 0; j < G.numNodes; j++) {
if (G.arc[i][j] == 1 && !visited[j]) {
visited[j] = TRUE;
printf("%c ",G.vers[j]);
EnQueue(&Q, j);
}
}
}
}
}
}
邻接表广度优先遍历
int visited[MAXSIZE]; /* 访问标志的数组 */
void BFSTraverse(GraphAdjList GL){
//1.创建结点
EdgeNode *p;
Queue Q;
InitQueue(&Q);
//2.将访问标志数组全部置为"未访问状态FALSE"
for(int i = 0; i < GL->numVertexes; i++)
visited[i] = FALSE;
//3.对遍历邻接表中的每一个顶点(对于连通图只会执行1次,这个循环是针对非连通图)
for(int i = 0 ;i < GL->numVertexes;i++){
//4.判断当前结点是否被访问过.
if(!visited[i]){
visited[i] = TRUE;
//打印顶点
printf("%c ",GL->adjList[i].data);
EnQueue(&Q, i);
while (!QueueEmpty(Q)) {
DeQueue(&Q, &i);
p = GL->adjList[i].firstedge;
while (p) {
//判断
if(!visited[p->adjvex]){
visited[p->adjvex] = TRUE;
printf("%c ",GL->adjList[p->adjvex].data);
EnQueue(&Q, p->adjvex);
}
p = p->next;
}
}
}
}
}