二叉树的前序, 中序, 后续遍历,层次遍历
//
// 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 ;
}
更多数据结构知识, 请关注小编, 一只不会写代码的小猪