C语言基于邻接表的图的深度优先、广度优先遍历

目录

1 深度优先(Depth_First Search)

2 广度优先(Broadth_First Search)

3 基于邻接表的深度优先、广度优先遍历

4 源代码示例

4.1 深度优先

4.2广度优先


_{}假设有无向图G = (V,E),标志数组visited [ n ]

(1)点集 V = { v_{1}, v_{2}, v_{3}, v_{4}, v_{5}, v_{6}, v_{7}, v_{8} }

     边集 E = {  \left (v_{1}, v_{2}\right ), \left (v_{1}, v_{3}\right ), \left (v_{2}, v_{4}\right ), \left (v_{2}, v_{5}\right ), \left (v_{3}, v_{6}\right ), \left (v_{3}, v_{7}\right ), \left (v_{4}, v_{8}\right ), \left (v_{5}, v_{8}\right ), \left (v_{6}, v_{7}\right ) }

(2)visited [ n ] (n为图中顶点个数,初始元素都为0)

若相应节点被访问过,则visited [ i ] 为 1;否则visited [ i ] 为 0

1 深度优先(Depth_First Search)

选定一个节点并遍历后,遍历该节点的第一个未被遍历邻接点;从刚遍历的节点开始,遍历该节点第一个未被遍历邻接点;

如此重复(深度含义由此可知)。若顶点的所有邻接点都被遍历,则检测visited[]数组,从元素值为0的节点开始遍历。

以上图为例:

从顶点V1开始遍历,然后遍历V1的第一个未被遍历邻接点V2;

从V2开始,遍历V2的第一个未被遍历邻接点V4;

从V4开始,遍历V4的第一个未被遍历邻接点V8;

从V8开始,遍历V8的第一个未被遍历邻接点V5;

从V5开始,发现V5所有邻接点都被遍历,则检测visited[]数组,发现数组中第一个未被遍历邻接点V3;

从V3开始,遍历V3的第一个未被遍历邻接点V6;

从V6开始,遍历V6的第一个未被遍历邻接点V7;

结束。

综上,深度优先序列:1,2,4,8,5,3,6,7。

2 广度优先(Broadth_First Search)

假设从顶点V1开始遍历,则遍历完V1的所有未被遍历邻接点,然后从所有邻接点中挑选出(按顺序从小到大)下标第一小的节点,再遍历该节点所有未被遍历邻接点;第二小……;第三小……。如此循环(广度含义由此可知)。若顶点的所有邻接点都被遍历,则检测visited[]数组,从元素值为0(未遍历)的节点开始遍历。

以上图为例:

从顶点V1开始遍历,然后遍历V1的所有未被遍历邻接点V2,V3;

从V2开始,遍历V2所有未被遍历邻接点V4,V5;

从V3开始,遍历V3所有未被遍历邻接点V6,V7;

从V4开始,遍历V4所有未被遍历邻接点V8。结束

综上,广度优先序列:1,2,3,4,5,6,7,8。

3 基于邻接表的深度优先、广度优先遍历

关于图的邻接表存储,可参考我的博客C语言图的邻接表存储

以上图为例,其邻接表结构如下所示:

顶点 1 :[ 2 ] -> [ 3 ] -> NULL
顶点 2 :[ 1 ] -> [ 4 ] -> [ 5 ] -> NULL
顶点 3 :[ 1 ] -> [ 6 ] -> [ 7 ] -> NULL
顶点 4 :[ 2 ] -> [ 8 ] -> NULL
顶点 5 :[ 2 ] -> [ 8 ] -> NULL
顶点 6 :[ 3 ] -> [ 7 ] -> NULL
顶点 7 :[ 3 ] -> [ 6 ] -> NULL
顶点 8 :[ 4 ] -> [ 5 ] -> NULL

深度遍历

对所有节点(1、2……8),假设从1开始访问,每访问一个节点,便将其标志数组(visited)对应位置置1,然后访问其第一个未被访问的邻接点,接着对当前访问的顶点执行同样操作若所有邻接点都被访问,则遍历标志数组,找到第一个未被访问的节点开始访问。

