数据结构课程设计之图的遍历和生成树求解
数据结构中的树与图算法教程

数据结构中的树与图算法教程第一章树的基本概念与遍历算法树是一种非线性数据结构,它由若干个节点组成,这些节点以层级的方式连接,形成分支的结构。
树中的一个节点被称为根节点,它没有父节点;其他节点可以有一个或多个父节点,这些节点被称为子节点。
树具有分支,但没有循环。
1.1 具体树的概念在树的结构中,每个节点可以有零个或者多个子节点,但是只能有一个父节点。
树具有层级关系,通过连接节点的边表示。
1.2 树的分类常见的树包括二叉树、二叉搜索树、红黑树等。
其中,二叉树是一种特殊的树结构,它的每个节点最多可以有两个子节点。
1.3 树的遍历算法树的遍历算法主要有前序遍历、中序遍历和后序遍历。
前序遍历是以根节点、左子树、右子树的顺序进行遍历;中序遍历是以左子树、根节点、右子树的顺序进行遍历;后序遍历是以左子树、右子树、根节点的顺序进行遍历。
第二章树的存储结构与常见应用2.1 树的存储结构树的存储结构有两种常见的实现方式,分别是链表实现和数组实现。
链表实现利用指针进行节点的连接,数组实现则使用数组的索引来表示节点之间的关系。
2.2 平衡二叉树平衡二叉树是一种自平衡的二叉搜索树,它的左右子树的高度差不超过1。
平衡二叉树的插入和删除操作都可以通过旋转操作进行平衡。
2.3 哈夫曼树哈夫曼树是一种特殊的二叉树,用于编码和解码数据。
哈夫曼树中出现频率高的字符距离根节点较近,而出现频率低的字符距离根节点较远,以实现编码的高效率。
第三章图的基本概念与遍历算法3.1 图的基本概念图是由节点和边组成的非线性数据结构。
节点表示实体,边表示节点之间的关系。
图可以分为有向图和无向图两种类型,有向图的边是有方向的,无向图的边没有方向。
3.2 图的存储结构图的存储结构有邻接矩阵和邻接表两种常见的方式。
邻接矩阵是一个二维数组,用于表示节点之间的连接关系;邻接表是由链表或者数组实现的,用于表示每个节点相邻节点的信息。
3.3 图的遍历算法图的遍历算法主要有深度优先搜索(DFS)和广度优先搜索(BFS)。
《数据结构》课程教案

数据结构》课程教案课程类别:专业基础课适用专业:计算机应用技术授课学时:32学时课程学分:4学分一、课程性质、任务课程性质:《数据结构》是计算机应用技术专业的必修课程,也是研究如何对数据进行组织和设计、如何编制高效率的处理程序的一门基础学科。
课程任务:1、学习计算机程序编写中的数据组织和设计;2、数据的物理结构和逻辑结构;3、经典算法的设计和算法效率的分析。
二、课程培养目标:(一)知识目标通过理论学习和程序的编写,使学生系统地掌握程序中数据的组织、数据的物理结构和逻辑结构,在重要算法的实现上逐步提高编程能力。
(二)技能目标通过课程的学习,让学生掌握重要的数据结构,对数据的逻辑结构和物理结构有深入的理解,同时能编写出使用重要算法知识的程序,并运用所学知识编写程序解决实际中的问题。
(三)素质目标通过课程的学习,让学习学会自学,培养学生的自学能力、克服学习困难的能力,同时让学生掌握计算机编程中数据结构的学习方法,并养成严谨、认真、仔细、踏实、上进的好习惯。
三、选用教材与参考资料教材版本信息《数据结构与算法简明教程(Java语言版)》清华大学出版社叶小平陈瑛主编教材使用评价本教材经过两年的使用,得到了读者一致认可,同时也在不断改进,适合高职高专教学使用,内容基础、重难点突出,符合高职高专“理论够用、注重实践”的要求。
选用的参考资料严蔚敏•吴伟民《数据结构(C语言版)》•清华大学出版社.2009年版殷人昆.《数据结构》•清华大学出版社.1999年版《C语言程序设计》•石油大学出版社《C语言程序设计》•中国石油大学出版社.2006年版四、本课程与其他课程的联系与分工先修课程《离散数学》、《程序设计基础》后续课程《面向对象技术》、《操作系统》与其他课程配合与取舍情况《数据结构》与《离散数学》知识点结合较多,《离散数学》讲求逻辑思维能力的培养和训练,《数据结构》中逻辑结构的学习也需要逻辑思维能力做铺垫。
同时《程序设计基础》课程也为学习《数据结构》打下了基础,对于本课程的教材,我们采用C语言来描述数据结构,因此程序设计基础也是以C语言作为的对象。
《数据结构》课程教学大纲(三套)

