二叉树遍历c++实现

文章中部分内容和思路来自《数据结构、算法与应用 c++语言描述》

接续上一篇文章《二叉树的存储与c++描述》:http://blog.csdn.net/superyang_/article/details/79213272

遍历策略

  • 前序遍历:先访问一个节点,再访问左右子树。以图11-5 为例,访问次序依次为+*ab/cd;+++abcd;/+-a+xy*+b*ca
  • 中序遍历:先访问左子树,再访问该节点,再访问右子树。以图11-5为例,访问次序依次为a*b+c/d;a+b+c+d;-a+x+y/+b*c*a
  • 后序遍历:先访问左右子树,再访问该节点。以图11-5为例,访问次序依次为ab*cd/+;ab+c+d+;a-xy++b+ca**/
  • 层次遍历:从上到下,从左到右,依次访问树的元素。以图11-5为例,访问次序依次为+*/abcd;++d+cab;/+*-++*axybca

代码实现

-------------
BinaryTree.h:
-------------
#ifndef BINARYTREE_H
#define BINARYTREE_H
 
 
#include <QDebug>
 
 
template <class T>
struct BinaryTreeNode
{
public:
    BinaryTreeNode() {lChild = rChild = NULL;}
    BinaryTreeNode(const T &value)
    {
        this->value = value;
        lChild = rChild = NULL;
    }
    BinaryTreeNode(const T &value, BinaryTreeNode *lChild, BinaryTreeNode *rChild)
    {
        this->value = value;
        this->lChild = lChild;
        this->rChild = rChild;
    }
 
 
public:
    T value;
    BinaryTreeNode *lChild;
    BinaryTreeNode *rChild;
};
 
 
//template <class E>
class ExpressBinaryTree
{
public:
    ExpressBinaryTree();
    explicit ExpressBinaryTree(const QString &express);
 
 
public:
    void preOrder(BinaryTreeNode<char> *root = NULL);
    void inOrder(BinaryTreeNode<char> *root = NULL);
    void postOrder(BinaryTreeNode<char> *root = NULL);
    void levelOrder(BinaryTreeNode<char> *root = NULL);
 
 
    BinaryTreeNode<char> *getRoot() const;
 
 
protected:
    void printNodeValue(BinaryTreeNode<char> *node);
    QString Middle2After(const QString &str);  // 中缀表达式转换成后缀表达式
 
 
private:
    BinaryTreeNode<char> *_root; // 根节点
};
 
 
#endif // BINARYTREE_H
 
