【图论】——图的存储和遍历方式

图的存储

图分为有向图和无向图,在此基础上还有有权和无权图。
有向图适用于邻接表存储,无向图适用于邻接矩阵。

无向图的存储结构——邻接矩阵

无向图的邻接矩阵是对称矩阵,可以压缩为n(n+1)/2;
有向图的邻接矩阵不一定是对称矩阵,存储空间为n²;

邻接矩阵的创建较为简单,只需对矩阵先进行初始化,再将输入的信息放进矩阵,修改矩阵的值即可

创建邻接矩阵

//构建邻接矩阵
#define WQ 65535
void CreatGraph(int n, int e) {
    for (int i = 1; i <= n; i++) {//先对矩阵初始化
        for (int j = 1; j <= n; j++) {
            edge[i][j] = WQ;//WQ即无穷大,默认无穷大为不连通
            if (i == j) edge[i][j] = edge[j][i] = 0;
        }
    }
    for (int k = 0; k < e; k++) {//输入的边的起始点和终点及权值,进行修改
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        edge[a][b] = c;
        edge[b][a] = edge[a][b];
    }
}

有向图的存储结构———邻接表

邻接表:两部分① 顺序存储的顶点表②边链表:对图的每一个顶点都建立一个单链表,包含顶点的所有邻接顶点

在这里插入图片描述

在这里插入图片描述

创建邻接表

//邻接表的结构
typedef struct Vertex {
    int vername;//顶点名称
    struct edge* adjacent;//边链表的头指针
}Vertex;
Vertex head[200];
typedef struct edge {
    int veradj;//邻接顶点序号
    int cost;//权值
    struct edge* link;//指向下一个边结点的指针
}edge;
//从题目中复制下了一部分代码
```for (int i = 1; i <= n; i++)//初始化
        {
            head[i].vername = i;//head数组存放顶点序号
            head[i].adjacent = NULL;//初始化为空
        }
        for (int i = 1; i <= m; i++)
        {//输入各点信息
        ***//创建邻接表***
            scanf("%d %d", &a, &b);//a指向b
            edge* edge1 = creat(b);//某一论文指向的顶点b
            edge* p = head[a].adjacent;//p为边链表头指针
            if (p == NULL)
                head[a].adjacent = edge1;//即a节点没有邻接顶点
            else
            {	//尾插
                p = head[a].adjacent;
                while (p->link)
                {
                    p = p->link;
                }
                p->link = edge1;   //放在最后
        }
    }

图的遍历

深度优先遍历(DFS)

在这里插入图片描述
在这里插入图片描述

递归算法

在这里插入图片描述

迭代算法

在这里插入图片描述

在这里插入图片描述

广度优先遍历(BFS)

类似于树的层次遍历,是分层搜索的过程,不需要回溯,不需要递归。
算法中利用队列记录还未被处理的节点,利用辅助数组vis[ ]给访问过的顶点加标记。
在这里插入图片描述


在这里插入图片描述

需要注意的是:DFS和BFS只是一种思想一种算法,并不是只局限于这一种情况,还有许多可以利用DFS 和 BFS 的情况,需要多加思考

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值