数据结构课程教学大纲(三套)《数据结构》课程教学大纲(36/36 课时)一、课程的性质和任务数据结构是计算机及应用专业中一门重要的专业基础课程,在计算机软件的各个领域中均会使用到数据结构的有关知识。
当用计算机来解决实际问题时,就要涉及到数据的表示及数据的处理,而数据表示及数据处理正是数据结构课程的主要研究对象,通过这两方面内容的学习,为后续课程,特别是软件方面的课程打开厚实的基础。
因此,数据结构课程在计算机应用专业中具有举足轻重的作用。
本课程的任务是:在基础方面,要求学员掌握常用数据结构的基本概念及其不同的实现方法;在技能方面,通过系统学习能够在不同存储结构上实现不同的运算,并对算法设计的方式和技巧有所体会。
总言之,使应用者较全面的掌握各种常用的数据结构,提高运用数据结构解决实际问题的能力。
二、课程的基本要求本课程的教学基本要求如下:本课程要求理论必须与上机实践操作相结合,多做题和调试算法,实现算法。
实践项目只利用课堂时间是不够的,必须提前布置给学生。
通过本课程的学习与实践,学生应达到:1、掌握数据结构的基本概念和基本理论;2、熟练掌握顺序表、链表、队列、栈、树以及二叉树、图等基本数据结构的设计和分析;3、熟练地掌握常用算法(递归、遍历、查找、排序)的知识;4、能对所求解的问题进行分析,抽象出逻辑结构,选择合适的存储结构定义所需的运算,设计相应的算法;5、对算法进行分析和评价。
三、教学内容(一)理论教学(二)实践环节四、课时分配《数据结构》课程共4学分,课内72学时,其中理论课36学时,上机36学时。
五、大纲说明本课程必须理论与上机实践操作相结合,并要教、学、练相结合,讲清基本概念,指出知识要点、重点和难点,并通过实例分析解决算法难点;要求学生认真预习、认真听课、认真思索、认真做实验, 通过对算法的编程实现来提高学生 由于内容多、 难度大, 要特别注重精讲多练, 实践项目一定 要提前布置给学生, 调动学生的主观能动性,鼓励学生多提 问题、共同探讨和解决问题。
数据结构实验报告图的遍历讲解

数据结构实验报告图的遍历讲解一、引言在数据结构实验中,图的遍历是一个重要的主题。
图是由顶点集合和边集合组成的一种数据结构,常用于描述网络、社交关系等复杂关系。
图的遍历是指按照一定的规则,挨次访问图中的所有顶点,以及与之相关联的边的过程。
本文将详细讲解图的遍历算法及其应用。
二、图的遍历算法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. 创建图的数据结构首先,我们需要创建一个图的数据结构,以方便后续的操作。
图可以使用邻接矩阵或邻接表来表示,这里我们选择使用邻接矩阵。
class Graph:def__init__(self, num_vertices):self.num_vertices = num_verticesself.adj_matrix = [[0] * num_vertices for _ in range(num_vertic es)]def add_edge(self, v1, v2):self.adj_matrix[v1][v2] =1self.adj_matrix[v2][v1] =1def get_adjacent_vertices(self, v):adjacent_vertices = []for i in range(self.num_vertices):if self.adj_matrix[v][i] ==1:adjacent_vertices.append(i)return adjacent_vertices2. 深度优先搜索(DFS)DFS是一种遍历图的算法,其基本思想是从图的某一顶点开始,沿着一条路径一直走到最后,然后返回尚未访问过的顶点继续遍历,直到所有顶点都被访问过为止。
def dfs(graph, start_vertex):visited = [False] * graph.num_verticesstack = [start_vertex]while stack:vertex = stack.pop()if not visited[vertex]:print(vertex)visited[vertex] =Truefor neighbor in graph.get_adjacent_vertices(vertex):if not visited[neighbor]:stack.append(neighbor)3. 广度优先搜索(BFS)BFS同样是一种遍历图的算法,其基本思想是从图的某一顶点开始,首先访问其所有邻接点,然后再依次访问邻接点的邻接点,直到所有顶点都被访问过为止。
数据结构 第七章-图2

