实验七 图的深度优先遍历

  1. 实验目的

熟悉图的数组表示法和邻接表存储结构,掌握构造有向图、无向图的算法 ,在掌握以上知识的基础上,熟悉图的深度优先遍历算法,并实现。

  1. 实验内容

(1)图的数组表示法定义及基本操作的实现。

(2)图的邻接表表示法定义及基本操作的实现。

(3)写函数实现图的深度优先遍历(分别在两种结构上)

(4)在邻接表上实现拓扑排序、关键路径的求法,在邻接矩阵上实现最短路经、最小生成树的求法。

  1. 问题描述

    (说明你选做的题目及要求

(2)图的邻接表表示法定义及基本操作的实现。邻接表(Adjacency List)是图的一种顺序存储与链式存储结合的存储方法。邻接表表示法类似于树的孩子链表表示法。就是对于图G 中的每个顶点vi,将所有邻接于vi 的顶点vj 链成一个单链表,这个单链表就称为顶点vi 的邻接表,再将所有点的邻接表表头放到数组中,就构成了图的邻接表

  1. 数据结构定义

    (说明你算法中用到的数据结构、数据类型的定义

一个图的邻接表存储结构可形式地说明如下:

#define MAX_VERTEX_NUM  20

Typedef struct ArcNode {

Int           adjvex;     //该弧所指向的顶点的位置

Struct ArcNode *nexttarc;   //指向下一条弧的指针

InfoType      *info;      //该弧相关信息的指针

}ArcNode ;

typedef struct VNode{

VertexType  data;  //顶点信息

ArcNode *firstarc;   //指向第一条依附该顶点的弧的指针

}VNode,AdjList[MAX_VERTEX_ NUM];

Typedef struct{

AdjList   vertices;

Int    vexnum,arcnum;//图的当前顶点数和弧数

Int    kind;          //图的种类标志

}ALGraph;
  1. 算法思想及算法设计

    (先文字说明算法的思想,然后给出类C语言算法

图的邻接表表示法类似于树的孩子链表表示法。对于图G中的每个顶点vi,该方法把所有邻接于vi的顶点vj链成一个带头结点的单链表,这个单链表就称为顶点vi的邻接表.建立顶点表读入顶点信息边表头指针置为空读入边(Vi, Vj)的顶点对应的序号生成边表节点

void CreatALGraph(ALGraph G)

{

int i, j, k, a;

EdgeNode s; //定义边表节点

printf("请输入顶点数和边数:\n");

scanf("%d %d", &i, &j);

G->n = i;

G->e = j;

printf("请输入顶点编号:\n");

for (i = 1; i <= G->n; i++) //建立顶点表

{

scanf("%d", &a);

G->adjlist[i].vertex = a; //读入顶点信息

G->adjlist[i].firstedge = NULL; //边表头指针置为空

}



printf("请输入由两个定点构成的边,示例:0 1\n");

for (k = 0; k < G->e; k++)

{

scanf("%d %d", &i, &j); //读入边(Vi, Vj)的顶点对应的序号

s = malloc(sizeof(struct node)); //生成边表节点

s->adjvex = j;

s->next = G->adjlist[i].firstedge;

G->adjlist[i].firstedge = s; //将新节点*s插入顶点Vi的边表头部

}

}

  1. 实验代码

    (即C语言程序

#include <stdio.h>

#include <stdlib.h>



#define MaxVertexNum 50



typedef struct node *EdgeNode;

typedef struct vnode *VertexNode;

typedef struct graph *ALGraph;



struct node

{ //边表节点

int adjvex; //邻接点域

EdgeNode next; //链域

};



struct vnode

{ //顶点表节点

int vertex; //顶点域

EdgeNode firstedge; //边表头指针

};



struct graph

{

struct vnode *adjlist;

int n; //图中当前顶点数

int e; //图中当前边数

};



void CreatALGraph(ALGraph G)

{

int i, j, k;

int a;

EdgeNode s; //定义边表节点

printf("请输入顶点数和边数:\n");

scanf("%d %d", &i, &j);

G->n = i;

G->e = j;

printf("请输入顶点编号:\n");

for (i = 1; i <= G->n; i++) //建立顶点表

{

scanf("%d", &a);

G->adjlist[i].vertex = a; //读入顶点信息

G->adjlist[i].firstedge = NULL; //边表头指针置为空

}



printf("请输入由两个定点构成的边,示例:0 1\n");

for (k = 0; k < G->e; k++)

{

scanf("%d %d", &i, &j); //读入边(Vi, Vj)的顶点对应的序号

s = malloc(sizeof(struct node)); //生成边表节点

s->adjvex = j;

s->next = G->adjlist[i].firstedge;

G->adjlist[i].firstedge = s; //将新节点*s插入顶点Vi的边表头部

}

}





int main()

{

int i, j;

ALGraph G = malloc(sizeof(struct graph));

G->adjlist = (struct vnode *)malloc(sizeof(struct vnode) * MaxVertexNum);

CreatALGraph(G);



for (i = 1; i <= G->n; i++)

{

while (G->adjlist[i].firstedge)

{

printf("%d -> ", G->adjlist[i].vertex);

printf("%d\n", G->adjlist[i].firstedge->adjvex);

G->adjlist[i].firstedge = G->adjlist[i].firstedge->next;

}

}



return 0;

}
  1. 算法测试结果

    (说明测试数据,粘贴实验结果图

 

  1. 分析与总结

    (1)算法复杂度分析及优、缺点分析

        (说明你编写算法的复杂度,算法的优点和缺点有哪些

设图中有n个顶点,e条边,则用邻接表表示无向图时,需要n个顶点结点,2e个表结点;用邻接表表示有向图时,若不考虑逆邻接表,只需n个顶点结点,e个边结点。在无向图的邻接表中,顶点vi的度恰为第i个链表中的结点数。在有向图中,第i个链表中的结点个数只是顶点vi的出度。在逆邻接表中的第i个链表中的结点个数为vi的入度。建立邻接表的时间复杂度为O(n+e)

    (2)实验总结

        (说明你怎么解决实验中遇到的问题,有什么收获

通过这次实验让我熟悉图的数组表示法和邻接表存储结构,掌握构造有向图、无向图的算法 ,在掌握以上知识的基础上,熟悉图的深度优先遍历算法,并实现基本掌握邻接表的存储结构以及邻接表的建立和操作,但对构建邻接表的算法理解还不够,实验存在一些问题。在邻接表上容易找到任一顶点的一个邻接点和下一个邻接点,但要判断两个顶点(vi和vj)之间是否有边或弧相连,则需搜索需第i个或第j个链表,不及邻接矩阵方便。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值