基于邻接表的深度优先遍历和广度优先遍历及查路径、入度、出度

typedef struct ArcNode {
    int adjvex;  // 该边所指向的顶点的序号
    struct ArcNode *nextarc;  // 指向下一条边的指针
    int weight; // 边的权值
} ArcNode;  // 弧边的节点结构

typedef struct {
    int data;  // 顶点信息
    int inDegree;  // 顶点的入度
    ArcNode *firstarc; // 指向第一条依附该点的边的指针
} AdjList[5]; // 定点的节点结构

typedef struct {
    AdjList adjList;  //
    int vexnum, arcnum;  // 图当前的顶点数和边数
} Graph;//图的结构定义


bool visited[5] = {false, false, false, false, false}; //标记已经访问过的节点
/**
 * 深度优先遍历  递归
 * @param g
 * @param v
 */
void G_DFS(Graph *g, int v) {
    printf("%d ", g->adjList[v].data);  // 访问顶点v
    visited[v] = true; // 标记已经访问过
    ArcNode *arc = g->adjList[v].firstarc; // 记录第一个链接节点
    while (arc) {
        int adjvex = arc->adjvex; // 拿取顶点所在的序号值
        if (!visited[adjvex]) { // 没有访问过
            G_DFS(g, adjvex); // 深度 递归访问
        }
        arc = arc->nextarc; // 拿取下一个链接节点
    }
}

/**
 * 深度优先算法 非递归
 * @param g 
 */
void G_DFS_N(Graph *g) {
    Stack *stack = NULL;
    stack = initStack(stack); // 初始化栈
    enStack(stack, g->adjList[0].data); // 放入起始节点
    ArcNode *arc = NULL; // 用于标记第一个链接点
    while (!isEmptyStack(stack)) { // 栈为空时,则退出,说明已经全部访问完
        int vex = deStack(stack); // 出栈,
        visited[vex] = true;
        printf("%4d", vex);
        arc = g->adjList[vex].firstarc; // 拿取链接的第一个节点
        while (arc) {
            if (!visited[arc->adjvex]) {
                enStack(stack, arc->adjvex); // 没有访问则放入栈中
            }
            arc = arc->nextarc;
        }
    }
}

/**
 * 广度优先遍历  非递归
 * @param g 
 */
void G_BFS_N(Graph *g) {
    Queue *queue = NULL;
    queue = initQueue(queue); // 初始化队列
    enQueue(queue, g->adjList[0].data); // 起始节点入队
    ArcNode *arc = NULL;
    while (!isNULLQueue(queue)) { // 队列为空时,退出
        int vex = deQueue(queue); // 出队
        visited[vex] = true;
        printf("%4d", vex);
        arc = g->adjList[vex].firstarc;
        while (arc) {
            if (!visited[arc->adjvex]) { // 没有访问过则入队
                enQueue(queue, arc->adjvex);
            }
            arc = arc->nextarc;
        }
    }
}

/**
 * 查找到 k 到 v 的所有简单路径
 * i 表示path的下标,用于回溯操作
 * @return 
 */
void searchKToVPathByDFS(Graph *g, int k, int v, int path[], int i) {
    path[i++] = g->adjList[k].data; // 路径放入
    if (g->adjList[k].data == g->adjList[v].data) { // 说明找到一个简单路径,输出结果
        for (int l = 0; l < i; ++l) {
            printf("%4d", path[l]);
        }
        printf("\n");
        return;
    }
    visited[k] = true; // 标记已经访问
    ArcNode *arc = g->adjList[k].firstarc;
    while (arc) {
        int adjvex = arc->adjvex;
        if (!visited[adjvex]) { // 没有访问过
            searchKToVPathByDFS(g, adjvex, v, path, i); // 递归查找
        }
        // i 不用--,因为当前的i值并没有变化,相当于回溯操作
        arc = arc->nextarc;
    }
}

/**
 * 求顶点v的入度
 * 只需要遍历顶点链表的每一行,只要nextarc==v就是入度
 * @return 
 */
int calculateImportDegree(Graph *g, int v, int n) {
    ArcNode *arc = NULL;
    for (int i = 0; i < g->vexnum; ++i) {
        arc = g->adjList[i].firstarc;
        while (arc) {
            if (arc->adjvex == v) {
                ++n;
            }
            arc = arc->nextarc;
        }
    }
    return n;
}

/**
 * 求度最大的节点
 * @param g
 */
void calculateMaxDegree(Graph *g) {
    int maxVex = 0, max, nowVex;
    ArcNode *arc = NULL;
    for (int i = 0; i < g->vexnum; ++i) {
        arc = g->adjList[i].firstarc;
        nowVex = 0;
        while (arc) { // 求出度
            nowVex++;
            arc = arc->nextarc;
        }
        int importDegree = calculateImportDegree(g, i, 0); // 求入度
        nowVex += importDegree;
        if (nowVex > maxVex) {
            max = i;
            maxVex = nowVex;
        }
    }
    printf("度最大的节点下标:%d", max);
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值