数据结构 图的遍历(初始化图)

合集下载

数据结构中的图的遍历算法

数据结构中的图的遍历算法

数据结构中的图的遍历算法图是一种非常重要且广泛应用的数据结构,它由顶点和边组成,可以用来表示各种实际问题,如社交网络、路线规划等。

图的遍历算法是对图中的所有顶点进行系统访问的方法,它可以用来查找、遍历和搜索图中的元素。

本文将介绍图的遍历算法的基本概念和常用的实现方法。

一、图的遍历算法概述图的遍历算法是指按照某种规则遍历图中的所有顶点,以便于查找、遍历和搜索图中的元素。

常用的图的遍历算法有深度优先搜索(DFS)和广度优先搜索(BFS)两种。

深度优先搜索(DFS)是一种先访问顶点的所有邻接顶点,再递归访问邻接顶点的邻接顶点的算法。

它以深度为优先级,一直向前走到不能继续为止,然后返回到前一个结点,继续向前走,直到遍历完整个图。

广度优先搜索(BFS)是一种先访问顶点的所有邻接顶点,再访问邻接顶点的邻接顶点,以此类推的算法。

它以广度为优先级,先访问离起始顶点最近的顶点,然后依次访问离起始顶点更远的顶点,直到遍历完整个图。

二、深度优先搜索(DFS)深度优先搜索是一种递归的搜索算法,它的基本思想是从图的某个顶点出发,沿着一条路径一直深入直到不能继续为止,然后返回到前一个结点,继续向前走。

具体实现时,可以使用递归或栈来保存需要访问的顶点。

以下是深度优先搜索的基本步骤:1. 选择一个起始顶点作为当前顶点,将其标记为已访问。

2. 访问当前顶点,并将其加入遍历结果。

3. 从当前顶点的未访问邻接顶点中选择一个作为下一个当前顶点,重复步骤2。

4. 如果当前顶点的所有邻接顶点都已访问,则返回到前一个顶点,重复步骤3。

5. 重复步骤4,直到遍历完整个图。

三、广度优先搜索(BFS)广度优先搜索是一种迭代的搜索算法,它的基本思想是从图的某个顶点出发,依次访问其所有未访问过的邻接顶点,然后再依次访问这些邻接顶点的未访问过的邻接顶点,直到遍历完整个图。

具体实现时,可以使用队列来保存需要访问的顶点。

以下是广度优先搜索的基本步骤:1. 选择一个起始顶点作为当前顶点,将其标记为已访问,并将其加入遍历结果。

数据结构C语言版 实验报告

数据结构C语言版 实验报告

数据结构C语言版实验报告一、实验目的本次实验旨在通过使用 C 语言实现常见的数据结构,加深对数据结构基本概念、原理和操作的理解,提高编程能力和解决实际问题的能力。

二、实验环境操作系统:Windows 10编程环境:Visual Studio 2019编程语言:C 语言三、实验内容1、线性表顺序表的实现与操作链表的实现与操作2、栈和队列栈的实现与应用(表达式求值)队列的实现与应用(模拟排队)3、树和二叉树二叉树的遍历(前序、中序、后序)二叉搜索树的实现与操作4、图图的存储结构(邻接矩阵、邻接表)图的遍历(深度优先搜索、广度优先搜索)四、实验步骤及结果1、线性表顺序表的实现与操作定义顺序表的数据结构,包括数组和表的长度。

实现顺序表的初始化、插入、删除、查找等操作。

测试顺序表的各种操作,输出操作结果。

