目录
二O二三年 12月28日
数据结构与算法课程设计
设计要求 (1)分组后,每组抽取一个题目,每人完成该题目
的一个功能模块的设计;
(2)winform应用程序实现(代码须锯齿型书写格式);
(3)必须上机调试通过;
(4)每人单独完成一份完整的课程设计报告。
课 题 发 给 日 期 2023年11月15日
1、程序功能菜单等界面设计情况:
2、功能全面,是否达到设计要求:
3、答辩情况:
4、课设报告完成情况:
5、出勤情况:
评分:
C数据结构课程设计任务书
一、课程设计的目的
数据结构课程主要是研究非数值计算的程序设计问题中所出现的计算机操作对象以及它们之间的关系和操作的学科。数据结构是介于数学、计算机软件和计算机硬件之间的一门计算机专业的核心课程,它是计算机程序设计、数据库、操作系统、编译原理及人工智能等的重要基础,广泛的应用于信息学、系统工程等各种领域。学习数据结构是为了将实际问题中所涉及的对象在计算机中表示出来并对它们进行处理。通过课程设计可以提高学生的思维能力,促进学生的综合应用能力和专业素质的提高。通过此次课程设计主要达到以下目的:
1、了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力;
2、初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方 法和技能;
3、提高综合运用所学的理论知识和方法独立分析和解决问题的能力; 训练用系统的观点和软件开发一般规范进行软件开发,培养软件工作者所应具备的科学的工作方法和作风。
二、课程设计报告的内容
1、课程设计题单(封面)
2、任务书
3、前言,需求分析(鼓励设置目录)
4、概要设计(程序设计组成框图、流程图)
5、详细设计(模块功能说明(如函数功能、入口及出口参数说明,函数调用关系描述等)
6、源程序清单和执行结果:清单中应有足够的注释
7、用户使用说明
8、调试与测试:调试方法,测试结果的分析与讨论,测试过程中遇到的主要问题及采取的解决措施
9、附录或参考资料
三、课程设计上机安排及分组情况
1、分组情况:
2、上机地点:
3、上机时间:
4、指导教师:
四、课程设计成绩评定办法
1、评分范围及权重:
(1)课程设计报告(40%);
(2)课程设计源程序(40%);
(3)平时成绩(20%)。
2、课程设计报告评定办法:根据课程设计报告的质量,如有雷同,则所有雷同的所有人均判为不及格。
3、课程设计源程序评定办法:根据课程设计完成情况,必须有可运行的软件,学生能面对教师提问并能熟练地解释清楚自己的程序。
4、平时成绩评定办法:根据平时上机考勤及表现,教师将不定期检查学生进度,学生不得以自己有私人电脑为借口而不来上机。
注意:所有材料于最后一次上机结束后提交,否则不予评定成绩。
前言
随着信息时代的来临,数据已成为我们生活和工作中不可或缺的元素。如何有效地存储、管理和操作这些数据已成为计算机科学领域的重要问题。在计算机科学中,数据结构是组织、存储和处理数据的重要方式。二叉树作为一种基本的数据结构,在解决这些问题中发挥着关键作用,因其高效的搜索、插入和删除操作,以及灵活的层次结构,在许多算法和程序设计中都占据着重要的地位。
本课程设计报告的目标是深入理解二叉树的原理和实现方式,掌握如何建立二叉树以及如何在实际情况中应用二叉树解决实际问题。创建一棵二叉树的关键在于如何将一个一个的节点按照树的脉络连接起来,通过实际编码和实验,我们将熟悉二叉树的建立过程,理解如何构建一个有效的二叉树。我们将通过具体的编程实现,来探索如何建立二叉树,这包括节点的动态输入,动态生成树等操作。在此过程中,我们将关注如何保证二叉树的有效的搜索和遍历。本课程设计报告将通过理论学习和实践操作相结合的方式,帮助我们深入理解二叉树的基本构成原理。这将为我们今后在计算机科学领域的学习和工作打下坚实的基础。
一、需求分析
输入形式与输入值的范围:首先,我们需要确定输入的形式。考虑到二叉树是由节点组成,每个节点包含数据和指向左右子节点的指针,因此输入应为一串表示节点数据的字符串。此外,为了建立二叉树,我们需要确定输入值的范围。对于节点的数据,它可以是一串字符或数字。
输出形式:为了验证二叉树的建立是否正确,我们需要将其输出。输出的形式是控制台打印和动画显示。在控制台打印中,我们可以按照层次顺序或遍历的方式输出二叉树的结构。在动画显示中,我们将显示二叉树根据前序中序动态生成的过程。
程序功能:根据需求分析,程序需要实现以下功能:根据前序和中序建立一棵二叉树,前序遍历的顺序为“根-左-右”,中序遍历的顺序为“左-根-右”。
测试数据:为了验证程序的正确性,我们需要提供一些测试数据。测试数据可以是多个字符串,每个字符串代表一个节点。例如,"前序 GDAFEMHZ,中序ADEFGHMZ "表示一个有8个节点的二叉树。
异常处理:在输入数据的过程中,可能会出现异常情况,如输入格式错误、节点数据无效等。因此,程序需要具备一定的异常处理能力,以应对这些情况的发生。例如,当输入格式错误时,程序应给出相应的错误提示;当节点数据无效时,程序应重新请求输入有效的节点数据。
、概要设计
2.1程序流程图
三、详细设计
3.1 binary_tree.h
模板类型声明,声明二叉树节点,以及释放二叉树函数。
template <typename _Ty>
struct bt_node {
_Ty data;
int level;
node_position pos;
bt_node* lchild;
bt_node* rchild;
};
inline void bt_destroy(binary_tree<_Ty>& _Tree) {
if (_Tree == nullptr) {
return;
}
bt_destroy(_Tree->lchild);
bt_destroy(_Tree->rchild);
delete _Tree;
_Tree = nullptr;
}
3.2 bt_builder.h
构建二叉树具体逻辑和函数入口。
inline void bt_build_page() {
ege::initgraph(DISPLAY_W, DISPLAY_H);
ege::setbkcolor(WHITE);
ege::delay_ms(550);
clear();
title_display("Data Structure Display - 前序&中序构造二叉树");
ege_title("前序&中序构造二叉树");
char pre_s[128]{ 0 }, in_s[128]{ 0 };
title_display("请输入字符串");
split();
input("前序遍历字符串 = ");
std::cin >> pre_s;
input("中序遍历字符串 = ");
std::cin >> in_s;
size_t pre_len = std::strlen(pre_s);
size_t in_len = std::strlen(in_s);
std::map<char, int> pre_map, in_map;
for (int i = 0; i < pre_len; i++) {
++pre_map[pre_s[i]];
}
for (int i = 0; i < in_len; i++) {
++in_map[in_s[i]];
}
if (!(pre_len && in_len) || pre_map != in_map) {
bt_build_failure();
bt_build_page();
return;
}
int ps_width = ege::textwidth("前序:");
float char_width = ege::textwidth(' ');
float char_height = ege::textheight(' ');
float start_x = center_position(0, DISPLAY_W, ps_width + char_width * pre_len);
string({ start_x, TEXTS_Y }, "前序:", "等线").draw();
string({ start_x, TEXTS_Y + char_height }, "中序:", "等线").draw();
built_char* pre_ss = new built_char[pre_len];
built_char* in_ss = new built_char[in_len];
for (int i = 0; i < pre_len; i++) {
pre_ss[i] = { pre_s[i], { { start_x + ps_width + char_width * i, TEXTS_Y }, std::string(1, pre_s[i]), "Consolas"}};
in_ss[i] = { in_s[i], { { start_x + ps_width + char_width * i, TEXTS_Y + char_height }, std::string(1, in_s[i]), "Consolas"}};
pre_ss[i].s.draw();
in_ss[i].s.draw();
bt tree = nullptr;
dsd::title_display("构造过程");
dsd::split();
printf("* 字符 层次 *\n");
tree = bt_build(pre_ss, in_ss, pre_len, 1, node_position{}, nullptr);
split();
printf("* 按任意键以返回...\n< ");
wait_key();
ege::closegraph();
bt_destroy(tree);
delete[] pre_ss;
delete[] in_ss;
}
四、源程序清单和运行结果
#define _CRT_SECURE_NO_WARNINGS 1
#include "drawer.h"
#include"DSDisplay.h"
#include "bt_builder.h"
extern char wait_key();//extern 关键字用于声明一个外部函数,表示该函数定义在其他文件中
bool attribute() {
dsd::clear();//于清除绘图区域或屏幕的内容。
dsd::title_display("Data Structure Display - Group 14");
dsd::title_display("目录");
dsd::split();
dsd::option('B', "前序&中序构造二叉树");
dsd::option('Q', "退出");
dsd::split();
printf("* 按下键盘以选择功能...\n< ");
switch (wait_key()) {
case 'B':
dsd::bt_build_page();//前序&中序构造二叉树
break;
case 'Q':
printf("Q | 退出\n");
return false;
default:
break;
};
return true;
}
int main() {
ege::setfont(-18, 0, "Consolas");//用于设置绘图时所使用的字体
while (attribute());//如果 attribute() 函数返回 true,那么 while 循环将重复执行,直到 attribute() 函数返回 false 才会停止
dsd::output("感谢您的使用!");
ege::closegraph();
//前序遍历字符串 = GDAFEMHZ
//中序遍历字符串 = ADEFGHMZ
}
五、用户使用说明
1.简介
二叉树是一种重要的数据结构,广泛应用于计算机科学领域。本用户使用说明将指导您如何建立二叉树。
2.操作步骤
输入节点信息:按照层次顺序,依次输入结点信息,每进入一个字符建立一个节点, 无论是否为虚拟节点,虚拟节点下可以继续接入虚拟节点。 若是第一个结点,则令其为根结点,否则将新结点插入到它的双亲结点上。
创建结构体实现树的建立:对于树而言,依旧采取结构体指针的方式,树拥有着一个左子树,一个右子树和一个储存数据的位置。先分配空间,再将左子树和右子树的位置全部变为空即可。
在二叉树的左子树和右子树中插入结点:
判断当前的树是否为空树:这是插入结点的第一步,因为如果树是空的,那么就无法进行插入操作。
先保存当前结点的(左/右)子树:创建一个新的结点,然后将新创建的结点设置指向数值。
将新创建的结点设置指向数值,然后插入设置结点和所保存子树之间(注意顺序:先和子树连接,再和当前结点连接):这是插入结点的关键步骤,需要按照特定的顺序进行操作。
返回所插入的值:完成插入操作后,函数会返回插入的结点的值,以供后续操作使用。
对建立的二叉树进行遍历:二叉树的遍历方法有前序遍历、中序遍历和后序遍历。可以根据实际需要选择适合的遍历方法。
3.注意事项
在输入节点信息时,请确保按照层次顺序输入,并注意结束符号的使用。
在创建结构体实现树的建立时,请确保正确分配空间并初始化子树指针。
在插入节点时,请确保当前树不为空,并按照正确的顺序进行操作。
在进行遍历时,请选择适合的遍历方法并注意顺序。
六、调试与测试
调试时主要遇到的问题是未经处理的异常,堆已损坏。经过查找资料了解到发生这个问题的主要原因是:
(1)对已经析构的对象,重新析构;
(2)对已经释放的变量,再次引用;
(3)数组越界访问,或者赋值;
(4)未对申请的空间进行释放;
由于目前所学知识不够完善,对代码进行多次修改与调试,还是未能解决这个问题。但是使用release编译的版本是没有出现此问题的。
参考资料
- 《数据结构(C语言版)》(Data Structure),严蔚敏、吴伟民著,清华大学出版社。
- 《算法导论》(Introduction to Algorithms),Cormen,T.H.著,机械工业出版社。
- 《C语言程序设计》(C programming),徐立辉、刘冬莉著,清华大学出版社。
项目报告文件下载
课程设计文档下载https://download.youkuaiyun.com/download/L152690/89246895