evansyangs evansyangs
首页
分类
标签
归档
GitHub (opens new window)

Evan Yang

摸鱼小能手
首页
分类
标签
归档
GitHub (opens new window)
  • 王道数据结构2019代码
  • Ch2 线性表(p12)
  • Ch3 栈和队列(p58)
  • Ch4 树与二叉树(p101)
  • Ch5 图(p177)
    • 5.2 图的存储及基本操作(p184)
      • 5.2.1 邻接矩阵法(p184)
      • 5.2.2 邻接表法(p186)
      • 5.2.3 十字链表(p187)
      • 5.2.4 邻接多重表(p188)
    • 5.3 图的遍历(p195)
      • 5.3.1 广度优先搜索(BFS)(p195)
      • 5.3.2 深度优先搜索(p197)
    • 5.4 图的应用(p206)
      • 5.4.1 最小生成树(p207)
      • 5.4.3 拓扑排序(p212)
  • Ch6 查找(p234)
  • Ch7 排序(p282)
目录

Ch5 图(p177)

# 5.2 图的存储及基本操作(p184)

# 5.2.1 邻接矩阵法(p184)

结点类型定义

#define MaxVertexNum 100            //顶点数目的最大值
typedef char VertexType;            //顶点的数据类型
typedef int EdgeType;                //带权图中边上权值的数据类型
typedef struct {
    VertexType Vex[MaxVertexNum];               //顶点表
    EdgeType Edge[MaxVertexNum][MaxVertexNum];  //邻接矩阵,边表
    int vexnum, arcnum;                         //图的当前顶点数和弧数
} MGraph;
1
2
3
4
5
6
7
8

# 5.2.2 邻接表法(p186)

图的邻接表存储结构定义

#define MaxVertexNum 100                    //图中顶点数目的最大值
typedef struct ArcNode {                    //边表结点
    int adjvex;                             //该弧所指向的顶点的位置
    struct ArcNode *next;                   //指向下一条弧的指针
    //InfoType info;                        //网的边权值
} ArcNode;
typedef struct VNode {                      //顶点表结点
    VertexType data;                        //顶点信息
    ArcNode *first;                         //指向第一条依附该结点的弧的指针
} VNode, AdjList[MaxVertexNum];
typedef struct {                            //图的邻接表存储结构定义
    AdjList vertices;                       //邻接表
    int vexnum, arcnum;                     //图的顶点数和弧数
} ALGraph;                                  //ALGraph是以邻接表存储的图类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 5.2.3 十字链表(p187)

十字链表存储结构定义

#define MaxVertexNum 100                    //图中顶点数目的最大值
typedef struct ArcNode{                     //边表结点
    int tailvex, headvex;                   //该弧的头尾结点
    struct ArcNode2 *hlink, *tlink;         //分别指向弧头相同和弧尾相同的结点
    //InfoType info;                        //相关信息指针
} ArcNode;
typedef struct VNode{                       //顶点表结点
    VertexType data;                        //顶点信息
    ArcNode *firstin, *firstout;            //指向第一条入弧和出弧
} VNode;
typedef struct {
    VNode xlist[MaxVertexNum];              //邻接表
    int vexnum, arcnum;                     //图的顶点数和弧数
} GLGraph;                                    //GLGraph是以十字邻接存储的图类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 5.2.4 邻接多重表(p188)

图的邻接多重表存储结构定义

#define MaxVertexNum 100                    //图中顶点数目的最大值
typedef struct ArcNode {                    //边表结点
    bool mark;                              //访问标记
    int ivex, jvex;                         //分别指向该弧的两个结点
    struct ArcNode3 *ilink, *jlink;         //分别指向两个顶点的下一条边
    //InfoType info;                        //相关信息指针
} ArcNode;
typedef struct VNode {                      //顶点表结点
    VertexType data;                        //顶点信息
    ArcNode *firstedge;                     //指向第一条依附该顶点的边
}VNode;
typedef struct {
    VNode adjmulist[MaxVertexNum];          //邻接表
    int vexnum, arcnum;                     //图的顶点数和弧数
} AMLGraph;                                 //AMLGraph是以邻接多重表存储的图类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 5.3 图的遍历(p195)

# 5.3.1 广度优先搜索(BFS)(p195)

1.广度优先搜索算法的伪代码

