数据结构课程设计报告 .doc
《数据结构课程设计报告 .doc》由会员分享,可在线阅读,更多相关《数据结构课程设计报告 .doc(47页珍藏版)》请在三一办公上搜索。
1、计算机与信息学院数据结构课程设计实验报告专 业 班 级计算机074班学生姓名及学号课程教学班号0002任 课 教 师实验指导教师实验地点2008 2009 学年第 二 学期题目1:设计程序完成如下功能:对给定的图结构,用Kruskal算法的基本思想求解图的最小生成树,并给出动态演示过程题目2:设计一个模拟计算器的程序,要求能包含加、减、乘、除、括号运算符,以及SQRT和ABS对任意整型表达式进行求解。 要求:要检测运算执行的条件并给出错误警报 一、动态演示Kruskal算法1、题目分析及建立模型在图的算法中,求最小生成树有着十分重要的理论和现实意义,二Kruskal算法正是求解这一问题的经典算
2、法。Kruskal算法的主要思想即是通过不断地寻求满足一定条件(即所选边不能构成环)的最小权值的边,直至找出图的最小生成树为止。为了能够动态地演示Kruskal算法求解最小生成树的过程,首先的问题是如何动态的建立一个图,然后的问题才是怎样动态地演示Kruskal算法。所以为了解决这个问题,我从这两个方面逐一入手进行求解,利用MFC的知识进行演示。2、算法的设计与具体的设计思路A、程序界面的设计 首先为了建立一个图,需要知道一个图的节点数,由于界面有限,这里将节点数限制在8以内(包括8),超出8个将会给出提示。所以在程序界面中必须有图节点数目的输入,这里设计了一个编辑框用于输入图的节点数目。另外
3、,一个完整的图还必须有一定的边信息,包括边的起始端点和权值,以便求解最小生成树。而这些信息完全是由用户确定的,并且由用户输入的图的节点数确定。这里在用于输入节点数的编辑框下设置两个列表框和一个编辑框分别用于边的起始端点和权值的输入。另外,为了使节点数和边信息产生关联,这里又设置了一个“应用”按钮,为了将边信息与图相关联,又设置了一个“增加边”按钮,最后还有一个“动态演示Kruskal算法”的操作按钮以及一个退出按钮。此外,在界面的右端设置一个图形演示区,已进行动态演示。完整的程序界面如下:B、按钮响应函数的设计 在上述界面中有三个主要按钮,分别是“应用”“增加边”以及“动态演示Kruskal算
4、法,下面分别设计其响应函数 “应用”按钮的主要作用是把图的节点数和边信息和图相关联。用户在编辑框m_vexnum中输入结点,然后点击“应用”按钮后,在两个列表框m_Start和m_End中自动添加n各结点,同时在演示区中画出n个节点,如下所示:为了关联相关信息,在CsmileGraph1Dlg中增加如下变量:Graph graph; int vexnum;在按钮的响应函数OnApply()中完成如下功能,一是在初始化图graph:/初始化一个图graph.graph_vexnum = 0;for(int j = 0; j 8; j+)graph.data j = (char)(A+j);for
5、(int i = 0; i 8; i+)for(int j = 0; j 8; j+)graph.AdjMatrix ij = graph.AdjMatrix ji =INF;二是将编辑框中的内容与图和列表框关联起来同时在演示区中绘制n个节点,如下所示:/输入图的节点数CString s ;m_vexnum.GetWindowText (s);int v_num = (int)atoi(s); /添加图的相关参数graph.graph_vexnum = v_num;for(int t = 0; t graph.graph_vexnum ; t+)graph.data t = (char)(A+
6、t);if(v_num0) Draw(v_num);else if(v_num8)MessageBox(请输入1到8之间的一个数!);elseMessageBox(你还没有输入结点数!);m_Start.ResetContent();m_End.ResetContent ();for(int k = 0; k v_num; k+)m_Start.AddString (VexNodek);m_End.AddString (VexNodek);为了在演示区中绘制n个结点,在OnApply函数中调用函数Draw(v_num);在函数Draw(int n)中绘制n个节点,为了限制结点个数,在演示区中固
7、定了8个点供演示。这8个点的组成形式如下:将这8个点保存在Point数组point中,同时以这8个点为中心作8个矩形Rect rcDraw8保存图的结点的外接矩形,并根据m_vexnum的大小利用MFC绘图函数绘制m_vexnum内切圆作为图的结点。“增加边”按钮的主要功能是输入图的边信息并与图关联起来,为此在CsmileGraph1Dlg类中增加变量Edge edge56用于保存用户输入的边信息。用户通过两个列表框选择一条边的两个端点并把其权值输入到下面的编辑框中,然后单击“增加边”按钮即可完成:在演示区中绘制一条边并显示其权值,修改图graph的边信息,即改变其邻接矩阵值。这里规定:两次输
8、入同一条边、输入的结点不存在、结点相同均视为无效,并给出提示,演示如下: 无效输入一、一条边的两个端点相同 无效输入二、输入边已经存在正常情况下可得到如下所示的图:以上效果均通过按钮的响应函数OnAddEdge()来实现:int start,end;/保存一条边的两个端点start = m_Start.GetCurSel (); end = m_End.GetCurSel (); CString val ; m_Value.GetWindowText (val);/获取权值 int value = atoi(val); /处理特殊情况 if(graph.AdjMatrixstartend!=I
9、NF) MessageBox(改边已经存在); else if(start=LB_ERR|end=LB_ERR) MessageBox(结点不存在!); else if(start=end) MessageBox(起始端点不应为同一结点!); else /增加图的边 edgeedge_num.start = start; edgeedge_num.end = end; edgeedge_num.val = value; edge_num+;/边数/修改图的邻接矩阵 graph.AdjMatrix startend = graph.AdjMatrix endstart = value; Draw
10、Edge(start,end,val);/绘制两个端点分别为start和/end,权值为val的边 在OnAddEdge()函数中调用了一个绘制边的函数DrawEdge(int,int,int),三个参数分别表示新增边的起始端点序号和权值,这里成为“起始端点”只是表述方便,实际上所建立的是无向图。而在函数DrawEdge中,主要利用了MFC的绘图函数Ellipse()、LineTo()、TextOut()等,具体实现细节请见源码,这里不再赘述。“动态演示Kruskal算法”的响应函数为本题的核心,Kruskal算法的实现在此。这里先说明一下此按钮的功能:用户按下此按钮后,将在演示区中动态的寻求
11、最小权值的边并用差异颜色重画以达到突出的目的,依次找出所有的符合条件的边后,擦除其他边只显示最小生成树的各边,具体过程如下:图1、动态寻找过程 图2、最终结果 下面介绍一下Kruskal算法的实现思想,因为Kruskal算法是不断的从图的边中寻求权值最小的边,所以首先对图的所有边按权值进行排序,这里使用快速排序,因此在CsmileGraph1Dlg中又增加了两个成员函数partition()和qiuck_sort()来实现数组edge的排序工作。接下来就是不断的从排好序边中依次选取满足条件的边。这里满足的【条件】是指所选边和之前所选边不能构成环。为此,特设置两个标志数组visited和is_m
12、in_tree分别标记结点和边是否已被选中。如果visitedi = visitedj或者is_min_treei,j=true说明再选取边(i,j)即会构成环,应当舍弃,继续往下寻找,直至找出含有n的节点的n-1个最小生成树的n-1条边,这里需要进行n-1趟循环。3、程序实现A、图的实现 本题采用邻接矩阵存储图,定义一个Graph和Edge结构体分别保存图的具体信息和边信息。定义如下:struct EdgeNodeint start;/起点int end;/终点int val;/权值;struct Graphint AdjMatrix88;/邻接矩阵char data8;/节点值int gr
13、aph_vexnum;/节点数;B、排序的实现void CSmileGraph1Dlg:partition(EdgeNode *edge, int s, int t, int &cutpoint) EdgeNode tmp; tmp.start = edges.start ; tmp.end = edges.end;tmp.val = edges.val ; int i = s; int j = t; while(ij) while(i edgei.val) j-; if(ij) edgei.start = edgej.start; edgei.end = edgej.end;edgei.va
14、l = edgej.val;i+; while(ij&edgei.val edgej.val) i+; if(ij) edgej.start = edgei.start; edgej.end = edgei.end;edgej.val = edgei.val;j-; edgei.start = tmp.start; edgei.end = tmp.end;edgei.val = tmp.val;cutpoint = i; void CSmileGraph1Dlg:quick_sort(EdgeNode *edge, int s, int t)if(st)int i;partition(edge
15、,s,t,i);/取得划分点quick_sort(edge,s,i-1);/对左半部分进行快速排序quick_sort(edge,i+1,t);/对右半部分进行快速排序C、Kruskal算法的实现/把图的边按照权值大小排序quick_sort(edge,0,edge_num-1);int visited8 ;/标记每一条支边的端点以判断是否形成回路for(i=0;i8;i+)visitedi = i;/初始化int min = INF;int min_start,min_end;/标志数组判断某一边是否为最小生成树的一支bool is_min_tree88;/标记一条边是否被选中for(min
16、_start = 0; min_start8 ; min_start+)for(min_end = 0; min_end8 ; min_end+)is_min_treemin_startmin_end = is_min_treemin_endmin_start = false;/初始化 int count = 0;/Kruskal算法演示1: 排序法for(int s = 0; s graph.graph_vexnum - 1; s+)if(countedge_num) int m = edgecount.start; int n = edgecount.end;while(visitedm=
17、visitedn)/找不能构成环的边 count+; m = edgecount.start; n = edgecount.end;/如果边不能构成环,则记录并绘制改边if(visitedm!=visitedn&!is_min_treemn&!is_min_treenm) min_start = m; min_end = n; min = edgecount.val; count+; for(int k = 0; k graph.graph_vexnum; k+)if(visitedk=visitedmin_end|visitedk=min_end)visitedk = visitedmin_
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构课程设计报告 数据结构 课程设计 报告
![提示](https://www.31ppt.com/images/bang_tan.gif)
链接地址:https://www.31ppt.com/p-2396801.html