C++ 数据结构: 二叉树的前序, 中序, 后续遍历,层次遍历, 模板函数, 模板类写法

二叉树的前序, 中序, 后续遍历,层次遍历

//
// Created by 31618 on 2021/5/21.
//
#include<iostream>
#include<string>
#include<queue>

using namespace std;

//链表二叉树的节点结构
template<class T>
struct binaryTreeNode
{
public:
    //构造函数
    binaryTreeNode()
    {
        this->leftChild = nullptr ;
        this->rightChild = nullptr ;
    }
    //explicit关键字的作用就是防止类构造函数的隐式自动转换.
    explicit binaryTreeNode(const T& elem)
    {
        this->element = elem ;
    }
    
    [[maybe_unused]] binaryTreeNode(const T& elem , const binaryTreeNode* left , const binaryTreeNode* right)
    {
        this->element = elem ;
        this->leftChild = left ;
        this->rightChild = right ;
    }
    
public:
    T element ;
    //左子树
    binaryTreeNode<T>* leftChild ;
    //右子树
    binaryTreeNode<T>* rightChild ;
    
};

//访问
template<class T>
void visit(binaryTreeNode<T>* node)
{
    cout<< node->element << endl;
}

//前序遍历
template<class T>
void preOrder(binaryTreeNode<T>* tree)
{
    //当前节点不为空
    if(tree != NULL)
    {
        //先访问根节点
        visit(tree) ;
        //再访问左孩子
        preOrder(tree->leftChild) ;
        //最后访问右孩子
        preOrder(tree->rightChild) ;
    }
    
}

//中序遍历: 先左孩子, 再根, 最后右孩子
template<class T>
void inOrder(binaryTreeNode<T>* treeNode)
{
    //递归返回条件: 当前节点不为空
    if(treeNode != NULL)
    {
        //先左孩子
        inOrder(treeNode->leftChild);
        //再根节点
        visit(treeNode) ;
        //最后右孩子
        inOrder(treeNode->rightChild) ;
    
    }
 
}

//后序遍历: 先访问左孩子, 再访问有孩子, 最后访问根节点
template<class T>
void postOrder(binaryTreeNode<T>* treeNode)
{
    //递归返回条件: 当前节点不为空
    if(treeNode !=NULL)
    {
        postOrder(treeNode->leftChild) ;
        postOrder(treeNode->rightChild) ;
        //最后访问根节点
        visit(treeNode) ;
    }
    
}


//构造中缀表达式
template<class T>
void infix(binaryTreeNode<T>* treeNode)
{
    //中缀表达式通过中序遍历得到
    cout << "(" ;
    //先左
    infix(treeNode->leftChild);
    //再根: 访问根节点, 这里可以替换为 visit(treeNode)
    cout<< treeNode->element ;
    //后右孩子
    infix(treeNode->rightChild) ;
    cout << ")" ;
}

//前缀表达式和后缀表达式不存在奇异, 不需要构造完全前缀表达式和后缀表达式, 直接使用前序遍历和后序遍历即可得到


//二叉树的层次遍历: 使用队列的先入先出的的特性存储记忆同一层级下的节点
/***
 * @description 先访问自己(根节点) ,  然后需要线下访问, 此时将自己的左右孩子节点加入到队列中, 然后再取已经加入到队列中的孩子节点(同时也是队首元素)
 *              此时取得的队首元素一定是它的孩子节点,即为下一层次, 然后让当前节点指向队首的孩子节点, 然后访问, 再将当前节点加入队列的队尾,
 *              此时再将队首元素出队, 再次取得队首元素, 这时的队首元素为当前节点的父节点的右孩子, 也就是当前节点的兄弟节点, 属于同一层次的
 *              如此反复就可以进行二叉树的层次遍历
 *
 * @tparam T
 * @param treeNode
 */
template<class T>
void levelOrder(binaryTreeNode<T>* treeNode)
{
    //队列
    queue<binaryTreeNode<T>*> child_queue ;
    while (treeNode != NULL)
    {
        //先访问自己
        visit(treeNode) ;
        //再将自己的左右孩子节点加入队列
        if(treeNode->leftChild != nullptr)
        {
            child_queue.push(treeNode->leftChild) ;
        }
        if(treeNode->rightChild!= nullptr)
        {
            child_queue.push(treeNode->rightChild) ;
        }
        //判断队列是否为空
        if(child_queue.empty())
        {
            return ;
        }
        //获取下一层次需要遍历访问的节点: 队首元素
        treeNode = child_queue.front() ;
        //删除队首元素
        child_queue.pop() ;
    }
}




int main()
{
    
    
    return 0 ;
}


更多数据结构知识, 请关注小编, 一只不会写代码的小猪

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值