二叉树的非递归遍历

树的非递归遍历比递归遍历要复杂,用栈来保存节点。

typedef struct node{

Elemtype data;

struct node* lChild;

struct node* rChild;

}BTNode;

1.先序遍历非递归算法

思路:由先序遍历过程可知,先访问根节点,再访问左子树,最后访问右子树,因此,先将根节点进栈,在栈不空时循环:出栈p,访问*p节点,若右孩子不为空将该右孩子节点进栈,若左孩子不空,再将左孩子节点 进栈。

void PreOrder(BTNode* b){

BTNode* St[MaxSize],*p;

int top=-1;

if(b!=NULL){

top++;   //根节点进栈

St[top]=b;

while(top>-1){      //栈不为空时循环

p=St[top];             //退栈并访问该节点

top--;

printf("%c",p->data);

if(p->rChild!=NULL){ //右孩子节点进栈

top++;

St[top]=p->rChild;

}

if(p->lChild){  //左孩子结点进栈

top++;

St[top]=p->lChild;
}

}

printf("\n");

}

}

2.中序遍历非递归算法

思路:用指针指向当前要处理的结点。先扫描(并非访问)根结点的所有左结点并将它们一一进栈,当无左结点时表示栈顶节点无左子树,然后出栈这个结点,并访问它,将p指向刚出栈结点的右孩子,对右孩子做同样的处理。需要注意的是,当结点*p的所有左下结点进栈后,这时的栈顶结点要么没有左子树,要么其左子树已经访问过,就可以访问这个栈顶结点。如此这样,直到栈空。

void InOrder(BTNode* b){

BTNode*  St[MaxSize],*p;

int top=-1;

if(b!=NULL){

p=b;

while(top>-1||p!=NULL){ //处理*p结点的左子树

while(p!=NULL){  //扫描*p的所有左结点并进栈

top++;

St[top]=p;

p=p->lChild;

}

//执行到此处时,栈顶元素没有左孩子或者左子树均以被访问过

if(top>-1){

p=St[top];    //出栈*p结点

top--;

printf("%c",p->data);   //访问之

p=p->rChild;     //转向处理*p的右孩子结点

}

}

printf("\n")

}

}

3.后序遍历非递归算法

思路:采用一个栈保存需要返回的结点指针,先扫描根节点的所有左结点并一一进栈,出栈一个结点*b作为当前结点,然后扫描该结点的右子树。当一个结点的左右孩子均被访问后再访问该结点,直到栈空为止。难点是如何判断一个结点*b的右子树已经被访问过(实际上当*b结点的右孩子被访问过,那么其油子树就已经被访问过),为此用p保存刚刚访问过的结点,初值设为NULL,若b-rChild==p成立(在后序遍历中,*b的右孩子结点一定刚好在*b访问之前被访问),说明*b的左右孩子均已被访问,可以访问*b;

void PostOrder(BTNode* b){

BTNode* St[MaxSize];

BTNode* p;

int flag,top=-1;

if(b!=NULL)

do{

while{(b!=NULL) //将b的所有左结点入栈

{

top++;

St[top]=b;

b=b->lChild;

}

//执行到此处说明栈顶元素没有左孩子或者左子树已经被访问过

p=NULL;  //p指向栈顶结点的前一个已访问的结点

flag=1;      //表示*b的左孩子已经被访问过或者是空

while(top!=-1&&flag){

b=St[top];       //取出当前栈顶元素

if(b->rChild==p){

/*  若p=NULL表示b的右孩子不存在,而其左子树不在或已经被 访问,所以可以访问*b;若p不等于NULL,表示b的右子树已访问(原因是p指向b的右子树中刚访问过的结点,而*p是b的右子树中后序序列的最后一个结点),所以可以访问*b */

printf("%c",p->data);   //访问*b结点

top--;

p=b;         //p指向刚刚访问过的结点

}else{

b=b->rChild;     //b指向右孩子结点

flag=0;       //表示*b的左孩子尚未访问过

}

}

}while(top!=-1)

}

printf("\n");

}

}

标题基于Python的自主学习系统后端设计与实现AI更换标题第1章引言介绍自主学习系统的研究背景、意义、现状以及本文的研究方法和创新点。1.1研究背景与意义阐述自主学习系统在教育技术领域的重要性和应用价值。1.2国内外研究现状分析国内外在自主学习系统后端技术方面的研究进展。1.3研究方法与创新点概述本文采用Python技术栈的设计方法和系统创新点。第2章相关理论与技术总结自主学习系统后端开发的相关理论和技术基础。2.1自主学习系统理论阐述自主学习系统的定义、特征和理论基础。2.2Python后端技术栈介绍DjangoFlask等Python后端框架及其适用场景。2.3数据库技术讨论关系型和非关系型数据库在系统中的应用方案。第3章系统设计与实现详细介绍自主学习系统后端的设计方案和实现过程。3.1系统架构设计提出基于微服务的系统架构设计方案。3.2核心模块设计详细说明用户管理、学习资源管理、进度跟踪等核心模块设计。3.3关键技术实现阐述个性化推荐算法、学习行为分析等关键技术的实现。第4章系统测试与评估对系统进行功能测试和性能评估。4.1测试环境与方法介绍测试环境配置和采用的测试方法。4.2功能测试结果展示各功能模块的测试结果和问题修复情况。4.3性能评估分析分析系统在高并发等场景下的性能表现。第5章结论与展望总结研究成果并提出未来改进方向。5.1研究结论概括系统设计的主要成果和技术创新。5.2未来展望指出系统局限性并提出后续优化方向。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值