bool visited[MAX_VERTEX_NUM];       //访问标记数组
void BFSTraverse(Graph G){
//对图G进行广度优先遍历,设访问函数为visit()
    for(i=0;i<G.vexnum,++i)
        visited[i]=false;          //访问标记数组初始化
    InitQueue(Q);                  //初始化辅助队列Q
    for (int i = 0; i < G.vexnum; ++i)//从0号顶点开始遍历
        if(!visited[i])            //对每个连通分量调用一次BFS
            BFS(G,i);             //Vi未访问过,从Vi开始BFS
}
void BFS(Graph G,int v){
//从顶点v出发,广度优先遍历图G,算法借助一个辅助队列Q
    visit(v);                        //访问初始顶点v
    visited[v]=true;                //对v做已访问标记
    EnQueue(Q,v);                     //顶点v入队列
    while(!IsEmpty(Q)){
        DeQueue(Q,v);               //顶点v出队列
        for (w=FirstNeighbor(G,v); w>=0;w=NextNeighbor(G,v,w))
        {                           //检测v所有邻接点
            if(!visited[w]){        //w为v的尚未访问的邻接顶点
                visit(w);           //访问顶点w
                visited[w]=true;    //对w做已访问标记
                EnQueue(Q,w);       //顶点w入队列
            }//if
        }
    }//while
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

2.BFS算法求解单源最短路径问题

void BFS_MIN_Distance(Graph G,int u){
//d[i]表示从u到i结点的最短路径
    for (int i = 0; i < G.vexnum; ++i)
        d[i]=∞;                    //初始化路径长度
    visited[u]=true;d[u]=0;
    EnQueue(Q,u);
    while(!IsEmpty(Q)){             //BFS算法主过程
        DeQueue(Q,u);               //队头元素u出队
        for (w=FirstNeighbor(G,u); w>=0;w=NextNeighbor(G,u,w))
        {
            if(!visited[w]){        //w为u的尚未访问的邻接顶点
                visited[w]=true;    //设已访问标记
                d[w]=d[u]+1;        //路径长度加1
                EnQueue(Q,w);       //顶点w入队
            }//if
        }
    }//while
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 5.3.2 深度优先搜索(p197)

bool visited[MAX_VERTEX_NUM];       //访问标记数组
void DFSTraverse(Graph G){
//对图G进行深度优先遍历,访问函数为visit()
    for(v=0;v<G.vexnum,++v)
        visited[v]=false;           //初始化已访问标记数据
    for (v = 0; v < G.vexnum; ++v)  //本代码中是从v=0开始遍历
        if(!visited[v])
            DFS(G,v);
}
void DFS(Graph G,int v){
//从顶点v出发,采用递归思想,深度优先遍历图G
    visit(v);                       //访问顶点v
    visited[v]=true;                //设已访问标记
    for (w=FirstNeighbor(G,v); w>=0;w=NextNeighbor(G,v,w))
    {
        if(!visited[w]){            //w为u的尚未访问的邻接顶点
            DFS(G,w);
        }//if
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 5.4 图的应用(p206)

# 5.4.1 最小生成树(p207)

GENERIC_MST(G){
    T=NULL;
    while T 未形成一颗生成树;
        do 找到一条最小代价边(u,v)并且加入T后不会产生回路;
            T=T∪(u,v);
}
1
2
3
4
5
6
  1. Prim算法
void Prim(G,T){
    T=∅;                        //初始化空树
    U={w};                      //添加任一顶点w
    while((V-U)!=∅){            //若树中不含全部顶点
        设(u,v)是使u∈U与v∈(V-U),且权值最小的边;
        T=T∪{(u,v)};            //边归入树
        U=U∪{v};               //顶点归入树
    }
}
1
2
3
4
5
6
7
8
9

2.Kruskal算法

void Kruskal(V,T){
    T=V;                        //初始化树T,仅含顶点
    numS=n;                        //连通分量数
    while(numS>1){                //如果连通分量数大于1
        从E中取出权值最小的边(v,u);
        if(v和u属于T中不同的连通分量){
            T=T∪{(v,u)};        //将此边加入生成数中
            numS--;                //连通分量数减1
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11

# 5.4.3 拓扑排序(p212)

拓扑排序算法的实现如下

bool TopologicalSort(Graph G){
//如果G存在拓扑序列,返回true;否则返回false,这时G中存在环
    InitStack(S);            //初始化栈,存储入度为0的顶点
    for (int i = 0; i < G.vexnum; ++i)
    {
        if(indegree[i]==0)
            Push(S,i);            //将所有入度为0的顶点进栈
    }
    int count=0;            //计数,记录当前已经输出的顶点数
    while(!IsEmpty(S)){        //栈不空,则存在入度为0的顶点
        Pop(S,i);            //栈顶元素出栈
        print[count++]=i;        //输出顶点i
        for(p=G.vertices[i].firstarc;p=p->nextarc){
        //将所有i指向的顶点的入度减1,并且将入度减为0的顶点压入栈S
            v=p->adjvex;
            if(!(--indegree[v]))
                Push(S,v);      //入度为0,则入栈
        }//for
    }//while
    if(count < G.vexnum)
        return false;        //排序失败,有向图中有回路
    else
        return true;        //拓扑排序成功
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

归纳总结 1.用邻接矩阵作存储结构

int NextNeighbor(MGraph& G,int x,int y){
    if(x!=-1&&y!=-1){
        for (int col=y+1;col < G.vexnum;col++)
        {
            if(G.Edge[x][col] > 0&&G.Edge[x][col] < maxWeight)
                return col;         //maxWeight代表∞
        }
    }
    return -1;
}
1
2
3
4
5
6
7
8
9
10

2.用邻接表作存储结构

int NextNeighbor(ALGraph& G,int x,int y){
    if(x!=-1){                //顶点x存在
        ArcNode *p=G.vertices[x].first;    //对应边链表第一个边结点
        while(p!=NULL&&p->data!=y)    //寻找邻接顶点Y
            p=p->next;
        if(p!=NULL&&p->next!=NULL)
            return p->next->data;    //返回下一个邻接顶点
    }
    return -1;
}
1
2
3
4
5
6
7
8
9
10
编辑 (opens new window)
#数据结构
上次更新: 2021/02/16, 02:45:37
Ch4 树与二叉树(p101)
Ch6 查找(p234)

← Ch4 树与二叉树(p101) Ch6 查找(p234)→

最近更新
01
Dell7472黑苹果
03-27
02
上手HackMD
04-13
03
Windows Terminal设置
03-14
更多文章>
Theme by Vdoing | Copyright © 2019-2023 Evan Yang
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式