二叉树遍历c++实现

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

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


遍历策略

二叉树遍历c++实现

  • 前序遍历:先访问一个节点,再访问左右子树。以图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();

}