{DeQueue(Q,u); /*队头元素出队,并赋值给u*/
/*访问u所有未被访问的邻接点*/
for(w=0; w<G.vexnum; w++;)
if (G.arcs[u,w].adj && !visited[w])
{ visited[w]=1; Visit(w); EnQueue(Q,w); }
void DFS(Graph G, int v)
7.3 图的遍历
visited 0 0 10 20 30 40
……
{/* 从第v个顶点出发,递归地深度优先遍历图G*/
/* v是顶点在一维数组中的位置,假设G是非空图*/
visited[v] =1;
Visit(v); /*访问第v个顶点*/
for ( w=FirstAdjVex(G, v); w; w=NextAdjVex(G, v, w) )
效率。
2
7.3 图的遍历
7.3 图的遍历:从图的某顶点出发,访问图中所有顶点, 并且每个顶点仅访问一次。
图结构的遍历复杂性:
(1)在图结构中,没有一个“自然”的首结点,图中的任 意一个顶点都可以作为第一个被访问的结点
(2)在非连通图中,从一个顶点出发,只能访问它所在的 连通分量上的所有顶点,因此,还需考虑如何选取下一个出 发点以访问图中的其余连通分量
} }/*DFSAL*/
8
7.3 图的遍历
在遍历时,对图中每个顶点至多调用一次DFS函数,因为 一旦某个顶点被标志成已被访问,就不再从它出发进行搜索。 因此,遍历图的过程实质上是对每个顶点查找其邻接点的过 程。其耗费的时间则取决于所采用的存储结构。
用邻接矩阵做图的存储结构时,查找各个顶点的邻接点所 需的时间为O(n2),其中n为图中顶点数。当以邻接矩阵做存 储结构时,深度优先搜索遍历图的时间复杂度为O(n2+n)。
杭电数据结构课程设计

杭电数据结构课程设计一、课程目标知识目标:1. 学生能理解数据结构的基本概念,掌握线性表、栈、队列、树、图等常见数据结构的特点与应用。
2. 学生能描述各类数据结构的存储方式和操作方法,了解其时间复杂度和空间复杂度。
3. 学生能运用所学的数据结构知识解决实际问题,如排序、查找、最短路径等。
技能目标:1. 学生能运用编程语言(如C++、Java等)实现常见数据结构及其相关算法。
2. 学生能分析实际问题的数据特征,选择合适的数据结构进行问题求解。
3. 学生能通过课程项目实践,培养团队协作、沟通表达、问题解决等综合能力。
情感态度价值观目标:1. 学生对数据结构产生兴趣,认识到数据结构在计算机科学与软件开发中的重要性。
2. 学生在解决实际问题的过程中,培养积极探究、勇于创新的精神。
3. 学生通过团队协作,学会尊重他人、分享经验,提高沟通能力。
课程性质:本课程为计算机科学与技术专业的核心课程,旨在培养学生掌握数据结构的基本知识、技能和素养。
学生特点:学生具备一定的编程基础和数学素养,具有较强的逻辑思维能力,但对数据结构的应用和实际操作能力有待提高。
教学要求:结合课程性质和学生特点,注重理论与实践相结合,强调动手实践和实际应用,提高学生的数据结构知识水平和问题解决能力。
通过课程目标分解,将知识、技能和情感态度价值观目标融入教学过程,为后续教学设计和评估提供依据。
二、教学内容1. 线性表:介绍线性表的定义、特点、存储结构(顺序存储、链式存储),以及线性表的相关操作(插入、删除、查找等)。
教材章节:第2章 线性表2. 栈与队列:讲解栈和队列的基本概念、存储结构及操作方法,分析其应用场景。
教材章节:第3章 栈与队列3. 树与二叉树:阐述树的基本概念、存储结构、遍历方法,重点讲解二叉树的性质、存储结构、遍历算法(前序、中序、后序)及二叉树的应用。
教材章节:第4章 树与二叉树4. 图:介绍图的定义、存储结构(邻接矩阵、邻接表),图的遍历算法(深度优先搜索、广度优先搜索),以及最短路径、最小生成树等算法。
数据结构入门-树的遍历以及二叉树的创建

