广州大学学生实验报告
开课实验室:计算机科学与工程实验(电子楼417) 2018年05月31日
学院 |
计算机科学与教育软件学院 |
年级、专业、班 |
网络161 |
姓名 |
卟咚君 |
学号 |
1606100*** |
|
实验课程名称 |
数据结构实验 |
成绩 |
|
|||||
实验项目名称 |
实验三:图的遍历生成树 |
指导老师 |
** |
|||||
一、实验目的 1、把图转化为程序能识别的邻接矩阵; 2、理解图的遍历方法及对应的生成树。 二、使用仪器、器材 微机一台 操作系统:WinXP 编程软件:C++ 三、实验内容及原理 实验内容: 图的输入:邻接矩阵直接写入源程序,或键盘输入,或读入数据文件 起始结点的输入:运行时由键盘输入 输出:生成树的边,用结点的序偶表示,例如 (1,3) 思路:定义一个class类Edge为图的边 定义一个class类Vertex为图的点 定义一个class类Graph为图 图的顶点个数和邻接矩阵由键盘输入,在图中存储了图的邻接矩阵,另外图中的每一个结点都有相应的data值和一个链首,链表存储的是这个顶点的连边,边上有相应的边权和目标点。插入一个新的结点的data值,插入一条新的连边,修改和撤销原本存在的连边,按照树的序偶表示的方式输出图的连边和输出图的邻接矩阵,以及深度和广度优先遍历生成一棵树(或者森林)的操作基本是在点和点的边的链表之间的操作。在 按照树的序偶表示的方式输出图的连边时,由于可能一条边遍历的时候会输出两次,需要标记已经输出的边,防止重复。在输出图的邻接矩阵时,由于在上述的操作中,基本是对点和点的边链表进行操作的,需要按照目前链表的信息更新图的邻接矩阵的信息,再输出。在深度优先生成一棵树(或者森林)输出的时候,由于可能是不连通图,先把键盘输入的起始点的深度优先遍历的图输出(void DFSprint(int s)),标记输出的点,然后遍历图中所有的点,查找没有遍历过的点,再对它进行深度优先遍历(函数void DFS(int s) ),再标记输出的点,重复这个操作,直到所有的点输出。在广度优先生成一棵树(或者森林)时,由于可能是不连通图,先把键盘输入的起始点的广度优先遍历的图输出(void DFSprint(int s)),标记输出的点,然后遍历图中所有的点,查找没有遍历过的点,再对它进行广度优先遍历(函数void DFS(int s) ),再标记输出的点,重复这个操作,直到所有的点输出。 #include<iostream> using namespace std; template<typename DistType> class Edge { public: Edge(int dest, DistType cost) : dest(dest), cost(cost), next(NULL) {}
public: int dest; DistType cost; Edge<DistType> *next;
}; template<typename NameType, typename DistType> class Vertex { public: Vertex() : adj(NULL) {} NameType data; Edge<DistType> *adj; ~Vertex(); }; template<typename NameType, typename DistType> Vertex<NameType, DistType>::~Vertex() { Edge<DistType> *pmove = adj; while (pmove) { adj = pmove->next; delete pmove; pmove = adj; } } template<typename NameType, typename DistType> class Graph { public: Graph(int size = DefaultSize); //建立一个有size个结点的图 ~Graph(); bool GraphEmpty() const { //判断图是否为空图 return 0 == numvertex; } bool GraphFull() const { //判断图是否已满 return MaxNum == numvertex; } int NumberOfVertex() const { //返回图中结点的个数 return numvertex; } int NumberOfEdge() const { //返回图中的边的个数 return numedges; } void intputGraph(DistType maps[][100]); NameType GetValue(int u); //返回图中结点v的data DistType GetWeight(int u, int v); //返回结点u和结点v之间的连边的边权 bool InsertVertex(int u, const NameType Data); //在结点u插入新的Data值 bool Removevertex(int u); //移除结点u bool InsertEdge(int v1, int v2, DistType weight = Infinity); //在结点u和结点v之间插入边Cost bool RemoveEdge(int v1, int v2); //移除u和v之间的连边 void Print(); //输出图 void Print2(); //输出图 int Getvertexpos(const NameType Data); //返回结点data==vertex的结点序号 void DFSprint(int s); //深度优先生成一棵树(或者森林) void DFS(int s); //深度优先生成一棵树 void BFSprint(int s); //广度优先生成一棵树(或者森林) void BFS(int s); //广度优先生成一棵树 private: Vertex<NameType, DistType> *nodetable; //图的结点,用链表的方式存储 int numvertex; //图中结点的总数 const int MaxNum; //图中最大能存储的结点总数 static const int DefaultSize = 10; //默认情况下图的最大能存储的结点总数 static const DistType Infinity = -1; //当边权==Infinity == -1时,默认为边权无穷大,对应的两点之间没有边相连 int numedges; //图中的边数 bool *flag; //标记数组 DistType map[100][100]; //图的邻接矩阵 }; template<typename NameType, typename DistType> Graph<NameType, DistType |