如上表:1开始;然后2;2第一个未被访问的邻接点4;4第一个未被访问的邻接点8;8第一个未被访问的邻接点5;5的所有邻接点都被访问、则遍历标志数组、找到第一个未被访问的3;3第一个未被访问的邻接点6;6第一个未被访问的邻接点7;结束。

广度遍历 

对所有节点(1、2……8),假设从1开始访问,每访问一个节点,便将其标志数组(visited)对应位置置1,然后访问其所有未被访问的邻接点,接着对节点所有邻接点按顺序重复同样操作。若节点邻接点都被访问,则遍历标志数组,找到第一个未被访问的节点开始访问。

如上表:1开始;访问2、3;然后从1的第一个邻接点2开始、访问2的邻接点4、5;3开始、访问6、7;4开始、访问8;5开始、其所有邻接点都被访问、跳过;……

4 源代码示例

4.1 深度优先

#include <stdio.h>
#include <stdlib.h>

#define MAX_VERTEX_NUM 100 // 图中最大节点数
typedef char VertexType;

// 边表节点
typedef struct node {
    VertexType adjvex; // 与顶点相连的邻接点下标(adjoin:邻接)
    struct node* next; // 指向顶点的下一个邻接点
} EdgeNode;

// 顶点结构
typedef struct vnode {
    VertexType vex;      // 存储顶点名
    EdgeNode* firstedge; // 边表头指针,指向顶点第一个邻接点
} VertexNode, AdjList[MAX_VERTEX_NUM];

typedef struct {
    AdjList adjlist; // 描述图结构的邻接表
    int vexnum;      // 节点的数目
    int edgenum;     // 边的数目
} ALGraph;           // adjacency list:邻接表

void CreateALG(ALGraph* ALG);     // 邻接表法创建图
void TraverseALG(ALGraph ALG);    // 输出图ALG的邻接表
void DFSTraverseALG(ALGraph ALG); // 深度优先遍历以邻接表存储的图ALG
void DFSALG(ALGraph ALG, int i);  // 以Vi为出发点对邻接表存储的图ALG开始DFS搜索
// 定位节点vertex,并将其下标赋给index
void LocateVex(ALGraph ALG, VertexType vertex, int* index);
int visited[MAX_VERTEX_NUM]; // 标志数组