数据结构⼊门-树的遍历以及⼆叉树的创建树定义:1. 有且只有⼀个称为根的节点2. 有若⼲个互不相交的⼦树,这些⼦树本⾝也是⼀个树通俗的讲:1. 树是有结点和边组成,2. 每个结点只有⼀个⽗结点,但可以有多个⼦节点3. 但有⼀个节点例外,该节点没有⽗结点,称为根节点⼀、专业术语结点、⽗结点、⼦结点、根结点深度:从根节点到最底层结点的层数称为深度,根节点第⼀层叶⼦结点:没有⼦结点的结点⾮终端节点:实际上是⾮叶⼦结点度:⼦结点的个数成为度⼆、树的分类⼀般树:任意⼀个结点的⼦结点的个数都不受限制⼆叉树:任意⼀个结点的⼦结点个数最多是两个,且⼦结点的位置不可更改⼆叉数分类:1. ⼀般⼆叉数2. 满⼆叉树:在不增加树层数的前提下,⽆法再多添加⼀个结点的⼆叉树3. 完全⼆叉树:如果只是删除了满⼆叉树最底层最右边的连续若⼲个结点,这样形成的⼆叉树就是完全⼆叉树森林:n个互不相交的树的集合三、树的存储⼆叉树存储连续存储(完全⼆叉树)优点:查找某个结点的⽗结点和⼦结点(也包括判断有没有⼦结点)速度很快缺点:耗⽤内存空间过⼤链式存储⼀般树存储1. 双亲表⽰法:求⽗结点⽅便2. 孩⼦表⽰法:求⼦结点⽅便3. 双亲孩⼦表⽰法:求⽗结点和⼦结点都很⽅便4. ⼆叉树表⽰法:把⼀个⼀般树转化成⼀个⼆叉树来存储,具体转换⽅法:设法保证任意⼀个结点的左指针域指向它的第⼀个孩⼦,右指针域指向它的兄弟,只要能满⾜此条件,就可以把⼀个⼀般树转化为⼆叉树⼀个普通树转换成的⼆叉树⼀定没有右⼦树森林的存储先把森林转化为⼆叉树,再存储⼆叉树四、树的遍历先序遍历:根左右先访问根结点,再先序访问左⼦树,再先序访问右⼦树中序遍历:左根右中序遍历左⼦树,再访问根结点,再中序遍历右⼦树后续遍历:左右根后续遍历左⼦树,后续遍历右⼦树,再访问根节点五、已知两种遍历求原始⼆叉树给定了⼆叉树的任何⼀种遍历序列,都⽆法唯⼀确定相应的⼆叉树,但是如果知道了⼆叉树的中序遍历序列和任意的另⼀种遍历序列,就可以唯⼀地确定⼆叉树已知先序和中序求后序先序:ABCDEFGH中序:BDCEAFHG求后序:这个⾃⼰画个图体会⼀下就可以了,⾮常简单,这⾥简单记录⼀下1. ⾸先根据先序确定根,上⾯的A就是根2. 中序确定左右,A左边就是左树(BDCE),A右边就是右树(FHG)3. 再根据先序,A左下⾯就是B,然后根据中序,B左边没有,右边是DCE4. 再根据先序,B右下是C,根据中序,c左下边是D,右下边是E,所以整个左树就确定了5. 右树,根据先序,A右下是F,然后根据中序,F的左下没有,右下是HG,6. 根据先序,F右下为G,然后根据中序,H在G的左边,所以G的左下边是H再来⼀个例⼦,和上⾯的思路是⼀样的,这⾥就不详细的写了先序:ABDGHCEFI中序:GDHBAECIF已知中序和后序求先序中序:BDCEAFHG后序:DECBHGFA这个和上⾯的思路是⼀样的,只不过是反过来找,后序找根,中序找左右树简单应⽤树是数据库中数据组织⼀种重要形式操作系统⼦⽗进程的关系本⾝就是⼀棵树⾯向对象语⾔中类的继承关系哈夫曼树六、⼆叉树的创建#include <stdio.h>#include <stdlib.h>typedef struct Node{char data;struct Node * lchild;struct Node * rchild;}BTNode;/*⼆叉树建⽴*/void BuildBT(BTNode ** tree){char ch;scanf("%c" , &ch); // 输⼊数据if(ch == '#') // 如果这个节点的数据是#说明这个结点为空*tree = NULL;else{*tree = (BTNode*)malloc(sizeof(BTNode));//申请⼀个结点的内存 (*tree)->data = ch; // 将数据写⼊到结点⾥⾯BuildBT(&(*tree)->lchild); // 递归建⽴左⼦树BuildBT(&(*tree)->rchild); // 递归建⽴右⼦树}}/*⼆叉树销毁*/void DestroyBT(BTNode *tree) // 传⼊根结点{if(tree != NULL){DestroyBT(tree->lchild);DestroyBT(tree->rchild);free(tree); // 释放内存空间}}/*⼆叉树的先序遍历*/void Preorder(BTNode * node){if(node == NULL)return;else{printf("%c ",node->data );Preorder(node->lchild);Preorder(node->rchild);}}/*⼆叉树的中序遍历*/void Inorder(BTNode * node){if(node == NULL)return;else{Inorder(node->lchild);printf("%c ",node->data );Inorder(node->rchild);}}/*⼆叉树的后序遍历*/void Postorder(BTNode * node){if(node == NULL)return;else{Postorder(node->lchild);Postorder(node->rchild);printf("%c ",node->data );}}/*⼆叉树的⾼度树的⾼度 = max(左⼦树⾼度,右⼦树⾼度) +1*/int getHeight(BTNode *node){int Height = 0;if (node == NULL)return 0;else{int L_height = getHeight(node->lchild);int R_height = getHeight(node->rchild);Height = L_height >= R_height ? L_height +1 : R_height +1; }return Height;}int main(int argc, char const *argv[]){BTNode * BTree; // 定义⼀个⼆叉树printf("请输⼊⼀颗⼆叉树先序序列以#表⽰空结点:");BuildBT(&BTree);printf("先序序列:");Preorder(BTree);printf("\n中序序列:");Inorder(BTree);printf("\n后序序列:");Postorder(BTree);printf("\n树的⾼度为:%d" , getHeight(BTree));return 0;}// ABC##DE##F##G##。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
##大学数据结构课程设计报告题目:图的遍历和生成树求解院(系):计算机工程学院学生姓名:班级:学号:起迄日期: 2011.6.20指导教师:2010—2011年度第 2 学期一、需求分析1.问题描述:图的遍历和生成树求解实现图是一种较线性表和树更为复杂的数据结构。
在线性表中,数据元素之间仅有线性关系,每个数据元素只有一个直接前驱和一个直接后继;在树形结构中,数据元素之间有着明显的层次关系,并且每一层上的数据元素可能和下一层中多个元素(及其孩子结点)相关但只能和上一层中一个元素(即双亲结点)相关;而在图形结构中,节点之间的关系可以是任意的,图中任意两个数据元素之间都可能相关。
生成树求解主要利用普利姆和克雷斯特算法求解最小生成树,只有强连通图才有生成树。
2.基本功能1) 先任意创建一个图;2) 图的DFS,BFS的递归和非递归算法的实现3) 最小生成树(两个算法)的实现,求连通分量的实现4) 要求用邻接矩阵、邻接表等多种结构存储实现3.输入输出输入数据类型为整型和字符型,输出为整型和字符二、概要设计1.设计思路:a.图的邻接矩阵存储:根据所建无向图的结点数n,建立n*n的矩阵,其中元素全是无穷大(int_max),再将边的信息存到数组中。
其中无权图的边用1表示,无边用0表示;有全图的边为权值表示,无边用∞表示。
b.图的邻接表存储:将信息通过邻接矩阵转换到邻接表中,即将邻接矩阵的每一行都转成链表的形式将有边的结点进行存储。
c.图的广度优先遍历:假设从图中的某个顶点v出发,在访问了v之后依次访问v的各个未曾访问过的邻接点,然后再访问此邻接点的未被访问的邻接点,并使“先被访问的顶点的邻接点”先于“后被访问的顶点的邻接点”被访问,直至图中所有已被访问的顶点的邻接点都被访问到。
若此时图中还有未被访问的,则另选未被访问的重复以上步骤,是一个非递归过程。
d.图的深度优先遍历:假设从图中某顶点v出发,依依次访问v的邻接顶点,然后再继续访问这个邻接点的系一个邻接点,如此重复,直至所有的点都被访问,这是个递归的过程。
e.图的连通分量:这是对一个非强连通图的遍历,从多个结点出发进行搜索,而每一次从一个新的起始点出发进行搜索过程中得到的顶点访问序列恰为其连通分量的顶点集。
本程序利用的图的深度优先遍历算法。
2.数据结构设计:ADT Queue{数据对象:D={ai | ai∈ElemSet,i=1,2,3……,n,n≥0}数据关系:R1={<ai-1,ai>| ai-1,ai∈D,i=1,2,3,……,n}基本操作:InitQueue(&Q)操作结果:构造一个空队列Q。
QueueEmpty(Q)初始条件:Q为非空队列。
操作结果:若Q为空队列,则返回真,否则为假。
EnQueue(&Q,e)初始条件:Q为非空队列。
操作结果:插入元素e为Q的新的队尾元素。
DeQueue(&Q,e)初始条件:Q为非空队列。
操作结果:删除Q的队头元素,并用e返回其值。
}ADT QueueADT Graph{数据对象V:V是具有相同特性的数据元素的集合,称为顶点集。
数据关系R:R={VR}VR={<v,w>|v,w∈V且P(v,w),<v,w>表示从v到w的弧,谓词P(v,w)定义了弧<v,w>的意义或信息}基本操作P:CreatGraph(&G,V,VR);初始条件:V是图的顶点集,VR是图中弧的集合。
操作结果:按V和VR的定义构造图G。
BFSTraverse(G,visit());初始条件:图G存在,Visit是定点的应用函数。
操作结果:对图进行广度优先遍历。
在遍历过程中对每个顶点调用函数Visit一次且仅一次。
一旦visit()失败,则操作失败。
DFSTraverse(G,visit());初始条件:图G存在,Visit是定点的应用函数。
操作结果:对图进行广度优先遍历。
在遍历过程中对每个顶点调用函数Visit一次且仅一次。
一旦visit()失败,则操作失败。
DFStra_fen(G)初始条件:图G存在,存在图的深度优先遍历算法。
操作结果:从多个顶点对图进行深度优先遍历,得到连通分量。
}ADT Graph;3.软件结构设计:maincreatMGraph_L(G)cre atadj(gra,G)ljjzprint(G)adjprint(gra,G)BFSTraverse(gra)DFStra(gra)DFSTraverse_fen(gra)MiniSpanTree_PRIM(g,G.vexnum)MiniSpanTREE_KRUSCAL(G,gra)01234567函数名返回值类型creatMGraph_L(G) intcreatadj(gra,G) intljjzprint(G) voidadjprint(gra,G) voidBFSTraverse(gra) voidDFStra(gra) intDFSTraverse_fen(gra) int MiniSpanTree_PRIM(g,G.vexnum) intMiniSpanTREE_KRUSCAL(G,gra) void三、详细设计1.定义程序中所有用到的数据及其数据结构,及其基本操作的实现;邻接矩阵定义:typedef struct ArcCell{VRType adj;//VRType是顶点关系类型。
对无权图,用1或0表示相邻否;对带权图,则为权值类型InfoType *info;//该弧相关信息的指针}ArcCell,AdjMatrix[max][max];typedef struct{VertexType vexs[max];//顶点向量AdjMatrix arcs;//邻接矩阵int vexnum,arcnum;//图的当前顶点数和弧数}MGraph_L;邻接表的定义:typedef struct ArcNode//弧结点{int adjvex;//该弧指向的顶点的位置struct ArcNode *nextarc;//指向下一条弧的指针InfoType *info;//该弧相关信息的指针}ArcNode;typedef struct VNode//邻接链表顶点头接点{VertexType data;//顶点信息ArcNode *firstarc;//指向第一条依附该顶点的弧的指针}VNode,AdjList;typedef struct//图的定义{AdjList vertices[max];int vexnum,arcnum;//图的当前顶点数和弧数}ALGraph;队列定义:typedef struct QNode{QElemType data;struct QNode *next;}QNode,*QueuePtr;typedef struct{QueuePtr front;//队头指针QueuePtr rear;//队尾指针}LinkQueue;2.主函数和其他函数的伪码算法;主函数:int main(){int s;char y='y';cout<<"||¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤菜单¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤||"<<endl;cout<<"||-------------------------【0、创建一个无向图------------------------------||"<<endl;cout<<"||-------------------------【1、显示该图的邻接矩阵--------------------------||"<<endl;cout<<"||-------------------------【2、显示该图的邻接表----------------------------||"<<endl;cout<<"||-------------------------【3、广度优先遍历--------------------------------||"<<endl;cout<<"||-------------------------【4、深度优先遍历--------------------------------||"<<endl;cout<<"||-------------------------【5、最小生成树MiniSpanTree_PRIM 算法-------------||"<<endl;cout<<"||-------------------------【6、最小生成树MiniSpanTree_KRUSCAL算法----------||"<<endl;cout<<"||-------------------------【7、连通分量------------------------------------||"<<endl;cout<<"||¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤||"<<endl;while(y=='y'){cout<<"请选择菜单:"<<endl;cin>>s;if(s==0){++o;if(o==2){n=0;l=0;o=0;}}switch(s){case 0:cout<<"创建一个无向图:"<<endl;MGraph_L G;creatMGraph_L(G);ALGraph gra;creatadj(gra,G);break;case 1:cout<<"邻接矩阵显示如下:"<<endl;ljjzprint(G);break;case 2:cout<<"邻接表显示如下:"<<endl;adjprint(gra,G);break;case 3:cout<<"广度优先遍历:";BFSTraverse(gra);cout<<endl;break;case 4:cout<<"深度优先遍历:";DFStra(gra);cout<<endl;break;case 5:if(n==0){cout<<"无权图没有最小生成树";break;}else if(l>0){cout<<"若该图为非强连通图(含有多个连通分量)时,最小生成树不存在"<<endl;break;}else{int i,g[max][max];for(i=0;i!=G.vexnum;++i)for(int j=0;j!=G.vexnum;++j)g[i+1][j+1]=G.arcs[i][j].adj;cout<<"普利姆算法:"<<endl;MiniSpanTree_PRIM(g,G.vexnum);break;}case 6:if(n==0){cout<<"无权图没有最小生成树";break;}else if(l>0){cout<<"该图为非强连通图(含有多个连通分量),最小生成树不存在"<<endl;break;}else{cout<<"克鲁斯卡尔算法:"<<endl;MiniSpanTREE_KRUSCAL(G,gra);break;}case 7:cout<<"连通分量:"<<endl;DFSTraverse_fen(gra);break;}cout<<endl<<"是否继续?y/n:";cin>>y;if(y=='n')break;}return 0;}邻接矩阵存储:int creatMGraph_L(MGraph_L &G)//创建图用邻接矩阵表示{char v1,v2;int i,j,w;cout<<"请输入顶点和弧的个数"<<endl;cin>>G.vexnum>>G.arcnum;cout<<"输入各个顶点"<<endl;for(i=0;i<G.vexnum;++i){cin>>G.vexs[i];}for(i=0;i<G.vexnum;++i)for(j=0;j<G.vexnum;++j){G.arcs[i][j].adj=int_max;G.arcs[i][j].info=NULL;}for(int k=0;k<G.arcnum;++k){cout<<"输入一条边依附的顶点和权"<<endl;cin>>v1>>v2>>w;//输入一条边依附的两点及权值i=localvex(G,v1);//确定顶点V1和V2在图中的位置j=localvex(G,v2);G.arcs[i][j].adj=w;G.arcs[j][i].adj=w;}for(i=0;i!=G.vexnum;++i)for(j=0;j!=G.vexnum;++j){if(G.arcs[i][j].adj!=1&&G.arcs[i][j].adj<int_max)n+=1;}if(n>=1)cout<<"这是一个有权图"<<endl;else cout<<"这是一个无权图"<<endl;cout<<"图G邻接矩阵创建成功!"<<endl;return G.vexnum;}邻接矩阵的输出:void ljjzprint(MGraph_L G) //邻接矩阵的输出{int i,j;if(n==0){for(i=0;i!=G.vexnum;++i){for(j=0;j!=G.vexnum;++j){if(G.arcs[i][j].adj==int_max){cout<<"0"<<" ";}else {cout<<G.arcs[i][j].adj<<" ";}}cout<<endl;}}else{for(i=0;i!=G.vexnum;++i){for(j=0;j!=G.vexnum;++j){if(G.arcs[i][j].adj==int_max){cout<<"∞"<<" ";}else {cout<<G.arcs[i][j].adj<<" ";}}cout<<endl;}}}用邻接表存储图:int creatadj(ALGraph &gra,MGraph_L G)//用邻接表存储图{int i=0,j=0;ArcNode *arc;//,*tem,*p;for(i=0;i!=G.vexnum;++i){gra.vertices[i].data=G.vexs[i];gra.vertices[i].firstarc=NULL;}for(i=0;i!=G.vexnum;++i)for(j=0;j!=G.vexnum;++j){if(G.arcs[i][j].adj!=int_max){arc=(ArcNode *)malloc(sizeof(ArcNode));arc->adjvex=j;arc->nextarc=gra.vertices[i].firstarc;gra.vertices[i].firstarc=arc;}}gra.vexnum=G.vexnum;gra.arcnum=G.arcnum;cout<<"图G邻接表创建成功!"<<endl;return 1;}邻接表输出:void adjprint(ALGraph gra,MGraph_L G) //邻接表输出{int i;for(i=0;i!=gra.vexnum;++i){ArcNode *p;cout<<"["<<i<<","<<G.vexs[i]<<"]";p=gra.vertices[i].firstarc;while(p!=NULL){cout<<"->"<<"["<<p->adjvex<<"]";p=p->nextarc;}cout<<"->"<<"End";cout<<endl;}}初始化队列:Status InitQueue(LinkQueue &Q)//初始化队列{Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));if(!Q.front)return 0;//存储分配失败Q.front->next=NULL;return 1;}入队:Status EnQueue(LinkQueue &Q,QElemType e)//入队,插入元素e为Q的新的队尾元素{QueuePtr p;p=(QueuePtr)malloc(sizeof(QNode));if(!p)return 0;//存储分配失败p->data=e;p->next=NULL;Q.rear->next=p;Q.rear=p;return 1;}出队:Status DeQueue(LinkQueue &Q,QElemType &e)//出队,若队列不空,则删除Q 的队头元素,用e返回,并返回真,否则假{QueuePtr p;if(Q.front==Q.rear)return 0;p=Q.front->next;e=p->data;Q.front->next=p->next;if(Q.rear==p)Q.rear=Q.front;free(p);return 1;}判断队为空:Status QueueEmpty(LinkQueue Q)//判断队为空{if(Q.front==Q.rear) return 1;return 0;}广度优先遍历:void BFSTraverse(ALGraph gra){int i,e;LinkQueue q;for(i=0;i!=gra.vexnum;++i)visited[i]=0;InitQueue(q);for(i=0;i!=gra.vexnum;++i)if(!visited[i]){visited[i]=1;cout<<gra.vertices[i].data;EnQueue(q,i);while(!QueueEmpty(q)){DeQueue(q,e);for(we=firstadjvex(gra,gra.vertices[e]);we>=0;we=nextadjvex(gra,g ra.vertices[e],we)){if(!visited[we]){visited[we]=1;cout<<gra.vertices[we].data;EnQueue(q,we);}}}}}深度优先遍历:int DFS(ALGraph gra,int i){visited[i]=1;int we1;cout<<gra.vertices[i].data;for(we=firstadjvex(gra,gra.vertices[i]);we>=0;we=nextadjvex(gra,g ra.vertices[i],we)){we1=we;if(visited[we]==0)DFS(gra,we);we=we1;}return 1;}int DFStra(ALGraph gra){int i,j;for(i=0;i!=gra.vexnum;++i){visited[i]=0;}for(j=0;j!=gra.vexnum;++j){if(visited[j]==0)DFS(gra,j);}return 0;}连通分量:int DFSTraverse_fen(ALGraph gra) {int i,j;for(i=0;i!=gra.vexnum;++i)visited[i]=0;for(j=0;j!=gra.vexnum;++j){if(visited[j]==0){DFS(gra,j);cout<<endl;l++;}}return 0;}3.主要函数的程序流程图,实现设计中主程序和其他子模块的算法,以流程图的形式表示。