```cinclude <stdioh>include <stdlibh>define MAX_SIZE 100typedef struct {int dataMAX_SIZE;int length;} SeqList;//初始化顺序表void initList(SeqList L) {L>length = 0;}//插入元素到顺序表int insertList(SeqList L, int pos, int element) {if (L>length >= MAX_SIZE || pos < 0 || pos > L>length) {return 0;}for (int i = L>length 1; i >= pos; i) {L>datai + 1 = L>datai;}L>datapos = element;L>length++;return 1;}//删除顺序表中的元素int deleteList(SeqList L, int pos) {if (pos < 0 || pos >= L>length) {return 0;}for (int i = pos; i < L>length 1; i++){L>datai = L>datai + 1;}L>length;return 1;}//查找顺序表中的元素int searchList(SeqList L, int element) {for (int i = 0; i < Llength; i++){if (Ldatai == element) {return i;}}return -1;}int main(){SeqList L;initList(&L);insertList(&L, 0, 10);insertList(&L, 1, 20);insertList(&L, 2, 30);printf("顺序表元素: ");for (int i = 0; i < Llength; i++){printf("%d ", Ldatai);}printf("\n");int pos = searchList(L, 20);if (pos!=-1) {printf("元素 20 在顺序表中的位置: %d\n", pos);} else {printf("顺序表中未找到元素 20\n");}deleteList(&L, 1);printf("删除元素后的顺序表元素: ");for (int i = 0; i < Llength; i++){printf("%d ", Ldatai);}printf("\n");return 0;}```实验结果:成功实现顺序表的初始化、插入、删除、查找等操作,输出结果符合预期。

数据结构实验报告图的遍历讲解

数据结构实验报告图的遍历讲解

数据结构实验报告图的遍历讲解一、引言在数据结构实验中,图的遍历是一个重要的主题。

图是由顶点集合和边集合组成的一种数据结构,常用于描述网络、社交关系等复杂关系。

图的遍历是指按照一定的规则,挨次访问图中的所有顶点,以及与之相关联的边的过程。

本文将详细讲解图的遍历算法及其应用。

二、图的遍历算法1. 深度优先搜索(DFS)深度优先搜索是一种常用的图遍历算法,其基本思想是从一个顶点出发,沿着一条路径向来向下访问,直到无法继续为止,然后回溯到前一个顶点,再选择此外一条路径继续访问。

具体步骤如下:(1)选择一个起始顶点v,将其标记为已访问。

(2)从v出发,选择一个未被访问的邻接顶点w,将w标记为已访问,并将w入栈。

(3)如果不存在未被访问的邻接顶点,则出栈一个顶点,继续访问其它未被访问的邻接顶点。

(4)重复步骤(2)和(3),直到栈为空。

2. 广度优先搜索(BFS)广度优先搜索是另一种常用的图遍历算法,其基本思想是从一个顶点出发,挨次访问其所有邻接顶点,然后再挨次访问邻接顶点的邻接顶点,以此类推,直到访问完所有顶点。

具体步骤如下:(1)选择一个起始顶点v,将其标记为已访问,并将v入队。

(2)从队首取出一个顶点w,访问w的所有未被访问的邻接顶点,并将这些顶点标记为已访问,并将它们入队。

(3)重复步骤(2),直到队列为空。

三、图的遍历应用图的遍历算法在实际应用中有广泛的应用,下面介绍两个典型的应用场景。

1. 连通分量连通分量是指图中的一个子图,其中的任意两个顶点都是连通的,即存在一条路径可以从一个顶点到达另一个顶点。

图的遍历算法可以用来求解连通分量的个数及其具体的顶点集合。

具体步骤如下:(1)对图中的每一个顶点进行遍历,如果该顶点未被访问,则从该顶点开始进行深度优先搜索或者广度优先搜索,将访问到的顶点标记为已访问。

(2)重复步骤(1),直到所有顶点都被访问。

2. 最短路径最短路径是指图中两个顶点之间的最短路径,可以用图的遍历算法来求解。

图的遍历 实验报告

图的遍历  实验报告

图的遍历实验报告一、引言图是一种非线性的数据结构,由一组节点(顶点)和节点之间的连线(边)组成。

图的遍历是指按照某种规则依次访问图中的每个节点,以便获取或处理节点中的信息。

图的遍历在计算机科学领域中有着广泛的应用,例如在社交网络中寻找关系紧密的人员,或者在地图中搜索最短路径等。

本实验旨在通过实际操作,掌握图的遍历算法。