int main(void)
{
    ALGraph g;

    CreateALG(&g);
    printf("------------------------------\n");
    printf("vexnum = %d ; edgenum = %d\n", g.vexnum, g.edgenum);
    printf("------------------------------\n");
    TraverseALG(g);
    printf("------------------------------\n");
    DFSTraverseALG(g);

    return 0;
}
void CreateALG(ALGraph* ALG)
{
    VertexType ch;
    int i = 0, count = 0;
    EdgeNode* temp;

    printf("请输入图的顶点:");
    // 建立顶点表
    while ((ch = getchar()) != '\n') {
        ALG->adjlist[i].vex = ch;
        ALG->adjlist[i].firstedge = NULL;
        i++;
    }
    ALG->vexnum = i; // 顶点数

    // 头插法建立顶点的邻接边表
    for (i = 0; i < ALG->vexnum; i++) {
        printf("请输入顶点 %c 的邻接顶点:", ALG->adjlist[i].vex);
        // 按下回车结束邻接点的创建
        while ((ch = getchar()) != '\n') {
            temp = (EdgeNode*)malloc(sizeof(EdgeNode));
            temp->adjvex = ch;
            temp->next = ALG->adjlist[i].firstedge;
            ALG->adjlist[i].firstedge = temp;
            count++;
        }
    }
    // 无向图中每条边连接两个顶点,故:节点总度数 = 边数 * 2
    ALG->edgenum = count / 2;
}
void TraverseALG(ALGraph ALG)
{
    int i;
    EdgeNode* temp;

    if (ALG.vexnum == 0) {
        printf("图为空\n");
        return;
    }

    // 遍历图
    for (i = 0; i < ALG.vexnum; i++) {
        printf("顶点 %c :", ALG.adjlist[i].vex);
        temp = ALG.adjlist[i].firstedge;
        // 输出图的信息
        while (temp) {
            printf("[ %c ] -> ", temp->adjvex);
            temp = temp->next;
        }
        printf("NULL\n");
    }
}
// 深度优先遍历以邻接表存储的图ALG
void DFSTraverseALG(ALGraph ALG)
{
    int i;

    // 初始化标志数组
    for (i = 0; i < ALG.vexnum; i++) {
        visited[i] = 0;
    }

    printf("图的深度优先遍历序列:");
    // 从第一个节点开始DFS搜索
    for (i = 0; i < ALG.vexnum; i++) {
        if (!visited[i]) {
            DFSALG(ALG, i);
        }
    }
}
// 以下标为i的节点为出发点对图ALG开始DFS搜索
void DFSALG(ALGraph ALG, int i)
{
    EdgeNode* temp;
    int index;

    printf("%c, ", ALG.adjlist[i].vex);
    visited[i] = 1; // 标记节点i已被访问

    temp = ALG.adjlist[i].firstedge;
    while (temp) {
        LocateVex(ALG, temp->adjvex, &index);
        // 若以index为下标的节点未被遍历,则遍历。并从该节点开始进行下一轮DFS搜索
        if (!visited[index]) {
            DFSALG(ALG, index);
        }
        // 若以index为下标的节点被遍历,则寻找节点的下一个邻接点
        temp = temp->next;
    }
}
void LocateVex(ALGraph ALG, VertexType vertex, int* index)
{
    int i;

    for (i = 0; i < ALG.vexnum; i++) {
        if (ALG.adjlist[i].vex == vertex) {
            *index = i; // 将节点vertex的下标赋给index
            return;
        }
    }
}
C:\WINDOWS\system32\cmd.exe /c (gcc -fexec-charset=gbk 1.c -o 1 ^&^& 1 ^&^& del 1.exe)
请输入图的顶点:12345678
请输入顶点 1 的邻接顶点:32
请输入顶点 2 的邻接顶点:541
请输入顶点 3 的邻接顶点:761
请输入顶点 4 的邻接顶点:82
请输入顶点 5 的邻接顶点:82
请输入顶点 6 的邻接顶点:73
请输入顶点 7 的邻接顶点:63
请输入顶点 8 的邻接顶点:54
------------------------------
vexnum = 8 ; edgenum = 9
------------------------------
顶点 1 :[ 2 ] -> [ 3 ] -> NULL
顶点 2 :[ 1 ] -> [ 4 ] -> [ 5 ] -> NULL
顶点 3 :[ 1 ] -> [ 6 ] -> [ 7 ] -> NULL
顶点 4 :[ 2 ] -> [ 8 ] -> NULL
顶点 5 :[ 2 ] -> [ 8 ] -> NULL
顶点 6 :[ 3 ] -> [ 7 ] -> NULL
顶点 7 :[ 3 ] -> [ 6 ] -> NULL
顶点 8 :[ 4 ] -> [ 5 ] -> NULL
------------------------------
图的深度优先遍历序列:1, 2, 4, 8, 5, 3, 6, 7, Hit any key to close this window...

4.2广度优先

广度优先遍历时,需要用队列辅助操作,关于队列的实现,可参考我的博客C语言实现顺序队列、循环队列、链式队列

#include <stdio.h>
#include <stdlib.h>

#define MAX_VERTEX_NUM 100 // 图中最大节点数
typedef char VertexType;   // 定义节点名为char型
// 边表节点
typedef struct node {
    VertexType adjvex; // 与顶点相连的邻接点下标(adjoin:邻接)
    struct node* next; // 指向顶点的下一个邻接点
} EdgeNode;

// 顶点结构
typedef struct vnode {
    VertexType vex;      // 存储顶点名
    EdgeNode* firstedge; // 边表头指针,指向顶点第一个邻接点
} VertexNode, AdjList[MAX_VERTEX_NUM];

// 描述图结构的邻接表
typedef struct {
    AdjList adjlist;
    int vexnum;  // 节点的数目
    int edgenum; // 边的数目
} ALGraph;       // adjacency list:邻接表

int visited[MAX_VERTEX_NUM]; // 标志数组

