#include“initList/initTree.h“

本文深入探讨了二叉树的构建与遍历方法,包括递归与非递归的先序、中序、后序遍历,以及层次遍历。通过代码实现,详细解析了每种遍历方式的原理与步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<iostream>
#include<stack>
#include<queue>
using namespace std;
typedef char ElementTYPE;

//结构体定义
typedef struct Node{
    ElementTYPE data;
    struct Node *lchild;
    struct Node *rchild;

}BinaryTree,*BiTree;

class initTree{
public:
//先序建立
int k=0;
BinaryTree* createBinaryTree(BinaryTree* &T,char ch[],int l){ //需要注意的地方,&T使用二重指针,而单链表使用的是一重指针

    ElementTYPE data = ch[k];
    T = new BinaryTree();
    if(data=='#'){
        T = NULL;
    }
    else{
        T->data = data;
        createBinaryTree(T->lchild,ch,k++);
        createBinaryTree(T->rchild,ch,k++);
    }
    return T;
} 
}init;

//二叉树递归遍历三种方法
class recursion{
public:


void visit(BinaryTree* T){
        cout<<T->data<<" ";
}

//先序遍历
void preOrder(BinaryTree* T){


    if(T!=NULL)
        { 
            visit(T);
            preOrder(T->lchild);
            preOrder(T->rchild);
        }
}

//中序遍历
void inOrder(BinaryTree* T){
    
    if(T!=NULL)
        { 
            inOrder(T->lchild);
            visit(T);
            inOrder(T->rchild);
        }
}

//后序遍历
void postOrder(BinaryTree* T){
    if(T!=NULL)
        { 
            postOrder(T->lchild);
            postOrder(T->rchild);
            visit(T);
        }
}
}recur;

//二叉树非递归遍历四种方法
class non_recursion{
public:

void visit(ElementTYPE data){
    cout<<data<<" ";
}
//先序遍历
/* 思路:将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,再先序遍历T的右子树。*/
void preOrder(BinaryTree* T){
    BinaryTree* p = T;
    stack<BinaryTree*> stack;
    while(p || !stack.empty())
    if(p){
        stack.push(p);//给的是树的地址,而不是值
        visit(p->data);
        p = p->lchild;
    }else{
        p = stack.top();//p返回到当前树的父节点地址
        stack.pop();//删除节点
        p = p->rchild;//访问右子树
    }

}

//中序遍历 指针p从根节点开始,首先沿着左子树向下移动,同时入栈保存,当到达空子树后需要退栈访问,然后移动到右子树上去
void inOrder(BinaryTree* T){
    BinaryTree* p = T;
    stack<BinaryTree*> stack;
    while(p || !stack.empty())
    if(p){
        stack.push(p);
        p = p->lchild;
    }else{
        p = stack.top();//退栈
        stack.pop();
        visit(p->data);//退栈时输出节点
        p = p->rchild;
    }

}

//非递归后序遍历 后序遍历时,分别从左子树和右子树共两次返回根节点,只有从右子树返是才访问根节点,所以增加一个栈标记到达节点的次序
typedef struct BiTNodePost{
    BiTree biTree;
    char tag;
}BiTNodePost, *BiTreePost;

void postOrder(BiTree T)
{
    stack<BiTreePost> stack;
    //p是遍历指针  
    BiTree p = T;
    BiTreePost BT;
    //栈不空或者p不空时循环  
    while (p != NULL || !stack.empty())
        {
        //遍历左子树  
        while (p != NULL)
               {
            BT = new 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();
            cout<<BT->biTree->data<<" ";
        }
        //遍历右子树  
        if (!stack.empty())
                {
            BT = stack.top();
            //访问过右子树  
            BT->tag = 'R';
            p = BT->biTree;
            p = p->rchild;
        }
    }
}

//层次遍历  
void LevelOrder(BiTree T)
{
    BiTree p = T; 
    queue<BiTree> queue;
    //根节点入队  
    queue.push(p);
    //队列不空循环  
    while (!queue.empty())
       {
        //对头元素出队  
        p = queue.front();
        //访问p指向的结点
        visit(p->data);
        //退出队列  
        queue.pop();
        //左孩子不为空,将左孩子入队  
        if (p->lchild != NULL)
                {
            queue.push(p->lchild);
        }
        //右孩子不空,将右孩子入队  
        if (p->rchild != NULL)
                {
            queue.push(p->rchild);
        }
    }
}

}non_recur;

// int main(){
//     char ch[] = {'1','2','4','8','#','#','9','#','#','5','#','#','3','6','#','#','7','#','#'};
//     int len = sizeof(ch)/sizeof(ch[0]);
//     BinaryTree* T;
//     T = init.createBinaryTree(T,ch,0);
//     //递归:
//     cout<<"递归先序:"; recur.preOrder(T);
//     cout<<"\n递归中序:"; recur.inOrder(T);
//     cout<<"\n递归后序:"; recur.postOrder(T);
//     //非递归:
//     cout<<"\n非递归先序:"; non_recur.preOrder(T);
//     cout<<"\n非递归中序:"; non_recur.inOrder(T);
//     cout<<"\n非递归后序:"; non_recur.postOrder(T);
//     cout<<"\n层次遍历:"; non_recur.LevelOrder(T);
// }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值