在本实验中,我们将实现两种常见的图的遍历算法:深度优先搜索(DFS)和广度优先搜索(BFS),并比较它们的差异和适用场景。

二、实验目的1. 理解和掌握图的遍历算法的原理与实现;2. 比较深度优先搜索和广度优先搜索的差异;3. 掌握图的遍历算法在实际问题中的应用。

三、实验步骤实验材料1. 计算机;2. 编程环境(例如Python、Java等);3. 支持图操作的相关库(如NetworkX)。

实验流程1. 初始化图数据结构,创建节点和边;2. 实现深度优先搜索算法;3. 实现广度优先搜索算法;4. 比较两种算法的时间复杂度和空间复杂度;5. 比较两种算法的遍历顺序和适用场景;6. 在一个具体问题中应用图的遍历算法。

四、实验结果1. 深度优先搜索(DFS)深度优先搜索是一种通过探索图的深度来遍历节点的算法。

具体实现时,我们可以使用递归或栈来实现深度优先搜索。

算法的基本思想是从起始节点开始,选择一个相邻节点进行探索,直到达到最深的节点为止,然后返回上一个节点,再继续探索其他未被访问的节点。

2. 广度优先搜索(BFS)广度优先搜索是一种逐层遍历节点的算法。

具体实现时,我们可以使用队列来实现广度优先搜索。

算法的基本思想是从起始节点开始,依次遍历当前节点的所有相邻节点,并将这些相邻节点加入队列中,然后再依次遍历队列中的节点,直到队列为空。

3. 时间复杂度和空间复杂度深度优先搜索和广度优先搜索的时间复杂度和空间复杂度如下表所示:算法时间复杂度空间复杂度深度优先搜索O(V+E) O(V)广度优先搜索O(V+E) O(V)其中,V表示节点的数量,E表示边的数量。

天大《数据结构》学习笔记五

天大《数据结构》学习笔记五

主 题: 《数据结构》学习笔记内 容:《数据结构》学习笔记五——图一、图的概念:1、术语:有向图,无向图,子图,顶点,边,弧,邻接点,出度,入度,路径,连通图。

2、图的存储:2.1邻接矩阵:0 1 1 0 0 1 0 1 00 0 0 0 1 0 1 0 10 0 0 1 0 1 0 1 11 0 0 0 1 0 1 0 00 1 1 0 02.2邻接表:2 3 ^4 ^1 ^Struct node{int data;struct node *next;}struct node V[n+1];3、程序:3.1已知邻接表,建立邻接矩阵。

{……for(I=1;I<=n;I++)for(j=1;j<=n;j++)w[I][j]=0;for(I=1;I<=n;I++){p=v[I].next;while(p){j=p->data;w[I][j]=1;p=p->next;}}}3.2已知邻接矩阵,建立邻接表。

{……for(I=1;I<=n;I++)v[I].next=0;for(I=1;I<=n;I++)for(j=1;j<=n;j++)if (w[I][j]= =1){p=(……)malloc(……);p->data=j;p->next=v[I].next;v[I].next=p;}}1、广度优先遍历1.1作法:(i)初始化(打印,加标记,进队)(ii)出队.(J)(iii)扫描(J)链,遇未访问点,则打印,加标记,进队.返回ii,直至队空.1.2 结果:2、深度优先遍历:2.1作法:从某点进入,打印,加标记,扫描此链:如没遇到未访问点,则返到原转来点.算法结束于进入点那个链的链尾.2.2 结果:1,2,4,8,5,3,6,73、广度优先程序:bfs(I)int I;{……f=0; r=0;for(t=1;t<=n;t++)v[t].data=0;printf(“%d”,I);v[I].data=1;r++; q[r]=I;while(f!=r){f++; j=q[f];p=v[j].next;while(p){k=p->data;if(v[k].data= =0){printf(“%d”,k);v[k].data=1;r++;q[r]=k;}p=p->next;}}}4、深度优先程序:dfs(I)int I;{……v[I].data=1;printf(“%d”,I);p=v[I].next;while(p){j=p->data;if(v[j].data= =0)dfs(j);p=p->next;}}三、最小生成树:1、解法11.1问题:选哪几条边,使得(I)能连到各点(II)边长之和最小?1.2思路:i. 从当前点集的发出边中选最小者,打印。