void CreateALG(ALGraph* ALG);     // 邻接表法创建图
void TraverseALG(ALGraph ALG);    // 输出图ALG的邻接表
void BFSTraverseALG(ALGraph ALG); // 广度优先遍历以邻接表存储的图ALG
// 定位节点vertex,并将其下标赋给index
void LocateVex(ALGraph ALG, VertexType vertex, int* index);

/*----------------定义一个循环队列-------------------*/
#define CQ_INIT_SIZE 100 // 队列初始容量
typedef int dataType;
typedef struct {
    dataType* data; //存储队列元素
    int front;      //指向队列中第一个元素
    int rear;       //指向队列中最后一个元素下一位置
    int cqCapacity; //最多能容纳的元素个数(队列容量)
} CQueue;

CQueue* initCQueue();            //创建一个空循环队列
int push(CQueue* Q, dataType x); //将元素x入队。操作成功返回1,失败返回0
int pop(CQueue* Q, dataType* x); //队首元素出队,并将其值赋给x。操作成功返回1,失败返回0
int isEmpty(CQueue* Q);          //队列空返回1,否则返回0
int isFull(CQueue* Q);           //队列满返回1,否则返回0

int main(void)
{
    ALGraph g;

    CreateALG(&g);
    printf("------------------------------\n");
    printf("vexnum = %d ; edgenum = %d\n", g.vexnum, g.edgenum);
    printf("------------------------------\n");
    TraverseALG(g);
    printf("------------------------------\n");
    BFSTraverseALG(g);

    return 0;
}

void CreateALG(ALGraph* ALG)
{
    VertexType ch;
    int i = 0, count = 0;
    EdgeNode* temp;

    printf("请输入图的顶点:");
    // 建立顶点表
    while ((ch = getchar()) != '\n') {
        ALG->adjlist[i].vex = ch;
        ALG->adjlist[i].firstedge = NULL;
        i++;
    }
    ALG->vexnum = i; // 顶点数

    // 头插法建立顶点的邻接边表
    for (i = 0; i < ALG->vexnum; i++) {
        printf("请输入顶点 %c 的邻接顶点:", ALG->adjlist[i].vex);
        // 按下回车结束邻接点的创建
        while ((ch = getchar()) != '\n') {
            temp = (EdgeNode*)malloc(sizeof(EdgeNode));
            temp->adjvex = ch;
            temp->next = ALG->adjlist[i].firstedge;
            ALG->adjlist[i].firstedge = temp;
            count++;
        }
    }
    ALG->edgenum = count / 2;
    // 无向图中每条边连接两个顶点,故:节点总度数 = 边数 * 2
}

void TraverseALG(ALGraph ALG)
{
    int i;
    EdgeNode* index;

    // 若图为空,则停止遍历
    if (ALG.vexnum == 0) {
        printf("图为空\n");
        return;
    }

    // 遍历图
    for (i = 0; i < ALG.vexnum; i++) {
        printf("顶点 %c :", ALG.adjlist[i].vex);
        index = ALG.adjlist[i].firstedge;
        // 以邻接表形式输出图的信息
        while (index) {
            printf("[ %c ] -> ", index->adjvex);
            index = index->next;
        }
        printf("NULL\n");
    }
}

// 广度优先遍历以邻接表存储的图ALG
void BFSTraverseALG(ALGraph ALG)
{
    int i, index; // index为当前访问节点的索引
    char ch;      // 从节点ch开始对图进行BFS搜索
    EdgeNode* temp;
    CQueue* que = initCQueue();

    // 初始化标志数组
    for (i = 0; i < ALG.vexnum; i++) {
        visited[i] = 0;
    }

    printf("请输入开始节点:");
    scanf("%c", &ch);
    LocateVex(ALG, ch, &index); // 将开始节点ch的下标赋给index

    printf("图的广度优先遍历序列:");
    if (!visited[index]) {
        push(que, index); // 开始节点入队,并修改visited数组
        visited[index] = 1;

        // 当队列不空时
        while (!isEmpty(que)) {
            pop(que, &index); // 队首元素出队并访问
            printf("%c, ", ALG.adjlist[index].vex);

            temp = ALG.adjlist[index].firstedge;
            // 将节点的所有邻接点入队
            while (temp) {
                LocateVex(ALG, temp->adjvex, &index);
                // 若节点未被遍历,则入队并修改visited数组
                if (!visited[index]) {
                    push(que, index);
                    visited[index] = 1;
                }
                temp = temp->next;
            }
        }
    }
}