---------------
BinaryTree.cpp:
---------------
#include "BinaryTree.h"
 
 
#include <QStack>
#include <QQueue>
#include <iostream>
 
 
using namespace std;
 
 
ExpressBinaryTree::ExpressBinaryTree()
{
    _root = NULL;
}
 
 
ExpressBinaryTree::ExpressBinaryTree(const QString &express)
{
    _root = NULL;
 
 
    // 中缀表达式转换成后缀表达式
    QString outFixexpress = Middle2After(express);
 
 
    // 利用后缀表达式构造表达式树
    QStack<BinaryTreeNode<char> *> stack;
 
 
    char *arr = new char[outFixexpress.size() + 1];
    memset(arr, 0, outFixexpress.size() + 1);
    memcpy(arr, outFixexpress.toLocal8Bit().data(), outFixexpress.size());
    for (int i = 0; (unsigned)i < strlen(arr); i++)
    {
        BinaryTreeNode<char> *newNode = new BinaryTreeNode<char>(arr[i]);
 
 
        if (arr[i] == '+' || arr[i] == '-' || arr[i] == '*' || arr[i] == '/')
        {
            if (!stack.isEmpty())
            {
                newNode->rChild = stack.top();
                stack.pop();
            }
 
 
            if (!stack.isEmpty())
            {
                newNode->lChild = stack.top();
                stack.pop();
            }
        }
 
 
        stack.push(newNode);
    }
 
 
    _root = stack.top();
}
 
 
// 前序遍历
void ExpressBinaryTree::preOrder(BinaryTreeNode<char> *root)
{
    if (NULL == root)
        return;
 
 
    printNodeValue(root);
    preOrder(root->lChild);
    preOrder(root->rChild);
}
 
 
// 中序遍历
void ExpressBinaryTree::inOrder(BinaryTreeNode<char> *root)
{
    if (NULL == root)
        return;
 
 
    inOrder(root->lChild);
    printNodeValue(root);
    inOrder(root->rChild);
}
 
 
// 后续便利
void ExpressBinaryTree::postOrder(BinaryTreeNode<char> *root)
{
    if (NULL == root)
        return;
 
 
    postOrder(root->lChild);
    postOrder(root->rChild);
    printNodeValue(root);
}
 
 
// 层次便利
void ExpressBinaryTree::levelOrder(BinaryTreeNode<char> *root)
{
    if (NULL == root)
        return;
 
 
    QQueue<BinaryTreeNode<char> *> queue;
 
 
    while(NULL != root)
    {
        printNodeValue(root); // 访问节点数据
 
 
        // 左右子树入队列
        if (NULL != root->lChild)
        {
            queue.push_back(root->lChild);
        }
 
 
        if (NULL != root->rChild)
        {
            queue.push_back(root->rChild);
        }
 
 
        // 取队首元素为当前访问节点
        if (!queue.isEmpty())
        {
            root = queue.front();
            queue.pop_front();
        }
        else
        {
            return;
        }
    }
}
 
 
BinaryTreeNode<char> *ExpressBinaryTree::getRoot() const
{
    return _root;
}
 
 
void ExpressBinaryTree::printNodeValue(BinaryTreeNode<char> *node)
{
    cout << node->value;
}
 
 
QString ExpressBinaryTree::Middle2After(const QString &str)
{
    /*
     * Step1:遇到操作数直接输出[ps:以下输出皆表示输出到后缀表达式]
     * Step2:栈空,遇到运算符直接入栈
     * Step3:遇到左括号,直接入栈
     * Step4:遇到右括号,将栈中元素依次出栈输出[ps:最后的左括号不输出]
     * Step5:遇到+-*除,出栈所有栈顶优先级大于或等于该运算符的栈顶元素,运算符入栈
    **/
    QStack<char> st;
    char stackCh;
    char *arr = new char[str.size() + 1];
    memset(arr, 0, str.size() + 1);
    memcpy(arr, str.toLocal8Bit().data(), str.size());
 
 
    char retArr[str.size() + 1];
    memset(retArr, 0, str.size() + 1);
//    QString ret(str.size() + 1, 0);
//    char *p = ret.toLocal8Bit().data();
    char *p = retArr;
    for (int i = 0; (unsigned)i < strlen(arr); i++)
    {
        if (arr[i] == '+' || arr[i] == '-' || arr[i] == '*' || arr[i] == '/' || arr[i] == '(' || arr[i] == ')')
        {
            if (st.isEmpty() || arr[i] == '(') // 栈空或左括号入栈
            {
                st.push(arr[i]);
                continue;
            }
 
 
            if (arr[i] == ')')
            {
                while(!st.isEmpty())
                {
                    stackCh = st.top();
                    if (stackCh != '(')
                    {
                        memcpy(p++, &stackCh, 1);
                    }
                    st.pop();
                }
                continue;
            }
 
 
            if (arr[i] == '+' || arr[i] == '-' || arr[i] == '*' || arr[i] == '/')
            {
                if (arr[i] == '+' || arr[i] == '-')
                {
                    stackCh = st.top();
                    while(!st.isEmpty() && stackCh != '(')
                    {
                        memcpy(p++, &stackCh, 1);
                        st.pop();
                    }
                }
                if (arr[i] == '*' || arr[i] == '/')
                {
                    stackCh = st.top();
                    while(!st.isEmpty() && (stackCh == '*' || stackCh == '/'))
                    {
                        memcpy(p++, &stackCh, 1);
                        st.pop();
                    }
                }
                st.push(arr[i]);
                continue;
            }
        }
        else
        {
            memcpy(p++, &arr[i], 1); // 操作数直接输出
            continue;
        }
    }
 
 
    return QString::fromLocal8Bit(retArr);
}
 
---------
main.cpp:
---------
#include <QCoreApplication>
 
 
#include "BinaryTree.h"
 
 
#include <QDebug>
 
 
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
 
 
    QString express = "(a*b)+(c/d)";
    ExpressBinaryTree bNode(express); // 构造一个表达式树
    qDebug() << "前序遍历结果:";
    bNode.preOrder(bNode.getRoot());
    qDebug() << "\n中序遍历结果:";
    bNode.inOrder(bNode.getRoot());
    qDebug() << "\n后续遍历结果:";
    bNode.postOrder(bNode.getRoot());
    qDebug() << "\n层次遍历结果:";
    bNode.levelOrder(bNode.getRoot());
 
 
    return a.exec();
 
 
}
 
 

 

 ====================================================================

博主有自己的个人主页啦!请求关注,请求支持。QAQ.

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SuperYang_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值