数据结构-实验6图的存储和遍历

数据结构-实验6图的存储和遍历

实验6.1实现图的存储和遍历一,实验目的掌握图的邻接矩阵和邻接表存储以及图的邻接矩阵存储的递归遍历。

二,实验内容6.1实现图的邻接矩阵和邻接表存储编写一个程序,实现图的相关运算,并在此基础上设计一个主程序,完成如下功能:(1)建立如教材图7.9所示的有向图G的邻接矩阵,并输出。

(2)由有向图G的邻接矩阵产生邻接表,并输出。

(3)再由(2)的邻接表产生对应的邻接矩阵,并输出。

6.2 实现图的遍历算法(4)在图G的邻接矩阵存储表示基础上,输出从顶点V1开始的深度优先遍历序列(递归算法)。

(5)利用非递归算法重解任务(4)。

(6)在图G的邻接表存储表示基础上,输出从顶点V1开始的广度优先遍历序列。

三,源代码及结果截图#include<stdio.h>#include<stdlib.h>#include<string.h>#include<iostream.h>#include<malloc.h>#define MAX_VERTEX_NUM 20typedef char VRType;typedef int InfoType; // 存放网的权值typedef char VertexType; // 字符串类型typedef enum{DG,DN,AG,AN}GraphKind; // {有向图,有向网,无向图,无向网}/*建立有向图的邻接矩阵*/typedef struct ArcCell{VRType adj;//VRType是顶点关系类型,对无权图用1或0表示是否相邻;对带权图则为权值类型InfoType *info; //该弧相关信息的指针(可无)}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];typedef struct{VertexType vexs[MAX_VERTEX_NUM];//顶点向量AdjMatrix arcs;//邻接矩阵int vexnum,arcnum;;//图的当前顶点数和弧数GraphKind kind;//图的种类标志}MGraph;/* 顶点在顶点向量中的定位*/int LocateVex(MGraph &M,VRType v1){int i;for(i=0;i<M.vexnum;i++)if(v1==M.vexs[i])return i;return -1;}void CreateGraph(MGraph &M)//建立有向图的邻接矩阵{int i,j,k,w;VRType v1,v2;M.kind=DN;printf("构造有向网:\n");printf("\n输入图的顶点数和边数(以空格作为间隔):");scanf("%d%d",&M.vexnum,&M.arcnum);printf("输入%d个顶点的值(字符):",M.vexnum);getchar();for(i=0;i<M.vexnum;i++) //输入顶点向量{scanf("%c",&M.vexs[i]);}printf("建立邻接矩阵:\n");for(i=0;i<M.vexnum;i++)for(j=0;j<M.vexnum;j++){M.arcs[i][j].adj=0;M.arcs[i][j].info=NULL;}printf("请顺序输入每条弧(边)的权值、弧尾和弧头(以空格作为间隔):\n");for(k=0;k<M.arcnum;++k)// 构造表结点链表{cin>>w>>v1>>v2;i=LocateVex(M,v1);j=LocateVex(M,v2);M.arcs[i][j].adj=w;}}//按邻接矩阵方式输出有向图void PrintGraph(MGraph M){int i,j;printf("\n输出邻接矩阵:\n");for(i=0; i<M.vexnum; i++){printf("%10c",M.vexs[i]);for(j=0; j<M.vexnum; j++)printf("%2d",M.arcs[i][j].adj);printf("\n");}}// 图的邻接表存储表示typedef struct ArcNode{int adjvex; // 该弧所指向的顶点的位置struct ArcNode *nextarc; // 指向下一条弧的指针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;void CreateMGtoDN(ALGraph &G,MGraph &M){//由有向图M的邻接矩阵产生邻接表int i,j;ArcNode *p;G.kind=M.kind;G.vexnum=M.vexnum;G.arcnum=M.arcnum;for(i=0;i<G.vexnum;++i){//构造表头向量G.vertices[i].data=M.vexs[i];G.vertices[i].firstarc=NULL;//初始化指针}for(i=0;i<G.vexnum;++i)for(j=0;j<G.vexnum;++j)if(M.arcs[i][j].adj){p=(ArcNode*)malloc(sizeof(ArcNode));p->adjvex=j;p->nextarc=G.vertices[i].firstarc;p->info=M.arcs[i][j].info;G.vertices[i].firstarc=p;}}void CreateDNtoMG(MGraph &M,ALGraph &G){ //由邻接表产生对应的邻接矩阵int i,j;ArcNode *p;M.kind=GraphKind(G.kind);M.vexnum=G.vexnum;M.arcnum=G.arcnum;for(i=0;i<M.vexnum;++i)M.vexs[i]=G.vertices[i].data;for(i=0;i<M.vexnum;++i){p=G.vertices[i].firstarc;while(p){M.arcs[i][p->adjvex].adj=1;p=p->nextarc;}//whilefor(j=0;j<M.vexnum;++j)if(M.arcs[i][j].adj!=1)M.arcs[i][j].adj=0;}//for}//输出邻接表void PrintDN(ALGraph G){int i;ArcNode *p;printf("\n输出邻接表:\n");printf("顶点:\n");for(i=0;i<G.vexnum;++i)printf("%2c",G.vertices[i].data);printf("\n弧:\n");for(i=0;i<G.vexnum;++i){p=G.vertices[i].firstarc;while(p){printf("%c→%c(%d)\t",G.vertices[i].data,G.vertices[p->adjvex].data,p->info);p=p->nextarc;}printf("\n");}//for}int visited[MAX_VERTEX_NUM]; // 访问标志数组(全局量)void(*VisitFunc)(char* v); // 函数变量(全局量)// 从第v个顶点出发递归地深度优先遍历图G。