void LocateVex(ALGraph ALG, VertexType vertex, int* index)
{
    int i;

    for (i = 0; i < ALG.vexnum; i++) {
        if (ALG.adjlist[i].vex == vertex) {
            *index = i; // 将节点vertex的下标赋给index
            return;
        }
    }
    printf("节点 %c 定位失败!\n", vertex);
}

// 建立空队列
CQueue* initCQueue()
{
    CQueue* Q = (CQueue*)malloc(sizeof(CQueue));
    Q->data = (dataType*)malloc(CQ_INIT_SIZE * sizeof(dataType));
    Q->front = 0;
    Q->rear = 0;
    Q->cqCapacity = CQ_INIT_SIZE;

    return Q;
}
int isFull(CQueue* Q)
{
    return (Q->rear + 1) % Q->cqCapacity == Q->front ? 1 : 0;
}

int isEmpty(CQueue* Q)
{
    return Q->front == Q->rear ? 1 : 0;
}
// 入队
int push(CQueue* Q, dataType x)
{
    if (isFull(Q)) {
        // 若达到最大容量,则将新容量扩大至旧容量 1.5 倍
        int increment = Q->cqCapacity / 2;
        Q->data = (dataType*)realloc(Q->data,
            (Q->cqCapacity + increment) * sizeof(dataType));

        if (!Q->data) {
            return 0;
        }
        Q->cqCapacity += increment;
    }
    Q->data[Q->rear] = x;
    Q->rear = (Q->rear + 1) % Q->cqCapacity;
    return 1;
}
// 出队
int pop(CQueue* Q, dataType* x)
{
    if (isEmpty(Q)) {
        return 0;
    } else {
        *x = Q->data[Q->front];
        Q->front = (Q->front + 1) % Q->cqCapacity;
        return 1;
    }
}

