二叉树的先序,中序,后序遍历递归与非递归实现

二叉树先序遍历:

递归实现:

void PreOrderTraverse(BSTreeNode* root, int )
{
    if(!root)
    {
        return ;
    }
    res.push_back(root->value);
    PreOrderTraverse(root->left, 0);
    PreOrderTraverse(root->right, 0);
}

非递归实现:

void PreOrderTraverse(BSTreeNode* root)
{
    stack<BSTreeNode* > sta;
    sta.push(root);
    //BSTreeNode* temp = root;
    while(!sta.empty())
    {
        BSTreeNode *node = sta.top();
        sta.pop();
        res.push_back(node->value);
        if(node->right)
        {
            sta.push(node->right);
        }

        if(node->left)
        {
            sta.push(node->left);
        }

    }
}

 

二叉树中序遍历:

递归实现:

遍历左子树输出结点值,再输出中间值,最后遍历右子树输出节点值

vector<int> res;
void InOrderTraverse(BSTreeNode* root,int n)
{
    if(!root)
    {
        return ;
    }
    InOrderTraverse(root->left, 0);
    res.push_back(root->value);
    InOrderTraverse(root->right, 0);
}

非递归实现:

void InOrderTraverse(BSTreeNode* root)
{
    stack<BSTreeNode* > sta;
    sta.push(root);
    BSTreeNode* temp = root;
    while(!sta.empty())
    {
        while(temp->left)
        {
            sta.push(temp->left);
            temp = temp->left;
        }
        BSTreeNode *node = sta.top();
        res.push_back(node->value);
        sta.pop();
        if(node->right)
        {
            temp = node->right;
            sta.push(node->right);
        }
    }
}

 

void InOrderTraverse(BSTreeNode *root)
{
    stack<BSTreeNode* > sta;
    BSTreeNode* temp = root;
    while(temp != NULL || !sta.empty())
    {
        while(temp)
        {
            sta.push(temp);
            temp = temp->left;
        }

        if(!sta.empty())
        {
            temp = sta.top();
            res.push_back(temp->value);
            sta.pop();
            temp = temp->right;
        }
    }
}

 下面是另一种写法:

vector<int> res;
void InOrderTraverse(BSTreeNode* root)
{
    if(!root)
        return ;
    stack<pair<BSTreeNode*, int>> sta;
    sta.push({root, 0});
    BSTreeNode* temp;
    int times;
    while(!sta.empty())
    {
        temp = sta.top().first;
        times = sta.top().second;
        sta.pop();
        if(times == 0)
        {
            if(temp->right)
                sta.push({temp->right, 0});
            sta.push({temp, times, 1});
            if(temp->left)
                sta.push({temp->left, 0});
        }
        else
        {
            res.push_back(temp->val);
        }
    }
}

 

二叉树后序遍历:

递归实现:

void PostOrderTraverse(BSTreeNode* root, int)
{
    if(!root)
    {
        return;
    }
    PostOrderTraverse(root->left, 0);
    PostOrderTraverse(root->right, 0);
    res.push_back(root->value);
}

非递归实现:

第二种思路:要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。

void PostOrderTraverse(BSTreeNode* root)
{
    stack<BSTreeNode *> sta;
    sta.push(root);
    BSTreeNode* temp = root;
    BSTreeNode* pre = NULL;
    while(!sta.empty())
    {
        temp = sta.top();
        if((!temp->left && !temp->right) || (pre != NULL) && (pre == temp->left || pre == temp->right))
        {
            res.push_back(temp->value);
            sta.pop();
            pre = temp;
        }
        else
        {
            if(temp->right)
            {
                sta.push(temp->right);
            }

            if(temp->left)
            {
                sta.push(temp->left);
            }
        }
    }
}

 

  

posted @ 2016-05-10 21:10  genidong  阅读(295)  评论(0编辑  收藏  举报