二叉树的遍历及相关题目
二叉树的遍历及相关题目
1.1二叉树遍历的概念
二叉树结构体的定义:
typedef struct node
{
ElemType data;
struct node * lchild;
struct node * rchild;
}
二叉树的遍历是指按照一定的次序访问二叉树中的所有的节点,并且每个节点仅访问一次的过程。
若规定先遍历左子树,后遍历右子树,则对于非空二叉树,可得到如下3种递归的遍历方法:
(1)先序遍历
访问根节点,先序遍历左子树,先序遍历右子树。(根,左,右)
(2)中序遍历
中序遍历左子树,访问根节点,中序遍历右子树。(左,根,右)
(3)后序遍历
后序遍历左子树,后序遍历右子树,访问根节点。(左,右,根)
除此之外也有层次遍历。先访问根节点,在从左到右访问第二层的所有节点,从左到右访问第三层的所有节点......
1.2二叉树遍历递归算法
先序遍历递归算法:
void PreOrder(BTNode * b)
{
if(n != NULL)
{
cout<<b->data;
PreOrder(b->lchild);
PreOrder(b->rchild);
}
}
中序遍历递归算法
void InOrder(BTNode * b)
{
if(n != NULL)
{
InOrder(b->lchild);
cout<<b->data;
InOrder(b->rchild);
}
}
后序遍历递归算法:
void PostOrder(BTNode * b)
{
if(b != NULL)
{
PostOrder(b->lchild);
PostOrder(b->rchild);
cout<<b->data;
}
}
题目1:输出一个给定二叉树的所有的叶子节点:
void DispLeaf(BTNode * b)
{
if(b != NULL)
{
if(b->lchild == NULL && b->rchild == NULL)
cout<<b->data;
DispLeaf(b->lchild);
DispLeaf(b->rchild);
}
}
以上算法采用先序遍历输出了所有的叶子节点,所以叶子节点是从左到右输出的。从右到左输出所有的叶子节点就需要才用后序遍历的思想。
void DispLeaf1(BTNode * b)
{
if(b != NULL)
{
if(b->lchild == NULL && b->rchild == NULL)
cout<<b->data;
DispLeaf1(b->rchild);
DispLeaf1(b->lchild);
}
}
题目2:求二叉树中节点值为x的节点的层数(假设二叉树中的节点的值都不同)。
题解:采用递归算法,设计函数Level(b,x,h),其返回值为在二叉树b中节点值x的节点所在的层次,返回0时表示未找到。h表示b所指节点的层次,从根节点开始查找,根节点的层次为1,所以h的初值为1。
int Level(BTNode * b, ElemType x, int h) //h的初始值为1
{
if(b == NULL)
{
return 0;
}
else if(b->data == x)
{
return h;
}else
{
int level = Level(b->lchild, x, h+1);
if(level != 0)
return level;
else
return Level(b->rchild, x, h+1);
}
}
题目3:判断两颗二叉树是否相似。所谓二叉树b1和b2相似是指b1和b2都是空的二叉树;或者b1和b2的根节点相似,且左子树和右子树分别相似。不必比较数值,结构一样就是相似。
//相似返回true,不相似返回false
bool Like(BTNode * b1, BTNode * b2)
{
if(b1 == NULL && b2 == NULL)
{
return true;
}
else if(b1 == NULL || b2 == NULL)
{
return false;
}
else
{
bool like1 = Like(b1->lchild, b2->lchild);
bool like2 = Like(b1->rchild, b2->rchild);
return (like1 && like2);
}
}
题目四:输出值为x的节点的所有的祖先。
//判断b是否时值为x的节点的祖先,如果是,返回true,如果不是,返回false
bool ancestor(BTNode* b, ElemType x)
{
if(b == NULL)
{
return false;
}
else if((b->lchild != NULL && b->lchild->data == x) || (b->rchild != NULL && b->rchild->data == x))
{
cout<<b->data;
return true;
}
else if(ancestor(b->lchild, x) || ancestor(b->rchild, x))
{
cout<<b->data;
return true;
}else
{
return false;
}
}
1.3二叉树遍历非递归算法
先序遍历非递归算法
void PreOrder(BTNode *b)
{
stack<BTNode*> BTStack;
if(b != NULL)
{
BTStack.push(b);
}
while(!BTStack.empty())
{
BTNode* node = BTStack.top();
BTStack.pop();
cout<<node->data;
if(node->rchild != NULL)
{
BTStack.push(node->rchild);
}
if(node->lchild != NULL)
{
BTStack.push(node->lchild);
}
}
cout<<endl;
}
中序遍历非递归算法
void PreOrder(BTNode *b)
{
stack<BTNode*> BTStack;
BTNode *node = b;
while(!BTStack.empty() || node != NULL)
{
while(node != NULL)
{
BTStack.push(node);
node = node->lchild;
}
node = BTStack.top();
BTStack.pop();
cout<<node->data;
node = node->rchild;
}
cout<<endl;
}
后序遍历非递归算法
void PostOrder(BTNode *b)
{
stack<BTNode *> BTNStack;
BTNode* p;
int flag; //表示是否遍历完成左子树
if(b != NULL)
{
do
{
while(b!= NULL)
{
BTNStack.push(b);
b = b->lchild;
}
p = NULL;
flag = 1; //表示*b左孩子已访问过或者为空
while(!BTNStack.empty() && flag)
{
b = BTNStack.top();
if(b->rchild == p) //查看刚刚遍历过的节点是不是右子树的根节点
{
cout<<b->data;
BTNStack.pop();
p = b;
}
else
{
b = b->rchild;
flag = 0;
}
}
}while(!BTNStack.empty());
cout<<endl;
}
}
posted on 2022-03-01 08:27 xcxfury001 阅读(217) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!