图的遍历问题

图的遍历问题

HUNAN UNIVERSITY数据结构实验报告题目:图的遍历问题学生姓名梁天学生学号************专业班级计科1403指导老师夏艳日期2016.05.14背景网络蜘蛛即Web Spider,是一个很形象的名字。

把互联网比喻成一个蜘蛛网,那么Spider 就是在网上爬来爬去的蜘蛛。

网络蜘蛛是通过网页的链接地址来寻找网页,从网站某一个页面(通常是首页)开始,读取网页的内容,找到在网页中的其它链接地址,然后通过这些链接地址寻找下一个网页,这样一直循环下去,直到把这个网站所有的网页都抓取完为止。

如果把整个互联网当成一个网站,那么网络蜘蛛就可以用这个原理把互联网上所有的网页都抓取下来。

这样看来,网络蜘蛛就是一个爬行程序,一个抓取网页的程序。

在抓取网页的时候,网络蜘蛛一般有两种策略:广度优先和深度优先(如下面这张简单化的网页连接模型图所示,其中A为起点也就是蜘蛛索引的起点)。

深度优先顾名思义就是让网络蜘蛛尽量的在抓取网页时往网页更深层次的挖掘进去讲究的是深度!也泛指: 网络蜘蛛将会从起始页开始,一个链接一个链接跟踪下去,处理完这条线路之后再转入下一个起始页,继续跟踪链接! 则访问的节点顺序为==> A --> B --> E --> H --> I --> C --> D --> F --> K --> L --> G。

深度爬行的优点是:网络蜘蛛程序在设计的时候相对比较容易些;缺点是每次爬行一层总要向"蜘蛛老家" 数据库访问一下。

问问老总有必要还要爬下一层吗! 爬一层问一次.... 如果一个蜘蛛不管3721不断往下爬很可能迷路更有可能爬到国外的网站去,不仅增加了系统数据的复杂度更是增加的服务器的负担。

广度优先在这里的定义就是层爬行,即一层一层的爬行,按照层的分布与布局去索引处理与抓取网页。

则访问的节点顺序为==> A --> B --> C --> D --> E --> F --> G --> H --> I--> K --> L。

数据结构名词解释