C:\WINDOWS\system32\cmd.exe /c (gcc -fexec-charset=gbk 1.c -o 1 ^&^& 1 ^&^& del 1.exe)
请输入图的顶点:12345678
请输入顶点 1 的邻接顶点:32
请输入顶点 2 的邻接顶点:541
请输入顶点 3 的邻接顶点:761
请输入顶点 4 的邻接顶点:82
请输入顶点 5 的邻接顶点:82
请输入顶点 6 的邻接顶点:73
请输入顶点 7 的邻接顶点:63
请输入顶点 8 的邻接顶点:54
------------------------------
vexnum = 8 ; edgenum = 9
------------------------------
顶点 1 :[ 2 ] -> [ 3 ] -> NULL
顶点 2 :[ 1 ] -> [ 4 ] -> [ 5 ] -> NULL
顶点 3 :[ 1 ] -> [ 6 ] -> [ 7 ] -> NULL
顶点 4 :[ 2 ] -> [ 8 ] -> NULL
顶点 5 :[ 2 ] -> [ 8 ] -> NULL
顶点 6 :[ 3 ] -> [ 7 ] -> NULL
顶点 7 :[ 3 ] -> [ 6 ] -> NULL
顶点 8 :[ 4 ] -> [ 5 ] -> NULL
------------------------------
请输入开始节点:1
图的广度优先遍历序列:1, 2, 3, 4, 5, 6, 7, 8, Hit any key to close this window...

  • 125
    点赞
  • 537
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
### 回答1: 邻接表是用于存储的数据结构,深度优先遍历广度优先遍历是两种常见的遍历算法。 下面是C语言实现邻接表深度优先遍历广度优先遍历的代码: 首先,定义邻接表的结构体: ```c typedef struct EdgeNode { int adjvex; // 邻接点下标 struct EdgeNode *next; // 指向下一个邻接点的指针 } EdgeNode; typedef struct VertexNode { int data; // 顶点数据 EdgeNode *firstedge; // 指向第一个邻接点的指针 } VertexNode, AdjList[MAXV]; typedef struct { AdjList adjList; // 邻接表 int vexnum, edgenum; // 顶点数和边数 } GraphAdjList; ``` 然后,实现深度优先遍历: ```c // 访问顶点 v void visit(int v) { printf("%d ", v); } // 从顶点 v 开始深度优先遍历 void DFS(GraphAdjList G, int v, int visited[]) { visited[v] = 1; // 标记顶点 v 已被访问 visit(v); // 访问顶点 v EdgeNode *p = G.adjList[v].firstedge; while (p != NULL) { int w = p->adjvex; // 获取邻接点下标 if (!visited[w]) { // 若邻接点未被访问,则递归访问它 DFS(G, w, visited); } p = p->next; } } // 遍历整个,对每个未被访问的顶点调用 DFS void DFSTraverse(GraphAdjList G) { int visited[MAXV] = {0}; // 初始化 visited 数组为 0 for (int i = 0; i < G.vexnum; i++) { if (!visited[i]) { DFS(G, i, visited); } } } ``` 最后,实现广度优先遍历: ```c // 从顶点 v 开始广度优先遍历 void BFS(GraphAdjList G, int v, int visited[]) { int queue[MAXV], front = 0, rear = 0; visit(v); // 访问顶点 v visited[v] = 1; // 标记顶点 v 已被访问 queue[rear++] = v; // v 入队 while (front != rear) { // 队列非空 int w = queue[front++]; // 出队 EdgeNode *p = G.adjList[w].firstedge; while (p != NULL) { int u = p->adjvex; // 获取邻接点下标 if (!visited[u]) { // 若邻接点未被访问,则访问它并将其入队 visit(u); visited[u] = 1; queue[rear++] = u; } p = p->next; } } } // 遍历整个,对每个未被访问的顶点调用 BFS void BFSTraverse(GraphAdjList G) { int visited[MAXV] = {0}; // 初始化 visited 数组为 0 for (int i = 0; i < G.vexnum; i++) { if (!visited[i]) { BFS(G, i, visited); } } } ``` 其中,MAXV 表示最大顶点数。 ### 回答2: 邻接表是一种的存储结构,C语言可以通过链表来实现邻接表深度优先遍历广度优先遍历深度优先遍历深度优先遍历是一种以深度为优先的遍历方法,它从起始顶点开始,访问其所有未访问过的邻接顶点,然后再访问这些邻接顶点的邻接顶点。在C语言中,我们可以使用递归函数来实现深度优先遍历邻接表。具体步骤如下: 1. 创建一个数组visited,用于记录每个顶点是否被访问过。 2. 选择一个起始顶点v,将visited[v]标记为已访问。 3. 遍历顶点v的邻接链表,对于每个未访问过的邻接顶点u,调用递归函数DFS(u),继续深度优先遍历。 4. 重复步骤3,直到中所有的顶点都被访问过。 具体的C语言代码如下: ``` #include <stdlib.h> #include <stdio.h> struct Node { int data; struct Node* next; }; void DFS(int v, struct Node** adj_list, int* visited) { struct Node* temp = adj_list[v]; visited[v] = 1; printf("%d ", v); while (temp != NULL) { int u = temp->data; if (!visited[u]) { DFS(u, adj_list, visited); } temp = temp->next; } } void addEdge(struct Node** adj_list, int src, int dest) { struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->data = dest; newNode->next = adj_list[src]; adj_list[src] = newNode; newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->data = src; newNode->next = adj_list[dest]; adj_list[dest] = newNode; } int main() { int num_vertices = 5; struct Node** adj_list = (struct Node**)malloc(num_vertices * sizeof(struct Node*)); int* visited = (int*)calloc(num_vertices, sizeof(int)); for (int i = 0; i < num_vertices; i++) { adj_list[i] = NULL; } addEdge(adj_list, 0, 1); addEdge(adj_list, 0, 2); addEdge(adj_list, 1, 2); addEdge(adj_list, 2, 0); addEdge(adj_list, 2, 3); addEdge(adj_list, 3, 3); printf("深度优先遍历结果:\n"); DFS(2, adj_list, visited); return 0; } ``` 广度优先遍历广度优先遍历是一种以广度为优先的遍历方法,它从起始顶点开始,访问其所有邻接顶点,然后再访问这些邻接顶点的邻接顶点,依次类推,直到中所有的顶点都被访问过。在C语言中,可以使用队列来实现广度优先遍历邻接表。具体步骤如下: 1. 创建一个数组visited,用于记录每个顶点是否被访问过。 2. 创建一个空队列queue,将起始顶点v入队,并将visited[v]标记为已访问。 3. 从队列中取出一个顶点u,访问u,将其所有邻接顶点入队并标记为已访问。 4. 重复步骤3,直到队列为空。 具体的C语言代码如下: ``` #include <stdlib.h> #include <stdio.h> struct Node { int data; struct Node* next; }; void BFS(int v, struct Node** adj_list, int* visited) { struct Node* queue = (struct Node*)malloc(sizeof(struct Node)); struct Node* front = queue; struct Node* rear = queue; visited[v] = 1; printf("%d ", v); while (front != NULL) { v = front->data; front = front->next; struct Node* temp = adj_list[v]; while (temp != NULL) { int u = temp->data; if (!visited[u]) { visited[u] = 1; printf("%d ", u); struct Node* new_node = (struct Node*)malloc(sizeof(struct Node)); new_node->data = u; new_node->next = NULL; rear->next = new_node; rear = new_node; } temp = temp->next; } } } void addEdge(struct Node** adj_list, int src, int dest) { struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->data = dest; newNode->next = adj_list[src]; adj_list[src] = newNode; newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->data = src; newNode->next = adj_list[dest]; adj_list[dest] = newNode; } int main() { int num_vertices = 5; struct Node** adj_list = (struct Node**)malloc(num_vertices * sizeof(struct Node*)); int* visited = (int*)calloc(num_vertices, sizeof(int)); for (int i = 0; i < num_vertices; i++) { adj_list[i] = NULL; } addEdge(adj_list, 0, 1); addEdge(adj_list, 0, 2); addEdge(adj_list, 1, 2); addEdge(adj_list, 2, 0); addEdge(adj_list, 2, 3); addEdge(adj_list, 3, 3); printf("广度优先遍历结果:\n"); BFS(2, adj_list, visited); return 0; } ``` 这样,我们就可以使用C语言来实现邻接表深度优先遍历广度优先遍历了。 ### 回答3: C语言实现邻接表深度优先遍历广度优先遍历的步骤如下: 深度优先遍历(DFS): 1. 声明一个栈,并将起始顶点压入栈中。 2. 创建一个布尔数组,用来标记每个顶点是否被访问过,并将起始顶点标记为已访问。 3. 循环执行以下步骤,直到栈为空: 1) 弹出栈顶元素,并输出该顶点。 2) 查找该顶点的邻接顶点: a) 若邻接顶点未被访问过,则将其压入栈中,并标记为已访问。 b) 若邻接顶点已被访问过,则继续查找下一个邻接顶点。 4. 遍历结束。 广度优先遍历(BFS): 1. 声明一个队列,并将起始顶点入队。 2. 创建一个布尔数组,用来标记每个顶点是否被访问过,并将起始顶点标记为已访问。 3. 循环执行以下步骤,直到队列为空: 1) 出队一个顶点,并输出该顶点。 2) 查找该顶点的邻接顶点: a) 若邻接顶点未被访问过,则将其入队,并标记为已访问。 b) 若邻接顶点已被访问过,则继续查找下一个邻接顶点。 4. 遍历结束。 在这两种遍历中,我们使用一个布尔数组来记录顶点的访问情况,避免重复访问。同时,栈和队列分别用来记录当前正在访问的顶点,以便按照深度优先或广度优先的顺序进行遍历。 以上是C语言实现邻接表深度优先遍历广度优先遍历的基本步骤,可以通过循环和递归等不同方式来实现具体代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值