邻接表存储图深度优先广度优先遍历
图的深度广度优先遍历操作代码
一、实验目的1.掌握图的各种存储结构,特别要熟练掌握邻接矩阵和邻接表存储结构;2.遍历是图各种应用的算法的基础,要熟练掌握图的深度优先遍历和宽度优先遍历算法,复习栈和队列的应用;3.掌握图的各种应用的算法:图的连通性、连通分量和最小生成树、拓扑排序、关键路径。
二、实验内容实验内容1**图的遍历[问题描述]许多涉及图上操作的算法都是以图的遍历为基础的。
写一个程序,演示在连通无向图上遍历全部顶点。
[基本要求]建立图的邻接表的存储结构,实现无向图的深度优先遍历和广度优先遍历。
以用户指定的顶点为起点,分别输出每种遍历下的顶点访问序列。
[实现提示]设图的顶点不超过30个,每个顶点用一个编号表示(如果一个图有N个顶点,则它们的编号分别为1,2,…,N)。
通过输入图的全部边输入一个图,每条边是两个顶点编号对,可以对边依附顶点编号的输入顺序作出限制(例如从小到大)。
[编程思路]首先图的创建,采用邻接表建立,逆向插入到单链表中,特别注意无向是对称插入结点,且要把输入的字符在顶点数组中定位(LocateVex(Graph G,char *name),以便后来的遍历操作,深度遍历算法采用递归调用,其中最主要的是NextAdjVex(Graph G, int v, int w);FirstAdjVex ()函数的书写,依次递归下去,广度遍历用队列的辅助。
[程序代码]头文件:#include<stdio.h>#include<stdlib.h>#define MAX_VERTEX_NUM 30#define MAX_QUEUE_NUMBER 30#define OK 1#define ERROR 0#define INFEASIBLE -1#define OVERFLOW -2#define TRUE 1#define FALSE 0typedef int Status;typedef int InfoType;typedef int Status;/* 定义弧的结构*/typedef struct ArcNode{int adjvex; /*该边所指向的顶点的位置*/ struct ArcNode *nextarc; /*指向下一条边的指针*/ InfoType info; /*该弧相关信息的指针*/}ArcNode;/*定义顶点的结构*/typedef struct VNode{char data[40]; /*顶点信息*/ArcNode *firstarc; /*指向第一条依附该顶点的弧的指针*/}VNode,AdjList[MAX_VERTEX_NUM];/*定义图的结构*/typedef struct {AdjList vertices;int vexnum,arcnum; /*图的当前顶点数和弧数*/int kind; /*图的类型标志*/}Graph;/*定义队列的结构*/typedef struct{int *elem;int front, rear;}Queue;/*功能选择*/void MenuSelect(int w);/*顶点定位*/int LocateVex(Graph G,char *name);/*创建无向图*/void CreateGraph(Graph &G);/*求第一个顶点*/int FirstAdjVex(Graph G, int v);/*求下一个顶点*/int NextAdjVex(Graph G, int v, int w);/*深度递归*/void DFS(Graph G, int v) ;/*深度遍历*/void DFSTravel(Graph G,int v);/*广度遍历*/void BFSTraverse(Graph G,char *name);/*初始化队列*/Status InitQueue(Queue &Q);/*判空*/Status EmptyQueue(Queue Q);/*进队*/Status EnQueue(Queue &Q, int e);/*出队*/Status DeQueue(Queue &Q, int &e);实现文件:#include <stdio.h>#include"malloc.h"#include "tuhead.h"#include "stdlib.h"#include "string.h"bool visited[MAX_VERTEX_NUM];/************************************************************ 顶点定位************************************************************/int LocateVex(Graph G,char *name){int i;for(i=1;i<=G.vexnum;i++) //从1号位置开始存储if(strcmp(name,G.vertices[i].data)==0) //相等则找到,返回位序return i;return -1;}/************************************************************ 创建无向图************************************************************/void CreateGraph(Graph &G){ArcNode *p;char name1[10],name2[10];int i,j,k;printf(" 请输入顶点数,按回车键结束:");scanf("%d",&G.vexnum);printf(" 请输入弧数,按回车键结束:");scanf("%d",&G.arcnum);printf(" 请依次输入顶点名(用空格分开且字符小于10),按回车键结束:\n");printf(" ");for(i=1;i<=G.vexnum;i++) //从1号位置开始存储{scanf("%s",G.vertices[i].data); //从一号位置开始初始化G.vertices[i].firstarc=NULL;}printf("\n\n\n\n");printf(" ………………………………………输入小提示………………………………………\n");printf(" &&&&1 为避免输入遗漏,最好从选择任意一点,输入所有相邻边\n");printf(" &&&&2 输入边时格式(用空格分开,即格式为顶点(空格)顶点(空格))\n");printf(" ………………………………………输入小提示………………………………………\n\n\n\n");for(k=0;k<G.arcnum;k++){printf("请输入相邻的两个顶点,按回车键结束:");scanf("%s%s",name1,name2);i=LocateVex(G,name1); //返回位序j=LocateVex(G,name2);p=(ArcNode *)malloc(sizeof(ArcNode)); //申请边节点p->adjvex=j; //插入到邻接表中,注意此处为逆向插入到单链表中p->nextarc=G.vertices[i].firstarc;G.vertices[i].firstarc=p;//无向图,注意是对称插入结点p=(ArcNode *)malloc(sizeof(ArcNode));p->adjvex=i;p->nextarc=G.vertices[j].firstarc;G.vertices[j].firstarc=p;}}/************************************************************ 求第一个顶点************************************************************/int FirstAdjVex(Graph G, int v){ArcNode *p;if(v>=1 && v<=G.vexnum){p=G.vertices[v].firstarc;if(p->nextarc==NULL)return 0;elsereturn (p->nextarc->adjvex); //返回第一个顶点字符}return -1;}/************************************************************ 求下一个顶点************************************************************/int NextAdjVex(Graph G, int v, int w){ //在图G中寻找第v个顶点的相对于w的下一个邻接顶点ArcNode *p;if(v>=1 && v<=G.vexnum && w>=1 && w<=G.vexnum){p=G.vertices[v].firstarc;while(p->adjvex!=w)p=p->nextarc; //在顶点v的弧链中找到顶点wif(p->nextarc!=NULL)return 0; //若已是最后一个顶点,返回0 elsereturn(p->nextarc->adjvex); //返回下一个邻接顶点的序号}return -1;}/************************************************************ 深度递归************************************************************/void DFS(Graph G, int v){int w;ArcNode *p;visited[v]=1;printf("%s ",G.vertices[v].data); //访问第v个顶点p=G.vertices[v].firstarc; //p为依附顶点的第一条边while (p!=NULL){w=p->adjvex;if(visited[w]==0)DFS(G,w);p=p->nextarc; //下移指针}}/************************************************************ 深度遍历************************************************************/void DFSTravel(Graph G,int v){for(int i=1;i<=G.vexnum;i++)visited[i]=0;int w;ArcNode *p;visited[v]=1;printf("%s ",G.vertices[v].data); //访问第v个顶点p=G.vertices[v].firstarc;while (p!=NULL){w=p->adjvex;if(visited[w]==0)DFS(G,w);p=p->nextarc;}}/************************************************************ 初始化队列************************************************************/Status InitQueue(Queue &Q){Q.elem = new int[MAX_QUEUE_NUMBER];Q.front = Q.rear = 0;return OK;}Status EmptyQueue(Queue Q){if(Q.front==Q.rear)return 0;elsereturn 1;}/*********************************************************** * 进队列* ***********************************************************/ Status EnQueue(Queue &Q, int e){if((Q.rear + 1)%MAX_QUEUE_NUMBER != Q.front)Q.elem[Q.rear ] = e;else ;Q.rear = (Q.rear + 1)%MAX_QUEUE_NUMBER;return OK;}/*********************************************************** * 出队列* ***********************************************************/ Status DeQueue(Queue &Q, int &e){if(Q.rear != Q.front)e = Q.elem[Q.front];else ;Q.front = (Q.front+1)%MAX_QUEUE_NUMBER;return OK;}/*********************************************************** * 广度遍历************************************************************/void BFSTraverse(Graph G,char *name){ArcNode *p;int v,w,u,k=0;Queue Q;int visited[20];for(v=1;v<=G.vexnum;v++) //初始化visited[v]=0;InitQueue(Q);for(v=LocateVex(G,name);k!=2;v=(v+1)%(G.vexnum-1)) //v为输入的字符转化的位序{if(v+1==LocateVex(G,name)) //从v开始走完图的所有顶点k++;if(visited[v]==0){visited[v]=1;printf("%s ",G.vertices[v].data); //访问第v个顶点EnQueue(Q,v); // 进队while(EmptyQueue(Q)!=0){DeQueue(Q,u); //出队p=G.vertices[u].firstarc;while(p!=NULL){w=p->adjvex; //p边的下一个顶点if(visited[w]==0){printf("%s ",G.vertices[w].data);visited[w]=1;EnQueue(Q,w);}p=p->nextarc; //下移指针}}}}}主文件:#include <stdio.h>#include"malloc.h"#include "tuhead.h"#include "stdlib.h"#include "string.h"/************************************************************ 界面控制************************************************************/void main(){printf("\n################################# 图的遍历#################################\n");printf("\n $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n");printf("\n");printf(" 1 ------- 图的创建\n");printf(" 2 ------- 图的深度优先遍历\n");printf(" 3 ------- 图的广度优先遍历\n");printf(" 0 ------- 退出\n");printf("\n $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n");printf("\n");printf("请输入选择的操作代码(0-3)按回车键结束\n");MenuSelect(1);}/************************************************************ 功能选择************************************************************/void MenuSelect(int w){int select,done;int v;Graph G; char name[10];while (done) {printf("input the operating code : ");scanf("%d",&select);switch(select){case 1: printf("根据要求创建图:\n ");CreateGraph(G);break;case 2: printf("请输入深度优先遍历开始点的名:");scanf("%s",name);v=LocateVex(G,name); //将输入字符找到在顶点数组name对应的序号Vprintf("深度优先遍历:");DFSTravel(G,v);printf("\n");break;case 3: printf("请输入广度优先遍历开始点的名:");scanf("%s",name);printf("广度优先遍历:");BFSTraverse(G,name);printf("\n");break;case 0: done=0; break;default: printf(" ERROR\n");}printf("\n");}}[实验数据与结果]测试数据:实验结果。
采用邻接表存储结构实现图的广度优先遍历。
精心整理课程设计题目九:图的广度优先遍历基本要求:采用邻接表存储结构实现图的广度优先遍历。
(2)对任意给定的图(顶点数和边数自定),建立它的邻接表并输出;(3)实现图的广度优先遍历*/#include<iostream.h>#include<stdio.h>#include<malloc.h>#defineMAX_NUM20intvisited[MAX_NUM]={0};typedefintVertexType;typedefenum{DG=1,UDG}GraphKind;typedefstructArcNode{intadjvex;intweight;structArcNode*nextarc;ArcNode*info;}ArcNode;typedefstructVNode{VertexTypedata;ArcNode*firstarc;}VNode,AdjList[MAX_NUM];typedefstruct{AdjListvertices;intvexnum,arcnum;GraphKindkind;}ALGraph;voidPRIN(ALGraph&G);voidCreat_adjgraph(ALGraph&G);voidbfs(ALGraph&G,intv);voidCreat_adjgraphDG(ALGraph&G);voidCreat_adjgraphUDG(ALGraph&G);voidCreat_adjgraph(ALGraph&G);voidCreat_adjgraphDG(ALGraph&G){inti,s,d;ArcNode*p=NULL,*q=NULL;G.kind=DG;printf("请输入顶点数和边数:");scanf("%d%d",&G.vexnum,&G.arcnum);for(i=0;i<G.vexnum;++i){printf("第%d个顶点信息:",i+1);scanf("%d",&G.vertices[i].data);G.vertices[i].firstarc=NULL;}for(i=0;i<G.arcnum;++i){printf("第%d条边的起始顶点编号和终止顶点编号:",i+1);scanf("%d%d",&s,&d);while(s<1||s>G.vexnum||d<1||d>G.vexnum){printf("编号超出范围,重新输入");scanf("%d%d",&s,&d);}s--;d--;p=new(ArcNode);p->adjvex=d;p->nextarc=G.vertices[s].firstarc;G.vertices[s].firstarc=p;}}voidCreat_adjgraphUDG(ALGraph&G){inti,s,d;ArcNode*p,*q;G.kind=UDG;printf("请输入顶点数和边数:");scanf("%d%d",&G.vexnum,&G.arcnum);for(i=0;i<G.vexnum;++i){printf("第%d个顶点信息:",i+1);scanf("%d",&G.vertices[i].data);G.vertices[i].firstarc=NULL;}for(i=0;i<G.arcnum;++i){printf("第%d条边的起始顶点编号和终止顶点编号:",i+1);scanf("%d%d",&s,&d);while(s<1||s>G.vexnum||d<1||d>G.vexnum){printf("编号超出范围,重新输入");scanf("%d%d",&s,&d);}s--;d--;p=new(ArcNode);p->adjvex=d;p->nextarc=G.vertices[s].firstarc;G.vertices[s].firstarc=p;q=new(ArcNode);q->adjvex=s;q->nextarc=G.vertices[d].firstarc;G.vertices[d].firstarc=q;}}voidPRIN(ALGraph&G){inti;ArcNode*p;if(G.kind==DG||G.kind==UDG){for(i=0;i<G.vexnum;++i){printf("V%d:",G.vertices[i].data);p=G.vertices[i].firstarc;while(p!=NULL){printf("%d\t",p->adjvex+1);p=p->nextarc;}printf("\n");}}}voidbfs(ALGraph&G,intv){v--;ArcNode*p;intqueue[MAX_NUM],front=0,rear=0;intw,i;for(i=0;i<G.vexnum;i++)visited[i]=0;printf("%4d",v+1);visited[v]=1;rear=(rear+1)%MAX_NUM;queue[rear]=v;while(front!=rear){front=(front+1)%MAX_NUM;w=queue[front];p=G.vertices[w].firstarc;while(p!=NULL){if(visited[p->adjvex]==0){printf("%3d",p->adjvex+1);visited[p->adjvex]=1;rear=(rear+1)%MAX_NUM;queue[rear]=p->adjvex;}p=p->nextarc;}}printf("\n");}voidCreat_adjgraph(ALGraph&G){printf("1:有向图2:无向图\n");printf("请根据上述提示输入图的类型:");scanf("%d",&G.kind);switch(G.kind){caseDG:Creat_adjgraphDG(G);PRIN(G);break;caseUDG:Creat_adjgraphUDG(G);PRIN(G);break;default:printf("ERROR");break;}}voidmain(){ALGraphG;Creat_adjgraph(G);printf("\n");printf("广度优先搜索遍历序列为:\n");bfs(G,1);printf("\n");}。
北邮数据结构第六章答案详解 图(1)
1
5
1
54 3
42
5 66
图 6-8 图 G 答案:根据不同算法构造的最小生成树如图 6-9 所示的图(a)和(b)
2
④
⑤ 5
1
①
4 3
②
③
6
2
⑤
③ 5
1
①
4 3
④
②
6
(a) Prim 生成树
(b) Kruskal 生成树
图 6-9 最小生成树
5、算法设计
(1)以邻接表为存储结构,设计实现深度优先遍历的非递归算法。
int top = -1; cout<<v<<’\t’; bVisited[v] = true; stack[++top] = v;
//访问结点 v //设置访问标记 //结点 v 入栈
while (top!=-1)
{
v=stack[top];
ArcNode<T> *p = adjlist[v]. firstarc; ①
)
A.1
B. n/2
C.n-1
D.n
解析:若超过 n-1,则路径中必存在重复的顶点
答案:C
(5) 若一个图中包含有 k 个连通分量,若按照深度优先搜索的方法访问所有顶点,则必
须调用(
)次深度优先搜索遍历的算法。
A.k
B.1
C.k-1
D.k+1
解析:一次深度优先搜索可以访问一个连通分量中的所有结点,因此 k 个连通分量需要 调用 k 次深度优先遍历算法。
④
} if (p==NULL) top--;
⑤//若是找不到未访问的结点,出栈
深度与广度优先搜索:迷宫问题
《数据结构课程设计》报告题目:深度与广度优先搜索--迷宫问题专业计算机科学与技术学生姓名李柏班级B计算机115学号1110704512指导教师巩永旺完成日期2013年1月11日目录1简介 (1)2算法说明 (1)3测试结果 (3)4分析与探讨 (7)5小结 (9)附录 (10)附录1 源程序清单 (10)迷宫问题1 简介1、图的存储结构图的存储结构又称图的表示,其最常用的方法是邻接矩阵和邻接表。
无论采用什么存储方式,其目标总是相同的,既不仅要存储图中各个顶点的信息,同时还要存储顶点之间的所有关系。
2、图的遍历图的遍历就是从指定的某个顶点(称其为初始点)出发,按照一定的搜索方法对图中的所有顶点各做一次访问过程。
根据搜索方法不同,遍历一般分为深度优先搜索遍历和广度优先搜索遍历。
本实验中用到的是广度优先搜索遍历。
即首先访问初始点v i,并将其标记为已访问过,接着访问v i的所有未被访问过的邻接点,顺序任意,并均标记为已访问过,以此类推,直到图中所有和初始点v i有路径相通的顶点都被访问过为止。
鉴于广度优先搜索是将所有路径同时按照顺序遍历,直到遍历出迷宫出口,生成的路径为最短路径。
因此我们采用了广度优先搜索。
无论是深度优先搜索还是广度优先搜索,其本质都是将图的二维顶点结构线性化的过程,并将当前顶点相邻的未被访问的顶点作为下一个顶点。
广度优先搜索采用队列作为数据结构。
本实验的目的是设计一个程序,实现手动或者自动生成一个n×m矩阵的迷宫,寻找一条从入口点到出口点的通路。
具体实验内容如下:选择手动或者自动生成一个n×m的迷宫,将迷宫的左上角作入口,右下角作出口,设“0”为通路,“1”为墙,即无法穿越。
假设一只老鼠从起点出发,目的为右下角终点,可向“上、下、左、右、左上、左下、右上、右下”8个方向行走。
如果迷宫可以走通,则用“■”代表“1”,用“□”代表“0”,用“☆”代表行走迷宫的路径。
输出迷宫原型图、迷宫路线图以及迷宫行走路径。
计算机专业(基础综合)模拟试卷152(题后含答案及解析)
计算机专业(基础综合)模拟试卷152(题后含答案及解析)题型有:1. 单项选择题 2. 综合应用题单项选择题1-40小题,每小题2分,共80分。
下列每题给出的四个选项中,只有一个选项是最符合题目要求的。
1.采用邻接表存储的图的广度优先遍历算法类似于树的( )。
A.中根遍历B.先根遍历C.后根遍历D.按层次遍历正确答案:D解析:图的深度优先遍历类似于树的先序遍历;图的广度优先遍历类似于树的层次遍历。
2.图1-1中强连通分量的个数为( )。
A.2B.3C.4D.5正确答案:C解析:在有向图G中,如果两个顶点vi、vj间有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通。
如果有向图G的每两个顶点都强连通,称G是一个强连通图。
有向图的极大强连通子图,称为强连通分量。
本题中可以看出v2、v3、v4同属于一个连通分量,另外v1、v5、v6各自属于一个强连通分量,所以共有4个强连通分量。
3.在计算机中,微程序一般存放在( )。
A.主存储器B.存储器控制器C.控制存储器D.辅助存储器正确答案:C解析:微程序存放在控制存储器中,选C。
注意存控与控存的区别,控存是用来存放微程序,而存控是用来管理协调CPU、DMA控制器等对主存储器访问的部件。
4.在I/O设备控制的发展过程中,最主要的推动因素是( )。
A.提高资源利用率B.提高系统吞吐量C.提高I/O设备与CPU的并行操作程度D.减少主机对I/O控制的干预正确答案:D5.已知循环冗余码生成多项式G(x)=x5+x4+x+1,若信息位为10101100,则冗余码是( )。
A.1101B.1100C.1101D.1100正确答案:B解析:(1)确定生成多项式G(x)=x5+x4+x+1,次数F5,对应位串110011。
(2)在信息位串后补5个0即10101100 00000,对应的多项式xrM(x),(3)用模2不借位除法,计算xrM(x)/G(x)的余数R(x),R(x)就是冗余码。
图的各种算法(深度、广度等)
vex next 4 p
3
2 ^
2
^
5
5 5 4 3 2 1 0 ^
^
4 ^
top
4
输出序列:6 1
1 2 3 4 5 6
in link 0 2 ^ 1 0 2 0
vex next 4 p
3
2 ^
2
^
5
5 5 4 3 2 1 0 ^
^
4 ^
top 4
输出序列:6 1
1 2 3 4 5 6
in link 0 2 ^ 1 0 2 0
c a g b h f d e
a
b h c d g f
e
在算法中需要用定量的描述替代定性的概念
没有前驱的顶点 入度为零的顶点 删除顶点及以它为尾的弧 弧头顶点的入度减1
算法实现
以邻接表作存储结构 把邻接表中所有入度为0的顶点进栈 栈非空时,输出栈顶元素Vj并退栈;在邻接表中查找 Vj的直接后继Vk,把Vk的入度减1;若Vk的入度为0 则进栈 重复上述操作直至栈空为止。若栈空时输出的顶点个 数不是n,则有向图有环;否则,拓扑排序完毕
^
4
^
top
输出序列:6 1 3 2 4
1 2 3 4 5 6
in link 0 0 ^ 0 0 0 0
vex next 4
3
2 ^
2
^
5
5 5 4 3 2 1 0 ^ p
^
4
^topBiblioteka 5输出序列:6 1 3 2 4
1 2 3 4 5 6
in link 0 0 ^ 0 0 0 0
vex next 4
w2 w1 V w7 w6 w3
算法设计:深度优先遍历和广度优先遍历
算法设计:深度优先遍历和广度优先遍历实现深度优先遍历过程1、图的遍历和树的遍历类似,图的遍历也是从某个顶点出发,沿着某条搜索路径对图中每个顶点各做一次且仅做一次访问。
它是许多图的算法的基础。
深度优先遍历和广度优先遍历是最为重要的两种遍历图的方法。
它们对无向图和有向图均适用。
注意:以下假定遍历过程中访问顶点的操作是简单地输出顶点。
2、布尔向量visited[0..n-1]的设置图中任一顶点都可能和其它顶点相邻接。
在访问了某顶点之后,又可能顺着某条回路又回到了该顶点。
为了避免重复访问同一个顶点,必须记住每个已访问的顶点。
为此,可设一布尔向量visited[0..n-1],其初值为假,一旦访问了顶点Vi之后,便将visited[i]置为真。
--------------------------深度优先遍历(Depth-First Traversal)1.图的深度优先遍历的递归定义假设给定图G的初态是所有顶点均未曾访问过。
在G中任选一顶点v为初始出发点(源点),则深度优先遍历可定义如下:首先访问出发点v,并将其标记为已访问过;然后依次从v出发搜索v的每个邻接点w。
若w未曾访问过,则以w为新的出发点继续进行深度优先遍历,直至图中所有和源点v有路径相通的顶点(亦称为从源点可达的顶点)均已被访问为止。
若此时图中仍有未访问的顶点,则另选一个尚未访问的顶点作为新的源点重复上述过程,直至图中所有顶点均已被访问为止。
图的深度优先遍历类似于树的前序遍历。
采用的搜索方法的特点是尽可能先对纵深方向进行搜索。
这种搜索方法称为深度优先搜索(Depth-First Search)。
相应地,用此方法遍历图就很自然地称之为图的深度优先遍历。
2、深度优先搜索的过程设x是当前被访问顶点,在对x做过访问标记后,选择一条从x出发的未检测过的边(x,y)。
若发现顶点y已访问过,则重新选择另一条从x出发的未检测过的边,否则沿边(x,y)到达未曾访问过的y,对y访问并将其标记为已访问过;然后从y开始搜索,直到搜索完从y出发的所有路径,即访问完所有从y出发可达的顶点之后,才回溯到顶点x,并且再选择一条从x出发的未检测过的边。
深度优先搜索和广度优先搜索-Read
7.1 图的定义和术语
1.图的定义 定义:图(Graph)是由非空的顶点集合和一个描述顶
点之间关系(边或者弧)的集合组成。 其二元组定义为: G=(V,E) V={vi| vi∈DataObject} E={(vi,vj)| vi, vj ∈V∧P(vi, vj)} 其中,G表示一个图,V是图G中顶点的集合,E是图G
为强连通分量。
V0
V1
V0
V1
V2Biblioteka V3强连通图G1V2
V3
非强连通图G2
V1 V0
V2
V3
G2的两个强连 通分量
生成树、生成森林
所谓连通图G的生成树,是G的包含其全部n 个顶点的 一个极小连通子图。它必定包含且仅包含G的n-1条边。
极小连通子图意思是:该子图是G 的连通子图,在该 子图中删除任何一条边,子图不再连通。
否则称为非连通图。
无向图中,极大的连通子图为该图的连通分量。显然,
任何连通图的连通分量只有一个,即它本身,而非连通图有
多个连通分量。
V0
V1
G2的两个
连通分量
V0
V1 V4
V2
V3
V4
V3
V2 V5
连通图G1
非连通图G2
强连通图、强连通分量
对于有向图来说,若图中任意一对顶点vi 和vj(i≠j) 均有从一个顶点vi到另一个顶点vj有路径,也有从vj到vi的路 径,则称该有向图是强连通图。有向图的极大强连通子图称
G1=<V1, E1>
V1={v0, v1, v2, v3, v4 } E1={(v0, v1), (v0, v3), (v1, v2), (v1, v4), (v2, v3), (v2, v4)}
数据结构习题及参考答案
数据结构习题及参考答案部门: xxx时间: xxx整理范文,仅供参考,可下载自行编辑数据结构习题及参考答案一、判断下列叙述的对错。
<1)线性表的逻辑顺序与物理顺序总是一致的。
<2)线性表的顺序存储表示优于链式存储表示。
<3)线性表若采用链式存储表示时所有结点之间的存储单元地址可连续可不连续。
<4)二维数组是其数组元素为线性表的线性表。
<5)每种数据结构都应具备三种基本运算:插入、删除和搜索。
二、设单链表中结点的结构为typedef struct node { file://链表结点定义ElemType data; file://数据struct node * Link; file://结点后继指针} ListNode;<1)已知指针p所指结点不是尾结点,若在*p之后插入结点* s,则应执行下列哪一个操作?A. s->link = p; p->link = s;B. s->link = p->link; p->link = s;C. s->link = p->link; p = s;D. p->link = s; s->link = p;<2)非空的循环单链表first的尾结点<由p所指向)满足:A. p->link == NULL;B. p == NULL;C. p->link == first;D. p == first;三、设有一个顺序栈S,元素s1, s2, s3, s4, s5, s6依次进栈,如果6个元素的出栈顺序为s2, s3, s4, s6, s5, s1,则顺序栈的容量至少应为多少?b5E2RGbCAP四、一棵具有n个结点的理想平衡二叉树<即除离根最远的最底层外其他各层都是满的,最底层有若干结点)有多少层?若设根结点在第0层,则树的高度h如何用n来表示<注意n可能为0)?p1 EanqFDPw五、从供选择的答案中选择与下面有关图的叙述中各括号相匹配的词句,将其编号填入相应的括号内。
浅析深度优先和广度优先遍历实现过程、区别及使用场景
浅析深度优先和⼴度优先遍历实现过程、区别及使⽤场景⼀、什么是深度/⼴度优先遍历? 深度优先遍历简称DFS(Depth First Search),⼴度优先遍历简称BFS(Breadth First Search),它们是遍历图当中所有顶点的两种⽅式。
这两种遍历⽅式有什么不同呢?我们来举个栗⼦: 我们来到⼀个游乐场,游乐场⾥有11个景点。
我们从景点0开始,要玩遍游乐场的所有景点,可以有什么样的游玩次序呢?1、深度优先遍历 第⼀种是⼀头扎到底的玩法。
我们选择⼀条⽀路,尽可能不断地深⼊,如果遇到死路就往回退,回退过程中如果遇到没探索过的⽀路,就进⼊该⽀路继续深⼊。
在图中,我们⾸先选择景点1的这条路,继续深⼊到景点7、景点8,终于发现⾛不动了: 于是,我们退回到景点7,然后探索景点10,⼜⾛到了死胡同。
于是,退回到景点1,探索景点9: 按照这个思路,我们再退回到景点0,后续依次探索景点2、3、5、4、发现相邻的都玩过了,再回退到3,再接着玩6,终于玩遍了整个游乐场: 具体次序如下图,景点旁边的数字代表探索次序。
当然还可以有别的排法。
像这样先深⼊探索,⾛到头再回退寻找其他出路的遍历⽅式,就叫做深度优先遍历(DFS)。
这⽅式看起来很像⼆叉树的前序遍历。
没错,其实⼆叉树的前序、中序、后序遍历,本质上也可以认为是深度优先遍历。
2、⼴度优先遍历 除了像深度优先遍历这样⼀头扎到底的玩法以外,我们还有另⼀种玩法:⾸先把起点相邻的⼏个景点玩遍,然后去玩距离起点稍远⼀些(隔⼀层)的景点,然后再去玩距离起点更远⼀些(隔两层)的景点… 在图中,我们⾸先探索景点0的相邻景点1、2、3、4: 接着,我们探索与景点0相隔⼀层的景点7、9、5、6: 最后,我们探索与景点0相隔两层的景点8、10: 像这样⼀层⼀层由内⽽外的遍历⽅式,就叫做⼴度优先遍历(BFS)。
这⽅式看起来很像⼆叉树的层序遍历。
没错,其实⼆叉树的层序遍历,本质上也可以认为是⼴度优先遍历。
数据结构-图的存储结构的建立与搜索
实验报告课程名称:数据结构与算法课程类型:必修实验项目:图型结构及应用实验题目:图的存储结构的建立与搜索一、实验目的1.了解图的两种存储方式:邻接矩阵和邻接表。
2.掌握邻接矩阵和邻接表的建立算法。
3.掌握图的深度优先搜索和广度优先搜索算法。
4.更加熟练文件的相关操作。
二、实验要求及实验环境实验要求:1.分别实现图的邻接矩阵、邻接表存储结构的建立算法,分析和比较各建立算法的时间复杂度以及存储结构的空间占用情况;2.实现图的邻接矩阵、邻接表两种存储结构的相互转换算法;3.在上述两种存储结构上,分别实现图的深度优先搜索(递归和非递归)和广度优先搜索算法。
并以适当的方式存储和显示相应的搜索结果(深度优先或广度优先生成森林(或生成树)、深度优先或广度优先序列和编号);4.分析搜索算法的时间复杂度;5.以文件形式输入图的顶点和边,并显示相应的结果。
要求顶点不少于10个,边不少于13个;6.软件功能结构安排合理,界面友好,便于使用。
实验环境:codeblocks/Dev-C++三、设计思想(本程序中的用到的所有数据抽象数据性ADT的定义,主程序的流程图及各程序模块之间的调用关系)1. 所用的抽象数据性ADT的定义1)逻辑结构:栈:是一种特殊形式的线性表,所有的插入和删除操作都在栈顶。
栈的置空操作:void makenull(stack* s)判断栈是否为空:int empty(stack* s)返回栈顶元素:btree* top(stack* s)入栈操作:void push(btree* x, stack* s)出栈操作:void pop(stack* s)队列:是一种特殊形式的线性表,队尾入队,队首出队。
将队列置空:void makenull_q(queue* duilie)在队列后面插入T:void enqueue_q(btree* T, queue* duilie)判断队列是否为空:int empty_q(queue* duilie)返回队列的第一个元素:btree* front_q(queue* duilie)删除队列的第一个元素:void dequeue_q(queue* duilie)2) 存储结构:定义了一个邻接矩阵结构体mtgraph,一个边表节点结构体edgenode,一个顶点表结点结构体vertexnode,一个邻接表结构体adjgraph,一个栈结构体stack,一个队列节点结构体node2,一个队列结构体queue,邻接表先深递归访问标记数组visited_1[20],邻接表先深递归顶点的先深标号数组dfn_1[20],邻接矩阵先深递归访问标记数组visited_2[20],邻接矩阵先深递归顶点的先深标号数组dfn_2[20],邻接表先深非递归访问标记数组visited_5[20],邻接表先深非递归顶点的先深标号数组dfn_5[20],邻接矩阵先深非递归访问标记数组visited_6[20],邻接矩阵先深非递归顶点的先深标号数组dfn_6[20],邻接表先广访问标记数组visited_3[20],邻接表先广顶点的先深标号数组dfn_3[20],邻接矩阵先广访问标记数组visited_4[20],邻接矩阵先广顶点的先深标号数组dfn_4[20]。
计算机专业(基础综合)-试卷1
计算机专业(基础综合)-试卷1(总分:104.00,做题时间:90分钟)一、单项选择题(总题数:41,分数:82.00)1.单项选择题1-40小题。
下列每题给出的四个选项中,只有一个选项是最符合题目要求的。
__________________________________________________________________________________________2.堆的逻辑结构是( )。
A.线性结构B.树形结构√C.网状结构D.数组堆是一种经过排序的树形数据结构,每个结点都有一个值。
通常我们所说的堆是指二叉堆。
堆的特点是根结点的值最小(或最大),且根结点的两个子树也是一个堆。
3.循环队列用数组A[0,1…m一1]存放其元素值,已知其头尾指针分别为front,rear,则其队列元素个数为( )。
A.(rear一front+m)%m √B.rear一front+1C.rear一frontD.front一rear数组下标从0开始共m个元素,故队列元素个数=(rear—front+m)%m。
4.设森林M中有三棵树,它们结点个数分别为N1,N2,N3,与森林相对应的二叉树上,根结点的右子树上的结点个数为( )。
A.N1B.NI+N2C.N3D.N2+N3 √由森林和二叉树的转换关系可知,森林中第一棵树的根结点转换为二叉树的根结点、其他结点变为二叉树的根结点的左子树上的结点,森林中第二和第三棵树全部构成二叉树根结点的右子树,故知根结点的右子树上的结点个数为N2+N3;故选D。
5.采用邻接表存储的图的广度优先遍历算法类似于树的( )。
A.中根遍历B.先根遍历C.后根遍历D.按层次遍历√图的深度优先遍历类似于树的先序遍历;图的广度优先遍历类似于树的层次遍历。
6.已知一棵完全二叉树的第6层(设根为第1层)有8个叶结点,则完全二叉树的结点个数最多是( )。
A.39B.52C.111 √D.119第6层满时第6层共有32个结点,当第六层的最后8个结点为叶结点,其余24个结点为非叶结点时完全二叉树结点总数达最多,此时共有1+2+4+8+16+32+48=111个结点;故选C。
基于邻接表存储结构的遍历策略探讨
G > e n m n/顶 点向量 中的结点 -vx u = : / 弧尾 , 弧表 中存放弧头
( 即单链 表头结点) 作
s a f& ,j: c n (i&)∥输入 弧, 即弧 的头尾端点 户约定如果某 次输 入的弧尾是0 表 示弧 已经全部输入完 ,
基于邻接表存储结构的遍历策略探讨 计析 设分・
李 亮 梅 松。 . (武汉大学 管理 1 信息 学院 湖北 武汉 407;. 湖北省委党 , 30 2 2 中共 校信息网 心 湖北 武汉 40 2 络中 , 30 ) 2
摘 要 : 图结 构是 最常用 的非缌 数据 结构 之一, 图的遍历是其 上的基 础操 作 。 论文首先 阐述 了图的邻接 表存 储 方式的 实现 算法, 然后 分析
f r( = . e [] f r t d e w: = 一 n x ) i o w G v x v . i e g : w w > e t f s s
fr (= : n i+∥初 始化顶 点数组 , 是当前 图中顶点 的 o i0 i : ) : < + n 个数
(c n (G >e si.a a :G >e si.i s a c N L : s a f& -v x [ d t ) - vx [ fr t r = U L) , ] ]
21邻接表存ห้องสมุดไป่ตู้方式创建有向图的算法 .
i t A jr a eA O a h G n dC e t (1r p )
有路径相通的项点都被访问完为止。 {-v x =V x o e m lo (a n d * i e fVx o e) 至 图中所有与v G >e s (e N d a lcm x o e s z o (e N d ) 为了便于在算法 中区分顶点是否 已被访 问过 , 需要创建一 : ∥分配 空间. m x o e . a n d 是最多能容纳 的顶点个数 , 在程 序运行 个 一维数 组v st dn n i ie []( 是图中顶点 的数 目) 用来设置访 问 , 时由用户输入
图的遍历实验报告
实验四:图的遍历题目:图及其应用——图的遍历班级:姓名:学号:完成日期:一.需求分析1.问题描述:很多涉及图上操作的算法都是以图的遍历操作为基础的。
试写一个程序,演示在连通的无向图上访问全部结点的操作。
2.基本要求:以邻接表为存储结构,实现连通无向图的深度优先和广度优先遍历。
以用户指定的结点为起点,分别输出每种遍历下的结点访问序列和相应生成树的边集。
3.测试数据:教科书图7.33。
暂时忽略里程,起点为北京。
4.实现提示:设图的结点不超过30个,每个结点用一个编号表示(如果一个图有n个结点,则它们的编号分别为1,2,…,n)。
通过输入图的全部边输入一个图,每个边为一个数对,可以对边的输入顺序作出某种限制,注意,生成树的边是有向边,端点顺序不能颠倒。
5.选作内容:(1).借助于栈类型(自己定义和实现),用非递归算法实现深度优先遍历。
(2).以邻接表为存储结构,建立深度优先生成树和广度优先生成树,再按凹入表或树形打印生成树。
二.概要设计1.为实现上述功能,需要有一个图的抽象数据类型。
该抽象数据类型的定义为:ADT Graph{数据对象V:V是具有相同特性的数据元素的集合,称为顶点集。
数据关系R:R={VR}VR={<v,w> | v,w v且P(v,w),<v,w>表示从v到w得弧,谓词P(v,w)定义了弧<v,w>的意义或信息}} ADT Graph2.此抽象数据类型中的一些常量如下:#define TRUE 1#define FALSE 0#define OK 1#define max_n 20 //最大顶点数typedef char VertexType[20];typedef enum{DG, DN, AG, AN} GraphKind;enum BOOL{False,True};3.树的结构体类型如下所示:typedef struct{ //弧结点与矩阵的类型int adj; //VRType为弧的类型。
图的遍历深度优先遍历和广度优先遍历
4
5
f
^
对应的邻接表
终点2作为下次的始点, 由于1点已访问过,跳过, 找到4,记标识,送输出, 4有作为新的始点重复上 述过程
1 2 4
5
输出数组 resu
3.邻接表深度优先遍历的实现
template <class TElem, class TEdgeElem>long DFS2(TGraphNodeAL<TElem, TEdgeElem> *nodes,long n,long v0, char *visited, long *resu,long &top) {//深度优先遍历用邻接表表示的图。nodes是邻接表的头数组,n 为结点个数(编号为0~n)。 //v0为遍历的起点。返回实际遍历到的结点的数目。 //visited是访问标志数组,调用本函数前,应为其分配空间并初 始化为全0(未访问) //resu为一维数组,用于存放所遍历到的结点的编号,调用本函 数前,应为其分配空间 long nNodes, i; TGraphEdgeAL<TEdgeElem> *p; nNodes=1;
1 2
4
图 20-1有向图
5
3
1 2 3 4 5
1 0 1 0 1 0
2 1 0 0 0 0
3 0 0 0 0 0
4 0 1 0 0 0
5 1 0 1 0 0
1 2 3 4 5
1 1 0 1 1
1 2 4 5
所示图的邻接矩阵g
访问标识数组 visited
输出数组 resu
例如从1点深度优先遍历,先把1设置访问标志,并置入输出数组resu,然后从邻接 矩阵的第一行,扫描各列,找到最近的邻接点2,将其设置访问标志,并进入输出数 组,接着从邻接矩阵的2行扫描,找到第一个构成边的点是1,检查访问标识数组, 发现1已经访问过,跳过,找第二个构成边 的点4,设置访问标识,进入输出数组, 再从邻接矩阵的第4行扫描,寻找构成边的点,除1外在无其他点,返回2行,继续 寻找,也无新点,返回1,找到5,将5置访问标志,进入输出数组,1行再无其他新 点,遍历结束,返回遍历元素个数为4 。
树图查找排序复习讲解【范本模板】
树一、判断题:1。
二叉树是一棵无序树。
(×)2.在一棵二叉树中,假定每个结点只有左子女,没有右子女,对它分别进行中序遍历和后序遍历,则具有相同的结果。
(√)3。
度为二的有序树等价于二叉树。
(√)4.树的带权路径长度最小的二叉树中必定没有度为1的结点。
(√)5。
哈夫曼树一定是满二叉树。
(×)6.满二叉树也是完全二叉树.(√)7。
设与一棵树T所对应的二叉树为BT,则与T中的叶子结点所对应的BT中的结点也一定是叶子结点。
(×)8.将一棵树转换成二叉树后,根结点没有左子树(×)9。
已知一棵二叉树的前序序列和后序序列可以唯一地构造出该二叉树。
(√)10用二叉树的前序遍历和中序遍历可以导出树的后序遍历.(√)11.在完全二叉树中,若某结点无左孩子,则它必是叶结点。
(√)。
12.任何一棵二叉树都有n0=n2+1的关系式.(√)13.已知一棵树的前序遍历和后序遍历序列能唯一地确定这棵树.( √)二、填空题1.假定一棵二叉树的结点个数为32,则它的最小深度为___6___,最大深度为:32.2.在一棵二叉树中,度为2的结点有5个,度为1的结点有6个,那么叶子结点有__6____ 个.3.树的双亲表示法便于实现涉及到___双亲___的操作,孩子表示法便于实现涉及到孩子的操作。
4.对于一颗具有n个结点的二叉树,对应二叉链表中指针域有__n—1__个用于指向子结点。
5.下图所示二叉树存储在一维数组中,则元素F的下标位置为___11___。
(A为1)6.高度为k的二叉树具有的结点数目,最少为___ K ___,最多为___2K—1___。
7.对任何一棵二叉树,若n0,n1,n2分别是度为0,1,2的结点的个数,则n0=__ n2+1__.8.一棵含有16个结点的完全二叉树,对他按层编号,对于编号为7的结点,他的双亲结编号点为___3___左孩子编号为____14__、右孩子编号为___15___。
图的广度优先遍历算法
图的⼴度优先遍历算法前⾔⼴度优先遍历算法是图的另⼀种基本遍历算法,其基本思想是尽最⼤程度辐射能够覆盖的节点,并对其进⾏访问。
以迷宫为例,深度优先搜索更像是⼀个⼈在⾛迷宫,遇到没有⾛过就标记,遇到⾛过就退⼀步重新⾛;⽽⼴度优先搜索则可以想象成⼀组⼈⼀起朝不同的⽅向⾛迷宫,当出现新的未⾛过的路的时候,可以理解成⼀个⼈有分⾝术,继续从不同的⽅向⾛,,当相遇的时候则是合⼆为⼀(好吧,有点扯了)。
⼴度优先遍历算法的遍历过程仍然以上⼀篇的例⼦进⾏说明,下⾯是⼴度优先遍历的具体过程:1. 从起点0开始遍历2. 从其邻接表得到所有的邻接节点,把这三个节点都进⾏标记,表⽰已经访问过了3. 从0的邻接表的第⼀个顶点2开始寻找新的叉路4. 查询顶点2的邻接表,并将其所有的邻接节点都标记为已访问5. 继续从顶点0的邻接表的第⼆个节点,也就是顶点1,遍历从顶点1开始6. 查询顶点1的邻接表的所有邻接节点,也就是顶点0和顶点2,发现这两个顶点都被访问过了,顶点1返回7. 从顶点0的下⼀个邻接节点,也就是顶点5,开始遍历8. 查询顶点5的邻接节点,发现其邻接节点3和0都被访问过了,顶点5返回9. 继续从2的下⼀个邻接节点3开始遍历10. 寻找顶点3的邻接节点,发现都被访问过了,顶点3返回11. 继续寻找顶点2的下⼀个邻接节点4,发现4的所有邻接节点都被访问过了,顶点4返回12. 顶点2的所有邻接节点都放过了,顶点2返回,遍历结束⼴度优先遍历算法的实现与深度优先遍历算法相同,都需要⼀个标记数组来记录⼀个节点是否被访问过,在深度优先遍历算法中,使⽤的是⼀个栈来实现的,但是⼴度优先因为需要记录与起点距离最短的节点,或者说能够⽤尽可能少的边连通的节点,距离短的优先遍历,距离远的后⾯再遍历,更像是队列。
所以在⼴度优先遍历算法中,需要使⽤队列来实现这个过程。
下⾯是具体的实现代码(已附详细注释):package com.rhwayfun.algorithm.graph;import java.util.LinkedList;import java.util.Queue;public class BreadFirstSearch {//创建⼀个标记数组private boolean[] marked;//起点private int s;public BreadFirstSearch(MyGraph G, int s){marked = new boolean[G.V()];this.s = s;//开始⼴度优先搜索bfs(G,s);}private void bfs(MyGraph G, int s2) {//创建⼀个队列Queue<Integer> queue = new LinkedList<Integer>();//标记起点marked[s] = true;queue.add(s);System.out.print(s + " ");while(!queue.isEmpty()){//从队列中删除下⼀个节点int v = queue.poll();//将该节点的所有邻接节点加⼊队列中for(int w : G.adj(v)){//如果没有标记就标记if(!marked[w]){marked[w] = true;System.out.print(w + " ");queue.add(w);}}}}}运⾏该程序,发现⼴度优先遍历算法对上图的遍历顺序是0,2,1,5,3,4。
数据结构第7章习题答案
第7章 《图》习题参考答案一、单选题(每题1分,共16分)( C )1. 在一个图中,所有顶点的度数之和等于图的边数的倍。
A .1/2 B. 1 C. 2 D. 4 (B )2. 在一个有向图中,所有顶点的入度之和等于所有顶点的出度之和的倍。
A .1/2 B. 1 C. 2 D. 4 ( B )3. 有8个结点的无向图最多有条边。
A .14 B. 28 C. 56 D. 112 ( C )4. 有8个结点的无向连通图最少有条边。
A .5 B. 6 C. 7 D. 8 ( C )5. 有8个结点的有向完全图有条边。
A .14 B. 28 C. 56 D. 112 (B )6. 用邻接表表示图进行广度优先遍历时,通常是采用来实现算法的。
A .栈 B. 队列 C. 树 D. 图 ( A )7. 用邻接表表示图进行深度优先遍历时,通常是采用来实现算法的。
A .栈 B. 队列 C. 树 D. 图( C )8. 已知图的邻接矩阵,根据算法思想,则从顶点0出发按深度优先遍历的结点序列是( D )9. 已知图的邻接矩阵同上题8,根据算法,则从顶点0出发,按深度优先遍历的结点序列是A . 0 2 4 3 1 5 6 B. 0 1 3 5 6 4 2 C. 0 4 2 3 1 6 5 D. 0 1 23465 ( D )10. 已知图的邻接表如下所示,根据算法,则从顶点0出发按深度优先遍历的结点序列是( A )11. 已知图的邻接表如下所示,根据算法,则从顶点0出发按广度优先遍历的结点序列是A .0 2 4 3 1 5 6B. 0 1 3 6 5 4 2C. 0 1 3 4 2 5 6D. 0 3 6 1 5 4 2⎥⎥⎥⎥⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎢⎢⎢⎢⎣⎡0100011101100001011010110011001000110010011011110A .0 1 3 2 B. 0 2 3 1 C. 0 3 2 1 D. 0 1 2 3A.0 3 2 1 B. 0 1 2 3C. 0 1 3 2D. 0 3 1 2(A)12. 深度优先遍历类似于二叉树的A.先序遍历 B. 中序遍历 C. 后序遍历 D. 层次遍历(D)13. 广度优先遍历类似于二叉树的A.先序遍历 B. 中序遍历 C. 后序遍历 D. 层次遍历(A)14. 任何一个无向连通图的最小生成树A.只有一棵 B. 一棵或多棵 C. 一定有多棵 D. 可能不存在(注,生成树不唯一,但最小生成树唯一,即边权之和或树权最小的情况唯一)二、填空题(每空1分,共20分)1. 图有邻接矩阵、邻接表等存储结构,遍历图有深度优先遍历、广度优先遍历等方法。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
if(g->vertex[i].data==v)
break;
return(i);
}
void creatgraph(ALG *g)
{
int i;
char c;
putchar(g->vertex[vi].data);
visited[vi]=1;
rear=g->vertex[vi].firstarc;
while((rear!=NULL)&&(!visited[rear->num]))
{
depthfirstsearch(g,rear->num);
}
void enterqueue(int v)
{
q.data[q.rear]=v;
q.rear++;
}
int deletequeue()
{
int t;
t=q.data[q.front];
q.front++;
return(t);
visited[rear->num]=1;
enterqueue(rear->num);
rear=rear->nextarc;
}
}
}
}
void main()
while((c=getchar())!='*')
{
temp=(arcnode *)malloc(sizeof(arcnode));
temp->num=locate(g,c);
rear->nextarc=temp;
//用邻接表存储的图,然后用深度优先和广度优先分别遍历整个图
#include<malloc.h>
#define max 20
#include<stdio.h>
typedef struct arcnode
{
int num;
struct arcnode *nextarc;
{
int i;
ALG g;
creatgraph(&g);
for(i=0;i<g.vexnum;i++)
visited[i]=0;
printf("采用邻接表的深度优先为\n");
travel(&g);
putchar('\n');
for(i=0;i<g.vexnum;i++)
visited[i]=0;
q.rear=q.front=0;
printf("采用邻接表的广度优先为\n");
breadfirstsearch(&g);
putchar('\n');
}
}ALG;
typedef struct
{
int data[max+10];
int front;
int rear;
}queue;
int visited[max];
queue q;
int locate(ALG *g,char v)
{
int i;
rear=temp;
}
}
rear->nextarc=NULL;
getchar();
}
}
void depthfirstsearch(ALG *g,int vi)
{
arcnode *rear;
}
int empty()
{
if(q.front==q.rear)
return 1;
return 0;
}
void breadfirstsearch(ALG *g)
{
int v,t;
arcnode *rear;
for(v=0;v<g->vexnum;v++)
rear=rear->nextarc;
}
}
void travel(ALG *g)
{
int v;
for(v=0;v<g->vexnum;v++)
if(!visited[v])
depthfirstsearch(g,v);
{
scanf("%c",&(g->vertex[i].data));
g->vertex[i].firstarc=NULL;
}
getchar();
for(i=0;i<g->vexnum;i++)
{
printf("输入所有和%c相连的顶点,以*结束\n",g->vertex[i].data);
{
if(!visited[v])
{
putchar(g->vertex[v].data);
visited[v]=1;
enterqueue(v);
}
while(!empty())
}arcnode;
typedef struct vexnode
{
char data;
arcnode *firstarc;
}vexnode;
typedef struct
{
vexnode vertex[max];
int vexnum;
int arcnum;
arcnode *rear,*temp;
printf("输入图的顶点数和边数\n");
scanf("%d%d",&g->vexnum,&g->arcnum);
getchar();
pቤተ መጻሕፍቲ ባይዱintf("输入所有顶点\n");
for(i=0;i<g->vexnum;i++)
{
t=deletequeue();
rear=g->vertex[t].firstarc;
while((rear!=NULL)&&(!visited[rear->num]))
{
putchar(g->vertex[rear->num].data);
if((c=getchar())!='*')
{
rear=(arcnode *)malloc(sizeof(arcnode));
g->vertex[i].firstarc=rear;
rear->num=locate(g,c);