7. 二叉树遍历( 先序、中序、后序 递归 非递归 )

RT, 部分参考了《剑指offer》

#pragma once
#include <iostream>
#include <vector>
#include <stack>
using namespace std;

struct BinaryTreeNode 
{
    int m_nValue;
    BinaryTreeNode* m_pLeft;
    BinaryTreeNode* m_pRight;
};

class BinaryTree
{
public:
    BinaryTreeNode* Construct(int preorder[], int inorder[], int length); // 根据先序、中序结果构造二叉树
    BinaryTreeNode* ConstructCore(int* startPreorder, int* endPreOrder, int* startInorder, int* endInorder);
  
// 递归, 遍历的结果放入vector中
void PreOrderTraverseRecursion(BinaryTreeNode* root, vector<int>& preOrder); void InOrderTraverseRecursion(BinaryTreeNode* root, vector<int>& inOrder); void PostOrderTraverseRecursion(BinaryTreeNode* root, vector<int>& postOrder);   // 非递归,遍历的结果放入vector中
void PreOrderTraverseStack(BinaryTreeNode* root, vector<int>& preOrder);
void InOrderTraverseStack(BinaryTreeNode* root, vector<int>& inOrder);
void PostOrderTraverseStack(BinaryTreeNode* root, vector<int>& postOrder);
public:
    BinaryTree(void);
    ~BinaryTree(void);

};

 

#include "BinaryTree.h"


BinaryTree::BinaryTree(void)
{
}


BinaryTree::~BinaryTree(void)
{
}

BinaryTreeNode* BinaryTree::Construct(int preorder[], int inorder[], int length)
{
    if (preorder == NULL || inorder == NULL || length < 0)
    {
        return NULL;
    }
    return ConstructCore(preorder, preorder + length - 1, inorder, inorder + length - 1);
}

BinaryTreeNode* BinaryTree::ConstructCore(int* startPreorder, int* endPreorder, int* startInorder, int* endInorder)
{
    int rootValue = startPreorder[0];
    BinaryTreeNode* root = new BinaryTreeNode();
    root->m_nValue = rootValue;
    root->m_pLeft = root->m_pRight = NULL;
    if (startPreorder == endPreorder)
    {
        if (startInorder == endInorder && *startInorder == *endInorder) // 叶子结点
        {
            return root;
        }
        else
            throw std::exception("Invalid input.");
    }

    // 在中序中找到该value所在位置
    int* rootInorder = startInorder;
    while (rootInorder <= endInorder && *rootInorder != rootValue)
    {
        rootInorder++;
    }
    if (rootInorder > endInorder)
    {
        throw std::exception("Invalid input.");
    }

    int leftLength = rootInorder  - startInorder;
    if (leftLength > 0) // 左子树
    {
        root->m_pLeft = ConstructCore(startPreorder + 1, startPreorder + leftLength, startInorder, rootInorder -1);
    }
    if(endInorder - rootInorder > leftLength) // 有右子树
    {
        root->m_pRight = ConstructCore(startPreorder + leftLength + 1, endPreorder, rootInorder + 1, endInorder);
    }
    return root;
}


void BinaryTree::PreOrderTraverseRecursion(BinaryTreeNode* root, vector<int>& preOrder)
{
    BinaryTreeNode* current = root;
    // 先序递归遍历
    if (current != NULL) 
    {
        preOrder.push_back(current->m_nValue);
        PreOrderTraverseRecursion(current->m_pLeft, preOrder);
        PreOrderTraverseRecursion(current->m_pRight, preOrder); 
    }
}

void BinaryTree::InOrderTraverseRecursion(BinaryTreeNode* root, vector<int>& inOrder)
{
    BinaryTreeNode* current = root;
    // 中序递归遍历
    if (current != NULL) 
    {
        InOrderTraverseRecursion(current->m_pLeft, inOrder);
        inOrder.push_back(current->m_nValue);
        InOrderTraverseRecursion(current->m_pRight, inOrder); 
    }
}
void BinaryTree::PostOrderTraverseRecursion(BinaryTreeNode* root, vector<int>& postOrder)
{
    BinaryTreeNode* current = root;
    // 后序递归遍历
    if (current != NULL) 
    {
        PostOrderTraverseRecursion(current->m_pLeft, postOrder);
        PostOrderTraverseRecursion(current->m_pRight, postOrder);
        postOrder.push_back(current->m_nValue);
    }
}

void BinaryTree::PreOrderTraverseStack(BinaryTreeNode* root, vector<int>& preOrder)
{
    // 非递归 先序遍历
    BinaryTreeNode* current = root;
    stack<BinaryTreeNode*> travelStack;
    while (current || !travelStack.empty())
    {
        if (current)
        {
            travelStack.push(current);
            preOrder.push_back(current->m_nValue); // 先序
            current = current->m_pLeft;
        }
        else // 左子树为NULL
        {
            current = travelStack.top();
            current = current->m_pRight;
            travelStack.pop(); // 根出栈
        }
    }

}

void BinaryTree::InOrderTraverseStack(BinaryTreeNode* root, vector<int>& inOrder)
{
    // 非递归 中序遍历
    BinaryTreeNode* current = root;
    stack<BinaryTreeNode*> travelStack;
    while (current || !travelStack.empty())
    {
        if (current)
        {
            travelStack.push(current);
            current = current->m_pLeft;
        }
        else
        {
            current = travelStack.top();
            inOrder.push_back(current->m_nValue); // 中序
            current = current->m_pRight;
            travelStack.pop();
        }
    }
}

void BinaryTree::PostOrderTraverseStack(BinaryTreeNode* root, vector<int>& postOrder)
{
    // 非递归 后序遍历
    int flag[1000]; // 使用一个标记,标记该node的右结点是否被访问过
    stack<BinaryTreeNode* > travelStack;

    BinaryTreeNode* current = root;
    while(current) // 先左
    {
        travelStack.push(current);
        flag[travelStack.size()] = 0;
        current = current->m_pLeft;
    }
    while(!travelStack.empty())
    {
        current = travelStack.top();

        while (current->m_pRight && flag[travelStack.size()] == 0) // 右子树未被访问过
        {
            flag[travelStack.size()] = 1; // 标记当前结点的右子节点被访问过了
            current = current->m_pRight; // 右子树

            while(current) // 先左
            {
                travelStack.push(current);
                flag[travelStack.size()] = 0;
                current = current->m_pLeft;
            }
            current = travelStack.top();           
        }

        // current的右子树为NULL 或 已被访问过
        postOrder.push_back(current->m_nValue); // 后序访问根结点
        travelStack.pop(); // 出栈
    }
}

 

#include <iostream>
#include "BinaryTree.h"

using namespace std;
int main(int agrc, char* argv[])
{
    BinaryTree bt;
    int preOrder[] = {1,2,4,7,3,5,6,8};
    int inOrder[] = {4,7,2,1,5,3,8,6};

    BinaryTreeNode* root = bt.Construct(preOrder, inOrder, 8);

    vector<int> preV1;
    vector<int> preV2;
    vector<int> inV1;
    vector<int> inV2;
    vector<int> postV1;
    vector<int> postV2;
    bt.PreOrderTraverseRecursion(root, preV1);
    bt.PreOrderTraverseStack(root, preV2);
    bt.InOrderTraverseRecursion(root, inV1);
    bt.InOrderTraverseStack(root, inV2);
    bt.PostOrderTraverseRecursion(root, postV1);
    bt.PostOrderTraverseStack(root, postV2);

    return 0;

}

 

 

posted on 2013-08-31 21:20  没有什么能够阻挡  阅读(298)  评论(0编辑  收藏  举报

导航