您的位置:首页 > 理论基础

东北大学——考研初试——计算机842——图编程题

2020-05-31 22:57 169 查看

邻接表的数据结构,最为常考的结构;邻接矩阵、十字链表、邻接多重表不常考,定义放在文章的最后

typedef struct ArcNode {
int adjvex;
struct ArcNode* next;
}ArcNode;

typedef struct {
VertexType data;
ArcNode* first;
}VexNode;

typedef struct {
VexNode vexlist[MaxVexNum];
int vexnum, arcnum;
}ALGraph;

遍历模板,能解决大部分问题

int visited[MaxVexNum];
void traverse(Graph* G) {
for(int i = 0; i < G->vexnum; ++i) {
visited[MaxVexNum] = 0;
}
for(int i = 0; i < G->vexnum; ++i) {
if(!visited[i]) {
/*
这里有个重要的性质,
对于无线图,只要一次DFS或者BFS就能遍历一个联通分量,可以靠此知道无向图连通分量个数;
对于有向图,一次DFS或者BFS,不一定能遍历一个强连通分量。
考试曾考过几次求无向图连通分量个数。
*/
DFS(G, i); //BFS(G, i);
}
}
}

void DFS(Graph* G, int v) {
visited[v] = 1;
//preVisit(G, v);  放在这里是图的先序遍历
for(int w = FirstAdjVex(G, v); w >= 0; w = NextAdjVex(G, v, w)) {
/*
没时间时候,并要求全部函数都实现的情况下,这样写。
for(ArcNode* p = G->vexlist[v].first; p; p = p->next) {
int w = p->adjvex;
*/
if(!visited[w]) {
DFS(G, w);
}
}
//postVisit(G, v);  放在这里是图的后序遍历
}

void BFS(Graph* G, int v) {
visited[v] = 1;
visit(G, v);
Queue Q;
InitQueue(&Q);
EnQueue(&Q, v);
while(!isEmpty(&Q)) {
v = DeQueue(&Q);
for(int w = FirstAdjVex(G, v); w >= 0; w = NextAdjVex(G, v, w)) {
if(!visited[w]) {
visited[w] = 1;
visit(G, w);
EnQueue(&Q, w);
}
}
}
}

BFS能解决的问题,和点v的最短路径有关,类似树的层次遍历

  • 求出有向图、无向图点v中最短路径长度为k的所有结点 把点v到当前点的最短距离长度d一起入队,当d等于k时输出

DFS能解决的问题,和点src到点dst的路径相关

  • 有向图、无向图中是否存在从src到dst的路径
  • 有向图、无向图中打印所有从src到dst的路径 再加一个全局的栈变量,保存遍历过的路径
Stack S;
void DFS(Graph* G, int src, int dst) {
visited[src] = 1;
push(&S, src);
if(src == dst) {
//print(&S); 打印栈里面的内容
}
for(int v = FirstAdjVex(G, src); v >= 0; w = NextAdjVex(G, src, v)) {
if(!visited[v]) {
DFS(G, v);
}
}
pop(&S);
}

拓扑排序模板

int endegree[MaxVexNum];
int topoSort(Graph* G) {
//获取所有结点入度
FindEndegree(G, endegree);
Stack S;
InitStack(&S);
for(int i = 0; i < G->vexnum; ++i) {
//入度大于0,还不能遍历;等于0,可以遍历;少于0,已经遍历过了
if(!endegree[i]) {
Push(&S, i);
}
}
int count = 0;
while(!IsEmpty(&S)) {
int v = Pop(&S);
++count;
//print(v);
for(int w = FirstAdjVex(G, v); w >= 0; w = NextAdjVex(G, v, w)) {
--endegree[w];
if(!endegree[w]) {
Push(&S, w);
}
}
}
return count >= G.vexnum
}

拓扑排序解决的问题

  • 获取拓扑序列
  • 有向图是否存在环
  • 给结点标序号,要求弧<i, j>符合i<j
  • 逆邻接表中求逆拓扑序列,用出度代替入度
  • 对图进行深度优先后序遍历,再把所得序列用栈来颠倒一下,同样可以获得拓扑排序

邻接表中不用遍历模板的应用,当场也可以自己手写

  • 建立邻接表 输入结点集合序列,边集合序列
  • 输入邻接矩阵
  • 打印邻接表存储结构信息
  • 添加一个从src到dst的弧/边(边还要添加另外一个结点的)
  • 删除一个从src到dst的弧/边(边还要删除另外一个节点的)
  • 复制邻接表
  • 构建逆邻接表
  • 邻接矩阵

    typedef struct {
    VertexType vexlist[MaxVexNum];
    ArcType arcTable[MaxVexNum][MaxVexNum];
    int vexnum, arcnum;
    }MGraph;

    十字链表,有向图

    typedef struct ArcNode {
    int tailvex, headvex;
    struct ArcNode* tlink, * hlink;
    }ArcNode;
    
    typedef struct {
    VertexType data;
    ArcNode* firstin, * firstout;
    }VexNode;
    
    typedef struct {
    VexNode vexlist[MaxVexNum];
    int vexnum, arcnum;
    }GLGraph;

    邻接多重表,无向图

    typedef struct ArcNode {
    //int marked; 访问标记
    int ivex, jvex;
    struct ArcNode* ilink, * jlink;
    }ArcNode;
    
    typedef struct {
    VertexType data;
    ArcNode* first;
    }VexNode;
    
    typedef struct {
    VexNode vexlist[MaxVexNum];
    int vexnum, arcnum;
    }AMLGraph;
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: