上机实验习题
上机实验要求及规范
C程序设计具有比较强的理论性,同时也具有较强的可应用性和实践性。在上机实验是一个重要的教学环节。具体实习步骤如下:
1.问题分析与系统结构设计
充分地分析和理解问题本身,弄清要求做什么(而不是怎么做),限制条件是什么。按照以数据结构为中心的原则划分模块,搞清数据的逻辑结构(是线性表还是树、图?),确定数据的存储结构(是顺序结构还是链表结构?)。然后设计有关操作的函数。在每个函数模块中,要综合考虑系统功能,使系统结构清晰、合理、简单和易于调试。最后写出每个模块的算法头和规格说明,列出模块之间的调用关系(可以用图表示),便完成了系统结构设计。
3.上机准备
熟悉高级语言用法,如C语言。熟悉机器(即操作系统),基本的常用命令。静态检查主要有两条路径,一是用一组测试数据手工执行程序(或分模块进行);二是通过阅读或给别人讲解自己的程序而深入全面地理解程序逻辑,在这个过程中再加入一些注释和断言。如果程序中逻辑概念清楚,后者将比前者有效。
4.上机调试程序
调试最好分块进行,自底向上,即先调试底层函数,必要时可以另写一个调用驱动程序,表面上的麻烦工作可以大大降低调试时所面临的复杂性,提高工作效率。
5.整理实习报告
在上机实开始之前要充分准备实验数据,在上机实践过程中要及时记录实验数据,在上机实践完成之后必须及时总结分析。写出实验报告。
一、实验报告的基本要求:
一般性、较小规模的上机实验题,必须遵循下列要求。养成良好的习惯。
(1)姓名 班级 学号 日期
(2)题目:内容叙述
(3)程序清单(带有必要的注释)
(4)调试报告:
实验者必须重视这一环节,否则等同于没有完成实验任务。这里可以体现个人特色、或创造性思维。具体内容包括:测试数据与运行记录;调试中遇到的主要问题,自己是如何解决的;经验和体会等。
二、实验习报告的提高要求:
阶段性、较大规模的上机实验题,应该遵循下列要求。养成科学的习惯。
(1)需求和规格说明
描述问题,简述题目要解决的问题是什么。规定软件做什么。原题条件不足时补全。
(2)设计
a.设计思想:存储结构(题目中限定的要描述);主要算法基本思想。
b.设计表示:每个函数的头和规格说明;列出每个函数所调用和被调用的函数,也可以通过调用关系图表达。
c.实现注释:各项功能的实现程度、在完成基本要求的基础上还有什么功能。
(3)用户手册:即使用说明。
(4)调试报告:调试过程中遇到的主要问题是如何解决的;设计的回顾、讨论和分析;时间复杂度、空间复杂度分析;改进设想;经验和体会等。
编制部门:国土资源学院 编制人: 审核人: 编制日期:2017年5月3日
项目编号 No. C001
项目名称 数据结构
训练对象 GIS 2015级7、8
学时 4
课程名称 数据结构实验
教 材 数据结构(C语言版)
目的
Objective 1.学会用算法来进行编程。
第一题
请用两次课的时间完善下列程序的功能函数:
void CreateBiTree(BiTree &T); //生成一个二叉树
void PreOrder(BiTree); //递归先序遍历二叉树
void InOrder(BiTree); //递归中序遍历二叉树
void PostOrder(BiTree); //递归后序遍历二叉树
void InOrderTraverse(BiTree T); //非递归中序遍历二叉树
void PreOrder_Nonrecursive(BiTree T);//非递归先序遍历二叉树
void LeverTraverse(BiTree T);//非递归层序遍历二叉树
第二题
请理解中序遍历线索二叉树的线索化原理,对一颗二叉树进行中序线索化,并用中序遍历的方式输出来。
该二叉树:ABC DE G F .(点号不算)
第一题:
程序代码如下:
#include
#include
#include
using namespace std;
//二叉树结点
typedef struct BiTNode{
//数据
char data;
//左右孩子指针
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
//按先序序列创建二叉树
int CreateBiTree(BiTree &T); //生成一个二叉树
void PreOrder(BiTree); //递归先序遍历二叉树
void InOrder(BiTree); //递归中序遍历二叉树
void PostOrder(BiTree); //递归后序遍历二叉树
void InOrderTraverse(BiTree T); //非递归中序遍历二叉树
void PreOrder_Nonrecursive(BiTree T);//非递归先序遍历二叉树
void LeverTraverse(BiTree T);//非递归层序遍历二叉树
int CreateBiTree(BiTree &T){
char data;
//按先序次序输入二叉树中结点的值(一个字符),‘#’表示空树
scanf("%c",&data);
if(data == '#'){
T = NULL;
}
else{
T = (BiTree)malloc(sizeof(BiTNode));
//生成根结点
T->data = data;
//构造左子树
CreateBiTree(T->lchild);
//构造右子树
CreateBiTree(T->rchild);
}
return 0;
}
//输出
void Visit(BiTree T){
if(T->data != '#'){
printf("%c ",T->data);
}
}
//先序遍历
void PreOrder(BiTree T){
if(T != NULL){
//访问根节点
Visit(T);
//访问左子结点
PreOrder(T->lchild);
//访问右子结点
PreOrder(T->rchild);
}
}
//中序遍历
void InOrder(BiTree T){
if(T != NULL){
//访问左子结点
InOrder(T->lchild);
//访问根节点
Visit(T);
//访问右子结点
InOrder(T->rchild);
}
}
//后序遍历
void PostOrder(BiTree T){
if(T != NULL){
//访问左子结点
PostOrder(T->lchild);
//访问右子结点
PostOrder(T->rchild);
//访问根节点
Visit(T);
}
}
/* 先序遍历(非递归)
思路:访问T->data后,将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,再先序遍历T的右子树。
*/
void PreOrder2(BiTree T){
stack stack;
//p是遍历指针
BiTree p = T;
//栈不空或者p不空时循环
while(p || !stack.empty()){
if(p != NULL){
//存入栈中
stack.push(p);
//访问根节点
printf("%c ",p->data);
//遍历左子树
p = p->lchild;
}
else{
//退栈
p = stack.top();
stack.pop();
//访问右子树
p = p->rchild;
}
}//while
}
/* 中序遍历(非递归)
思路:T是要遍历树的根指针,中序遍历要求在遍历完左子树后,访问根,再遍历右子树。
先将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,访问T->data,再中序遍历T的右子树。
*/
void InOrder2(BiTree T){
stack stack;
//p是遍历指针
BiTree p = T;
//栈不空或者p不空时循环
while(p || !stack.empty()){
if(p != NULL){
//存入栈中
stack.push(p);
//遍历左子树
p = p->lchild;
}
else{
//退栈,访问根节点
p = stack.top();
printf("%c ",p->data);
stack.pop();
//访问右子树
p = p->rchild;
}
}//while
}
//后序遍历(非递归)
typedef struct BiTNodePost{
BiTree biTree;
char tag;
}BiTNodePost,*BiTreePost;
void PostOrder2(BiTree T){
stack stack;
//p是遍历指针
BiTree p = T;
BiTreePost BT;
//栈不空或者p不空时循环
while(p != NULL || !stack.empty()){
//遍历左子树
while(p != NULL){
BT = (BiTreePost)malloc(sizeof(BiTNodePost));
BT->biTree = p;
//访问过左子树
BT->tag = 'L';
stack.push(BT);
p = p->lchild;
}
//左右子树访问完毕访问根节点
while(!stack.empty() && (stack.top())->tag == 'R'){
BT = stack.top();
//退栈
stack.pop();
printf("%c ",BT->biTree->data);
}
//遍历右子树
if(!stack.empty()){
BT = stack.top();
//访问过右子树
BT->tag = 'R';
p = BT->biTree;
p = p->rchild;
}
}//while
}
//层次遍历
void LevelOrder(BiTree T){
BiTree p = T;
//队列
queue queue;
//根节点入队
queue.push(p);
//队列不空循环
while(!queue.empty()){
//对头元素出队
p = queue.front();
//访问p指向的结点
printf("%c ",p->data);
//退出队列
queue.pop();
//左子树不空,将左子树入队
if(p->lchild != NULL){
queue.push(p->lchild);
}
//右子树不空,将右子树入队
if(p->rchild != NULL){
queue.push(p->rchild);
}
}
}
int main()
{
BiTree T;
CreateBiTree(T);
printf("先序遍历:\n");
PreOrder(T);
printf("\n");
printf("先序遍历(非递归):\n");
PreOrder2(T);
printf("\n");
printf("中序遍历:\n");
InOrder(T);
printf("\n");
printf("中序遍历(非递归):\n");
InOrder2(T);
printf("\n");
printf("后序遍历:\n");
PostOrder(T);
printf("\n");
printf("后序遍历(非递归):\n");
PostOrder2(T);
printf("\n");
printf("层次遍历:\n");
LevelOrder(T);
printf("\n");
return 0;
}
实验二
请理解中序遍历线索二叉树的线索化原理,对一颗二叉树进行中序线索化,并用中序遍历的方式输出来。
该二叉树:ABC DE G F .(点号不算)
程序代码如下:
//算法5.9 遍历中序线索二叉树
#include
//二叉树的二叉线索类型存储表示
typedef struct BiThrNode
{
char data; //结点数据域
struct BiThrNode *lchild,*rchild; //左右孩子指针
int LTag,RTag;
}BiThrNode,*BiThrTree;
//全局变量pre
BiThrNode *pre=new BiThrNode;
//用算法5.3建立二叉链表
void CreateBiTree(BiThrTree &T)
{
//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
char ch;
scanf("%c",&ch);
if(ch=='#') T=NULL; //递归结束,建空树
else
{
T=new BiThrNode;
T->data=ch; //生成根结点
CreateBiTree(T->lchild); //递归创建左子树
CreateBiTree(T->rchild); //递归创建右子树
} //else
} //CreateBiTree
//用算法5.7以结点P为根的子树中序线索化
void InThreading(BiThrTree p)
{
//pre是全局变量,初始化时其右孩子指针为空,便于在树的最左点开始建线索
if(p)
{
InThreading(p->lchild); //左子树递归线索化
if(!p->lchild)
{ //p的左孩子为空
p->LTag=1; //给p加上左线索
p->lchild=pre; //p的左孩子指针指向pre(前驱)
}
else
p->LTag=0;
if(!pre->rchild)
{ //pre的右孩子为空
pre->RTag=1; //给pre加上右线索
pre->rchild=p; //pre的右孩子指针指向p(后继)
}
else
pre->RTag=0;
pre=p; //保持pre指向p的前驱
InThreading(p->rchild); //右子树递归线索化
}
}//InThreading
//用算法5.8带头结点的中序线索化
void InOrderThreading (BiThrTree &Thrt,BiThrTree T)
{
//中序遍历二叉树T,并将其中序线索化,Thrt指向头结点
Thrt=new BiThrNode; //建头结点
Thrt->LTag=0; //头结点有左孩子,若树非空,则其左孩子为树根
Thrt->RTag=1; //头结点的右孩子指针为右线索
Thrt->rchild=Thrt; //初始化时右指针指向自己
if(!T) Thrt->lchild=Thrt; //若树为空,则左指针也指向自己
else
{
Thrt->lchild=T; pre=Thrt; //头结点的左孩子指向根,pre初值指向头结点
InThreading(T); //调用算法5.7,对以T为根的二叉树进行中序线索化
pre->rchild=Thrt; //算法5.7结束后,pre为最右结点,pre的右线索指向头结点
pre->RTag=1;
Thrt->rchild=pre; //头结点的右线索指向pre
}
}
void InOrderTraverse_Thr(BiThrTree T)
{ BiThrNode *p=new BiThrNode;
p=T->lchild;
while(p!=T)
{
while(p->LTag==0)
p=p->lchild;
printf("%c",p->data);
while(p->RTag==1&&p->rchild!=T){
p=p->rchild;
printf("%c",p->data);
}
p=p->rchild;
}
}
int main()
{
pre->RTag=1;
pre->rchild=NULL;
BiThrTree tree,Thrt;
printf("请输入建立二叉链表的序列:\n");
CreateBiTree(tree);
InOrderThreading(Thrt,tree);
printf("中序遍历线索二叉树的结果为:\n");
InOrderTraverse_Thr(Thrt);
printf("\n");
return 0;
}
心得体会: