数据结构实验六,七,八
- 格式:doc
- 大小:162.00 KB
- 文档页数:19
1
实验六 图的遍历
一、实验目的
1、熟悉图的各种存储结构及其构造算法
2、熟练掌握图的两种搜索路径的遍历:遍历的逻辑定义、深度优先搜索的两种形式(递归和非递归)和广度优先搜索的算法。
3、应用图的遍历算法求解各种简单路径问题。
4、理解教科书中讨论的各种图的算法。
二、实验预备知识
本实验的重点:深度优先搜索和广度优先搜索。
图的遍历:和树的遍历类似,图的遍历也是从某个顶点出发,沿着某条搜索路径对图中每个顶点各做一次且仅做一次访问。它是许多图的算法的基础。深度优先遍历和广度优先遍历是最为重要的两种遍历图的方法。它们对无向图和有向图均适用。
图的深度优先遍历:假设给定初始状态图G中的所有顶点均未曾访问过。在G中任选一顶点v出发,首先访问出发点v,并将其标记为已访问过,然后依次从v出发搜索v的每个邻接点。若该邻结点未曾访问过,则以该邻结点为新的出发点继续进行深度优先遍历,直至图中所有和点v有路径相通的顶点均已被访问为止。若此时图中仍有未访问的顶点,则另选一个尚未访问的顶点作为新的源点重复上述过程,直至图中所有顶点均被访问为止。
2
v1v2v3v4v5v6v7
(a)无向图 G
v1v2v3v4v5v6v7123456
(b)图G深度优先过程
深度优先遍历序列:v1→v2→v4→v5→v3→v6→v7
图的广度优先遍历:设初始状态图G中的所有顶点均未访问过。在G中任选一顶点v,首先访问出发点v,接着依次访问v的所有邻接点,然后再依次访问与邻接的所有未曾访问过的顶点,并使“先被访问的顶点的邻接点”先于“后被访问的顶点的邻接点”被访问。依此类推,直至图中所有和点v有路径相通的顶点都已访问到。若此时图中尚有顶点未被访问,则另选图中的一个未被访问的顶点作起始点,重复上述过程,直到图中所有顶点都被访问到为止。
3
v1v2v3v4v5v6v7v8v9
(c)无向图G
v1v2v3v4v5v6v7v8v912345678
(d)图G广度优先搜索过程
广度悠闲遍历序列:v1→v2→v3→v4→v5→v6→v7→v8→v9
三、实验要求
1、掌握图的遍历思想以及其特点。
2、选择程序上机进行调试找出问题、保存和打印出程序的运行结果。
3、上机学会运用图的思想解决实际问题。
4、课后尝试自己编写程序并上机运行得出结果。
4
深度遍历图,邻接表加递归
#include
#include
#include
#define MAX 100
typedef struct Linknode
{
int adjvex;
//int info;
struct Linknode *next;
}LinkNode;
typedef struct Vexnode
{
int vexdata;
LinkNode *first;
}VexNode;
typedef struct {
int vexnum;
VexNode adjlist[100];
}ALGraph;
ALGraph G;
int pre[MAX],path[MAX];
void create();
void print();
void DFS(int u,int v,int d);
void main()
{
create();
//print();
DFS(2,2,-1);
}
void create()
{
5
int i,tempi;
LinkNode *p,*q;
freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
scanf("%d",&G.vexnum);
//scanf("%c",&temp);
for(i=0;i
{
scanf("%d",&G.adjlist[i].vexdata);
G.adjlist[i].first=NULL;
//scanf("%c",&temp);
}
for(i=0;i
{
scanf("%d",&tempi);
while(tempi!=100)
{
p=(LinkNode *)malloc(sizeof(LinkNode));
p->adjvex=tempi;
q=G.adjlist[i].first;
G.adjlist[i].first=p;
p->next=q;
scanf("%d",&tempi);
}
}
}
void print()
{
int i;
LinkNode *p;
for(i=0;i
{
printf("%d\t",G.adjlist[i].vexdata);
p=G.adjlist[i].first;
while(p!=NULL)
{
printf("%d\t",p->adjvex);
p=p->next;
}
printf("\n");
}
}
6
void DFS(int u,int v,int d)
{
int i,temp;
LinkNode *p;
pre[u]=1;
d++;
path[d]=u;
p=G.adjlist[u].first;
if(u==v )
{
for(i=0;i<=d;i++)
printf("%d\t",path[i]);
printf("\n");
}
while(p!=NULL)
{
temp=p->adjvex;
if(pre[temp]==0)
{
DFS(temp,v,d);
}
p=p->next;
}
pre[u]=0;
d--;
}
void print_path(int pre[],int v)
{
if(pre[v]!=v)
print_path(pre,pre[v]);
printf("%d ",v);
}
7
实验七 最小生成树
一、实验目的
1、图的邻接矩阵、邻接表和边集数组表示。
2、掌握建立图的邻接矩阵的算法,由邻接矩阵转换为邻接表和边集数组的算法。
3、熟悉最小生成树的构造。
4、熟悉并掌握求图的最小生成树的普里姆算法克鲁斯卡尔算法。
二、实验预备知识
掌握图的概念、图的邻接矩阵表示法和邻接表表示法、图的深度和广度优先遍历、生成树和最小生成树、树的最短路径、拓扑排序。
有向图:若图G中的每条边都是有方向的,则称G为有向图。
无向图:若图G中的每条边都是没有方向的,则称G为无向图。
完全图:有1/2条边的图无向图称为完全图。恰有n(n-1)条边的有向图称为有向完全图,恰有n(n-1)/2条边的无向图称无向完全图。
连通图:图中G中任意两个顶点Vi、Vj∈V、Vi和Vj连通的,则G称为连通图。v1v2v3v4v5
度:顶点V的度是和V相关联的边的数目。
8
强连通图:在有向图G中,如果对于每一对Vi,Vj∈V、Vi、Vj,从Vi到Vj和从Vj到Vi都存在路径,则G是强连通图。v1v2v3
无向图的路径:在无向图G中,若存在一个顶点序列vp,vi1,vi2,…,vim,vq,使得(vp,vi1),(vi1,vi2),…,(vim,vq)均属于E(G),则称顶点vp到vq存在一条路径。
有向图的路径:在有向图G中,路径也是有向的,它由E(G)中的有向边,,…,组成。
路径长度:路径长度定义为该路径上边的数目。
子图:设G=(V,E)是一个图,若V'是V的子集,E'是E的子集,且E'中的边所关联的顶点均在V'中,则G'=(V',E')也是一个图,并称其为G的子图。
生成树:如果连通图G的一个子图是一棵包含G的所有顶点的树,则该子图称为G的生成树。
最小生成树:权最小的生成树称为G的最小生成树。
图中(b)、(c)、(d)都是生成树,权分别是:21、13、9。可以证明(d)为一棵最小生成树。
9
1234541239543 123454953
(a)带权图 (b )生成树
123452353 123451233
(c)生成树 (d)最小生成树
三、实验要求
1、认真阅读和掌握本实验的内容。
2、从实验本上选择一个程序上机调试。
3、得出正确的程序后,运行程序输入一个图形,保存和打印出程序运行的结果,并进行程序的性能分析。
4、请重新编写一个程序并上机进行调试,得出结果后总结出程序的特点。
最小生成树:prim
#include
#include
#include
#define MAX 100
typedef struct dege