二叉树中结点左右子树的交换Word文档下载推荐.docx
- 文档编号:22578067
- 上传时间:2023-02-04
- 格式:DOCX
- 页数:38
- 大小:268.53KB
二叉树中结点左右子树的交换Word文档下载推荐.docx
《二叉树中结点左右子树的交换Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《二叉树中结点左右子树的交换Word文档下载推荐.docx(38页珍藏版)》请在冰豆网上搜索。
按照中序遍历方法遍历二叉树。
voidPostOrderTraverse(BiTreeT)
按照后序遍历方法遍历二叉树。
voidLevelOrderTraverse(BiTreeT)
按照层序遍历方法遍历二叉树。
voidSwapChild(BiTNode**p)
二叉树存在且交换的结点有子树;
将二叉树左右结点交换。
voidPaint(BiTreeT)
将二叉树的结点打印出来。
四、软件模块结构图
构造二叉树
五、程序设计思想
1、程序设计基本思想
(1)本实验要求编写一个程序实现对二叉树的各种基本操作,并以此为目的设计一个程序,完成如下功能:
1、输入二叉树的先序序列字符,建立二叉链表。
注意:
输入时,必须加入虚结点以示空指针的位置;
假设虚结点输入时用空格字符表示。
2、打印二叉树。
3、按先序、中序、后序和层序三种不同方法遍历二叉树。
4、交换二叉树的所有左右子树。
5、打印二叉树,并且分别按照先序、中序、后序和层序三种不同方法遍历二叉树。
6、在设计一个简单的菜单,分别调试上述算法。
7、编写主程序完成各功能的调用和实现。
(2)测试数据:
1、按照先序序列依次输入字符。
2、打印二叉树并且按先序、中序和后序遍历二叉树并输出遍历结果。
3、输出交换二叉树的左右子树并且打印二叉树并且按先序、中序和后
序遍历二叉树并输出遍历结果。
2、程序设计基本思想
本程序含有7个函数;
主函数main()
前序遍历二叉树PreOrderTraverse(T,PrintChar)
中序遍历二叉树Inorder(T)
后续遍历二叉树Postorder(T)
层序遍历二叉树LevelOrderTraverse(T)
打印二叉树Paint(T)
交换二叉树所有左右子树SwapChild(T)
六、程序流程图
1、创建函数
YN
chare;
e=getchar();
if(e=='
*'
)
(*p)=NULL;
else
{
if(!
((*p)=(BiTree)malloc(sizeof(BiTNode))))
{
printf("
分配失败\n"
);
exit(0);
}
(*p)->
data=e;
Create(&
((*p)->
lchild));
rchild));
}
2、前序遍历函数
Y
N
if(T)
%c"
T->
data);
PreOrderTraverse(T->
lchild);
rchild);
3、中序遍历函数
InOrderTraverse(T->
4、后序遍历函数
PostOrderTraverse(T->
5、层序遍历函数
BiTreeQ[MaxLength];
intfront=0,rear=0;
BiTreep;
//根结点入队
Q[rear]=T;
rear=(rear+1)%MaxLength;
//插入结点为新的队尾元素
while(front!
=rear)
//队头元素出队
p=Q[front];
front=(front+1)%MaxLength;
//删除头结点
p->
//左孩子不为空,入队
if(p->
lchild)
Q[rear]=p->
lchild;
//插入左孩子结点为新的队尾元素
//右孩子不为空,入队
rchild)
rchild;
//插入右孩子结点为新的队尾元素
6、左右子树交换函数
N
Y
//交换左右子树(递归算法)
BiTNode*temp;
if((*p))
//交换左右子树指针
temp=(*p)->
lchild=(*p)->
rchild=temp;
SwapChild(&
7、二叉树打印函数
//打印二叉树(采用凹入表横向打印)
voidPaint(BiTreeT,intn)
charc;
Paint(T->
rchild,n+1);
%*c"
4*n,T->
if(T->
lchild&
&
T->
c='
<
'
;
else
if(T->
c='
/'
else
if(T->
\\'
'
%c\n"
c);
lchild,n+1);
8、遍历调用函数
//遍历函数(调用层序,前序,中序,后序遍历函数)
voidOrderTraverse(BiTreeT)
printf("
层序遍历:
"
LevelOrderTraverse(T);
printf("
\n"
前序遍历:
PreOrderTraverse(T);
中序遍历:
InOrderTraverse(T);
后序遍历:
PostOrderTraverse(T);
9、菜单函数
//主菜单函数(显示系统功能,获取用户输入)
voidmenu(int*choice)
-------------欢迎使用-------------\n"
1.建立二叉树(前序)\n"
2.打印二叉树\n"
3.遍历二叉树(层序,前序,中序,后序)\n"
4.交换左右子树\n"
0.退出\n"
----------------------------------\n"
你的选择:
scanf("
%d"
choice);
getchar();
//很重要,存储回车,避免对后面函数的影响
/**************************************************************/
10、主函数
/***************************主函数****************************/
//根据用户的输入,调用相应的子函数
main()
BiTreeT=NULL;
//定义二叉树并默认为空
intchoice;
while
(1)
menu(&
choice);
//显示主菜单
switch(choice)//根据不同选择,实现相应操作
case1:
//创建二叉树
{
printf("
输入各元素,空子树用'
表示\n"
Create(&
T);
创建成功!
\n\n"
}break;
case2:
//打印二叉树
if(T)
{
printf("
打印结果:
Paint(T,1);
}
else
二叉树为空!
case3:
//遍历二叉树
OrderTraverse(T);
case4:
//交换左右子树
SwapChild(&
交换成功!
case0:
exit(0);
//退出
default:
无效输入!
/****************************************************************/
七、源程序代码
/********************头文件、宏定义和存储结构********************/
//用到的头文件
#include<
stdio.h>
stdlib.h>
//队列最大结点数目
#defineMaxLength100
//定义二叉树的存储结构(二叉链表)
typedefstructnode
chardata;
structnode*lchild,*rchild;
}BiTNode,*BiTree;
/*************************各功能函数的定义***********************/
/**************创建、遍历、交换、打印、主菜单函数****************/
//创建二叉树(前序)
chare;
e=getchar();
if(e=='
(*p)=NULL;
else
{
if(!
exit(0);
(*p)->
Create(&
}
//递归前序遍历
if(T)
PreOrderTraverse(T->
//递归中序遍历
InOrderTraverse(T->
//递归后序遍历
PostOrderTraverse(T->
//层序遍历(利用循环队列)
BiTreeQ[MaxLength];
intfront=0,rear=0;
BiTreep;
Q[rear]=T;
rear=(rear+1)%MaxLength;
while(front!
p=Q[front];
front=(front+1)%MaxLength;
if(p->
//交换左右子树(递归,类似于先序遍历)
BiTNode*temp;
if((*p))
temp=(*p)->
SwapChild(&
charc;
Paint(T->
if(T->
c='
Paint(T->
LevelOrderTraverse(T);
PreOrderTraverse(T);
InOrderTraverse(T);
PostOrderTraverse(T);
//主菜单(显示系统功能,获取用户输入)
scanf("
/***************************主函数*******************************/
intchoice;
while
(1)
Create(&
}break;
if(T)
Paint(T,1);
}
OrderTraverse(T);
SwapChild(&
八、调试分析
运行程序,例如:
输入如下图所示的有20个结点的完全二叉树。
时间复杂度分析:
很显然,先序.中序.后序递归算法的复杂度是相同的,递归算法非常的简单。
例如先序先访问跟节点,然后访问左节点,再访问右节点。
仔细看一下递归程序,就会发现,其实每次都是子树的左子树(lchild),直到左子树为空,然后开始从递归的最深处返回,然后开始恢复递归现场,访问右子树。
其实过程很简单:
一直往左走root->
lchild->
lchild...->
null,由于是先序遍历,因此一遇到节点,便需要立即访问;
由于一直走到最左边后,需要逐步返回到父节点访问右节点,时间方面每个节点调用一次函数,访问一次,是O(n).没有空间开销,所以是0.中序.后序递归算法同先序一样。
时间复杂度是O(n),空间复杂度是0.同理可知中序与后序也是一样的。
非递归层序遍历有不一样。
层序遍历中每次将节点压入队,然后弹出,再让左子树入队,再让右子树入队,在遍历过程中,左右子树依次入队出队。
时间复杂度O(n),空间复杂度为0。
问题一:
前序遍历、中序遍历以及后序遍历为递归算法很简单就没什么可说的了,而层次遍历就需要用到队列处理稍微复杂一点。
创建二叉树时,要求二叉树内容可以是各种形式,刚开始编创建算法的时候调试总是出错,后来经过参考数据结构相关资料才发现有一个地方少写一行申请空间的代码。
问题二:
非递归算法在编程时都是不很顺利,其中层序遍历有点难,需要掌握队列的
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 二叉 结点 左右 子树 交换