哈尔滨理工大学计算机学院 数据结构课程设计 建立二叉树层序先序.docx
《哈尔滨理工大学计算机学院 数据结构课程设计 建立二叉树层序先序.docx》由会员分享,可在线阅读,更多相关《哈尔滨理工大学计算机学院 数据结构课程设计 建立二叉树层序先序.docx(14页珍藏版)》请在冰豆网上搜索。
哈尔滨理工大学计算机学院数据结构课程设计建立二叉树层序先序
哈尔滨理工大学计算机学院
数据结构课程设计
建立二叉树
层序、先序遍历
班级:
计05-1班
姓名:
杨继伟
学号:
0504110122
1.1题目分析2
建立二叉树,层序、先序遍历
1需求分析:
1.1.题目:
建立二叉树,要求能够输入树的各个节点,并能够输出用不同方法遍历的遍历序列;分别建立二叉树存储的输入函数,输出层序遍历序列的函数,输出先序遍历序列的函数。
分析:
首先要输入元素建立二叉树,选择某一种存储结构存储二叉树,本程序采用二叉链表存储结构。
由于二叉树的定义是递归的,因而一棵非空二叉树可以看作是由根结点、左子树和右子树这三个基本部分组成的。
如果能依次遍历这三个部分的信息,也就遍历了整个二叉树。
由此得到的二叉树的遍历是按某种策略访问二叉树中的每一个结点且仅访问一次的过程。
程序一共分为如下3个模块:
二叉树的构造:
Insert_node(btree*root,intnode)
{……
}
create_btree(intdata[],intlen)
{……
}
层序遍历二叉树:
Voidlevelorder(bitree*root)
{……
}
先序遍历二叉树:
Voidpreorder(bitree*root)
{……
}
1.2.二叉树的构造
采用二叉链表存储结构建立二叉树,二叉树的结点由一个数据元素和分别指向其左右子树的两个分支构成,即数据域和左、右指针域
lchild
data
rchild
数据结构:
Typedefstrcutbnode
{
Telemtypedata;//结点数据类型
Structbnode*lchild,*rchild;//定义左右孩子为指针类型
}bnode,*btree;
其中Insert_node(btree*root,intnode)为插入二叉树结点函数,create_btree(intdata[],intlen)为建立二叉树函数
1.3.层序遍历二叉树
要采用一个队列。
先将二叉树的根节点入队,然后退队,输出该节点,若它有左子树,便将左子树的根节点入队,若它有左子树,便将有子树的根节点入队,直到队列空为止。
采用递归方法遍历。
1.4.先序遍历二叉树
若树不空,先访问根节点,其次访问左子树,最后访问右子树。
采用非递归方法遍历。
2.概要设计
1)二叉树的构造算法
先依序输入元素值,并存入数组nodelist中,再用函数一一插入二叉树的节点建立二叉树,节点的建立是将左子针指向左子树,右子针指向右子树
。
算法流程图如下:
Insert_node(btree*root,intnode):
create_btree(intdata[],intlen):
2)层序遍历二叉树:
算法流程图如下:
3)先序遍历二叉树:
算法流程图如下:
5)主函数
流程图:
3.详细设计
#include
#include
Typedefstructbtnode
{
Intdata;
Structbtnode*lchild,*rchild;
}bitree;
Bitree*insert_node(bitree*root,charnode)//插入二叉树的节点
{
bitree*newpointer;//根指针
bitree*currentpointer;//目前节点指针
bitree*parentpointer;//父节点指针
Newpointer=(bitree*)malloc(sizeof(bitree));
Newpointer->data=node;
Newpointer->lchild=null;
Newpoiter->rchild=null;
If(root==null)//当结点为空时
{
returnnewpointer;
}
Else
{
Currentpointer=root;//存储目前节点的指针
While(currentpointer!
=null)
{
parentpointer=currentpointer;//存储父节点的指针
If(currentpointer->data>node)//当目前结点大于插入结点时
{
currentpointer=currentpointer->lchild;//目前结点的左孩子赋为目前结点
}
Else
{
currentpointer=currentpointer->rchild;
}//右子树
}
If(parentpointer->data>node)//当父结点大于插入结点
{
parentpointer->lchild=newpointer;
}
Else
{
parentpointer->rchild=newpointer;
}
}
Returnroot;
}
Bitree*creatr_bittree(chardata[],intlen)//建立二叉树
{
IntI;
Bitree*root=null;
For(i=0;i{
Root=insert_node(root,data[i]);//调用insert_node()函数
}
Returnroot;
}
Voidpreorder(bitree*root)//前序非递归遍历二叉树
{
Bitree*p,*s[100];
Inttop=0;//top为栈顶指针
p=root;
While((p!
=null)||(top>0))
{
While(p!
=null)
{
printf(“%d”,p->data);
S[++top]=p;
P=p->lchild;
}
P=s[top--];
P=p->rchild;
}
}
Voidlevelorder(bitree*root)//层序递归遍历二叉树
{
Structnode
{
bitree*vec[100];
Intfront,rear;
}queue;//队列
Queue.front=0;
Queue.rear=0;//队列为空
If(root!
=null)
Printf(“%d”,root->data);
Queue.vec[queue.rear]=root;//根指针进队
Queue.rear++;
While(queue.front{
Root=queue.vec[queue.front];//队首元素出队
Queue.front++;
If(root->lchild!
=null)
{
printf(“%d”,root->lchild->data);
Queue.vec[queue.rear]=root->lchild;
Queue.rear++;
}
If(root->rchild!
=null)
{
printf(“%d”,root->rchild->dara);
Queue.vec[queue.rear]=root->rchild;
Queue.rear++;
}
}
}
Main()
{
bitree*root=null;//建立bitree型结点root
Intvalue,index,nodelist[20];//建立数组nodelist存放结点值
Printf(“pleaseinputdata:
\n”);
Index=0;
Scanf(“%d”,&value);//输入结点值
While(value!
=0)
{
Nodelist[index]=value;
Index++;
Scanf(“%d”,&value);
}
Root=create_bitree(nodelist,index);//创建二叉树
Printf(“thetreeisalreadycreated\n”);
Printf(“\n”);
Printf(“theresultafterlevelorderprocessing”);
Levelorder(root)//层序遍历二叉树
Printf(“\n”);
Printf(“theresultafterPreorderprocessing”);
Preorder(root);//先序遍历二叉树
}
4.调试分析
编译后,有多处错误,都是一些输入性错误,经改正后,编译成功,运行正确。
测试数据如下:
以0为结束符
原数据为:
75389420
建立的二叉树为:
7
58
39
24
层序遍历为:
7583924
先序遍历为:
7532489
时间复杂度分析:
层序遍历采用递归算法,时间复杂度为O(n);先序采用非递归算法,时间复杂度为O(n)
5.课设总结
二叉树是一种非常重要的数据结构,几乎任何数据结构都可以用二叉树来表示,二叉树的衍生结构可以应用于很多结构描述上,因此熟练的掌握二叉树的操作方法,对实际程序编写有很大促进,对锻炼自己的算法意识也有好处。
我总结了以下几点:
1)二叉树的定义是递归的,所以二叉树或为空,或是由一个根结点加上两棵分别称为左子树和右子树的互不相交的二叉树组成。
2)采用二叉链表存储,链表的头指针指向二叉树的根结点,在含有n个节点的二叉链表中有n+1个空链域
3)二叉树的遍历有先序,中序后序层序等从递归执行的角度来看,先序,中序后序是完全相同的,对含n个结点的二叉树,其时间算法复杂度为O(n),所需辅助空间为遍历过程中占的最大容量,即树的深度,,则空间复杂度也为O(n)
4)递归算法与非递归算法的差异:
从递归角度来看,递归操作隐式地调用系统栈,使时间和空间性能有比较大的损耗。
5)二叉树遍历的概念是很重要的,常用于解决实际问题。
一个最简单的例子就是可以将表达式(a-b)/(c+d)表示成一棵二叉树,遍历二叉树可计算出表达式的值。
感想:
经过一个星期的课程设计,使我意识到了自己多方面的不足,但同时也激发了我学习的积极性。
同样我也意识到了学好数据结构的重要性。
编程,调试过程真的需要很大的耐性,编好程序绝对不是一朝一夕就能学会的,这需要长时间的经验积累,磨炼,反复编程。
在调试过程中不断发现新问题不断改正。
当运行正确时,那份自豪与兴奋是无可替代的,让我我记住这份心情,把编程之路继续下去。