数据结构名词解释

数据结构名词解释数据结构名词解释1:数组:数组是一种线性数据结构,它是由一系列有序的元素组成。

数组中的元素可以根据索引来访问,索引从0开始,依次递增。

数组的大小在创建时需要预先确定,并且不能改变。

2:链表:链表也是一种线性数据结构,它由一系列节点组成。

每个节点包含数据和指向下一个节点的指针。

链表中的节点可以在运行时动态地创建和删除,并且没有大小限制。

3:栈:栈是一种特殊的数据结构,它按照后进先出(LIFO)的原则进行操作。

栈可以使用数组或链表来实现。

4:队列:队列也是一种特殊的数据结构,它按照先进先出(FIFO)的原则进行操作。

队列可以使用数组或链表来实现。

5:树:树是一种非线性数据结构,它由节点和边组成。

每个节点可以有多个子节点,但只有一个父节点。

树用于表示层次结构,如文件系统和组织架构。

6:图:图是一种非线性数据结构,它由节点和边组成。

节点可以自由地与其他节点相连,形成复杂的关系网络。

图可以用于表示社交网络、路由网络等。

7:哈希表:哈希表是一种根据关键字直接访问内存中存储位置的数据结构。

它通过哈希函数将关键字映射到一个固定大小的数组中,以实现快速查找和插入。

8:树堆:树堆是一种特殊的二叉树,它满足堆的性质。

堆分为最大堆和最小堆,最大堆中每个节点的值都大于等于其子节点的值,最小堆则相反。

9:图的遍历:图的遍历是指按照一定的规则遍历图中的所有节点。

常用的遍历算法有深度优先搜索(DFS)和广度优先搜索(BFS)。

10:排序算法:排序算法是将一组无序的数据按照某种特定的顺序进行排列的算法。

常用的排序算法有冒泡排序、插入排序、选择排序、快速排序、归并排序等。

附件:本文档未涉及到附件内容。

法律名词及注释:本文档不涉及法律名词及注释。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实践四:图及图的应用
1.实验目的要求
理解图的基本概念,两种主要的存储结构。

掌握在邻接链表存储结构下的图的深度优先递归遍历、广度优先遍历。

通过选做题"最短路径问题"认识图及其算法具有广泛的应用意义。

实验要求:正确调试程序。

写出实验报告。

2.实验主要内容
2.1 在邻接矩阵存储结构下的图的深度优先递归遍历、广度优先遍历。

2.1.1 要完成图的两种遍历算法,首先需要进行图的数据初始化。

为把时间主要花在遍历算法的实现上,图的初始化采用结构体声明时初始化的方法。

示例代码如下:
#include "stdio.h"
typedef int Arcell;
typedef int AdjMatrix[5][5];
typedef struct {
char vexs[5];
AdjMatrix arcs;
int vexnum,arcnum;
}MGraph;
void main(){
MGraph g={
{'a','b','c','d','e'},
{{0,1,0,1,0},
{1,0,0,0,1},
{1,0,0,1,0},
{0,1,0,0,1},
{1,0,0,0,0}} ,5,9};
}
2.1.2 深度优先遍历算法7.5中FirstAdjVex方法和NextAdjVex方法需要自己实现。

2.2 拓扑排序,求图的拓扑序列
2.3 "最短路径问题",以校园导游图为实际背景进行设计。

(选做)
程序代码如下:
#include <stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
#define MAX 20
#define NULL 0
#define OK 1
#define OVERFLOW -2
#define ERROR 0
typedef int Status;
typedef int Boolean;
typedef int QElemType;
// 图的邻接矩阵存储结构typedef struct ArcCell{
int adj;
}ArcCell, AdjMatrix[20][20];
typedef struct {
char vexs[20];
AdjMatrix arcs;
int vexnum,arcnum; }Graph;
//队列的链式存储结构typedef struct QNode{
QElemType data;
struct QNode * next;
}QNode, *QueuePtr;
typedef struct{
QueuePtr front;
QueuePtr rear;
}LinkQueue;
Status InitQueue(LinkQueue &Q){
//构造一个空队列
Q.front=Q.rear =(QueuePtr)malloc(sizeof(QNode));
if(!Q.front) exit(OVERFLOW);
Q.front->next=NULL;
return OK;
}
Status EnQueue(LinkQueue &Q, QElemType e){
//插入元素e为Q的新的队尾元素
QueuePtr p=(QueuePtr) malloc(sizeof(QNode));
if(!p) exit(OVERFLOW);
p->data=e; p->next=NULL;
Q.rear->next=p;
Q.rear=p;
return OK;
}
Status DeQueue(LinkQueue &Q,QElemType &e){
//若队列不空,则删除Q的对头元素,用e返回其值,并返回OK;
//否则返回ERROR
QueuePtr p;
if(Q.front==Q.rear) return ERROR;
p=Q.front->next;
e=p->data;
Q.front->next=p->next;
if(Q.rear==p) Q.rear=Q.front;
free(p);
return OK;
}
Status QueueEmpty(LinkQueue Q){
//若队列Q为空队列,则返回TRUE
if(Q.rear==Q.front)
return TRUE;
else
return FALSE;
}
Boolean visited[MAX];
Status(*VisitFunc)(char v);
Status Visit(char v){
//visit函数
printf("%c ",v);
return 0;
}
int FirstAdjVex(Graph G,int v){
int i;
for(i=0;i<G.vexnum;i++){
if(G.arcs[v][i].adj==1)
return i;
}
return -1;
}
int NextAdjVex(Graph G,int v,int w){
int i;
for(i=w+1;i<G.vexnum;i++){
if(G.arcs[v][i].adj==1)
return i;
}
return -1;
}
void DFS(Graph G,int v){
int w;
visited[v] = TRUE; VisitFunc(G.vexs[v]);
for(w=FirstAdjVex(G,v); w >= 0; w=NextAdjVex(G,v,w)) if(!visited[w]) DFS(G,w);
}
/* 图的深度优先搜索 */
void DFSTraverse(Graph G,Status(*Visit)(char v)){
VisitFunc = Visit;
int v;
for(v=0; v<G.vexnum; ++v) visited[v] = FALSE;
for(v=0; v<G.vexnum; ++v)
if(!visited[v]) DFS(G,v);
}
/* 图的广度优先搜索 */
void BFSTraverse(Graph G, Status(*Visit)(char)){
int v,w,u;
LinkQueue q;
for(v=0; v<G.vexnum; ++v) visited[v] = FALSE;
InitQueue(q);
for(v=0; v<G.vexnum; ++v)
if(!visited[v]){
visited[v] = TRUE; Visit(G.vexs[v]);
EnQueue(q,v);
while(!QueueEmpty(q)){
DeQueue(q,u);
for(w=FirstAdjVex(G,u); w>=0; w=NextAdjVex(G,u,w))
if(!visited){
visited[w] = TRUE; Visit(G.vexs[w]);
EnQueue(q,w);
}
}
}
}
/* 输出邻接矩阵 */
void PrintGraph(Graph G)
{
int i,j;
for(i=0;i<G.vexnum;i++)
{
for(j=0;j<G.vexnum;j++)
{
printf("%d ",G.arcs[i][j].adj);
}
printf("\n");
}
}
void main(){
Graph g={
{'a','b','c','d','e','f','g','h'},
{{0,1,1,0,0,0,0,0,0},
{1,0,0,1,1,0,0,0},
{1,0,0,0,0,1,1,0},
{0,1,0,0,0,0,0,1},
{0,1,0,0,0,0,0,1},
{0,0,1,0,0,0,1,0},
{0,0,1,0,0,1,0,0},
{0,0,0,1,1,0,0,0}} ,8,18};
printf("图的邻接矩阵为:\n");
PrintGraph(g);
printf("\n图的深度优先搜索为:\n");
DFSTraverse(g,Visit);
printf("\n图的广度优先搜索为:\n");
BFSTraverse(g,Visit);
printf("\n");
}
输出结果为:。

相关文档
最新文档