二叉樹的三種遍歷遞歸法和非遞歸法(前序、中序、後續)

二叉樹的前序遍歷:根->左->右

1、遞歸方法:

思路:我們知道遞歸就是將一個大問題不斷分成子問題進行處理,當達到遞歸終止條件時,跳出。因此在前序遍歷中我們把每一個節點分成三部分,即:根節點、左子樹、右子樹。

例如下面這個二叉樹遞歸過程:

這裏寫圖片描述

轉化成代碼代碼:

void PrevOrder()     //1、遞歸法    
{
    Node* root = _Root;
    _PrevOrder(root);
}
void _PrevOrder(Node* root)
{
    if (root)
    {
        cout<<root->_Data<<endl;
        _PrevOrder(root->_Left);
        _PrevOrder(root->_Right);
    }
}

2、非遞歸法

思路:不用遞歸去遍歷,我們如何獲得上個節點的信息呢??這裏,我們可以建立一個棧,這個棧用於保存每次化成子問題的根結點。

例如下面這個二叉樹非遞歸過程:

這裏寫圖片描述

代碼:

void PrevOrderNonR()  //2、非遞歸法(利用棧的思想)
{
    Node* cur = _Root;
    stack<Node*> s;
    while (!s.empty() || cur)
    {
        while(cur)
        {
            cout<<cur->_Data<<"  ";
            s.push(cur);
            cur = cur->_Left;
        }
        Node* top =  s.top();
        s.pop();
        cur = top->_Right;
    }
} 

二叉樹的中序遍歷:左->根->右

1、遞歸方法:

void InOrder()   //中序遞歸遍歷
{
    _InOrder(_root);
    cout << endl;
}
void _InOrder(Node* root)
{
    if (root != NULL)
    {
        _InOrder(root->_left);
        cout << root->_data << "  ";
        _InOrder(root->_right);
    }
}

2、非遞歸方法:

void InOrderNoR() //中序非遞歸遍歷
    {
        stack<Node*> s;
        Node* cur = _root;
        while (cur ||  !s.empty())
        {
            while (cur)
            {
                s.push(cur);
                cur = cur->_left;
            }
            Node* top = s.top();
            cout << top->_data << "  ";
            s.pop();
            cur = top->_right;
        }
        cout << endl;
    }

二叉樹的後序遍歷:左->右->根

1、遞歸方法:

    void PostOrder() //後續遞歸
{
    _PostOrder(_root);
    cout << endl;
}
    void _PostOrder(Node* root)
{
    if (root != NULL)
    {
        _PostOrder(root->_left);
        _PostOrder(root->_right);
        cout << root->_data << "  ";
    }
}

2、非遞歸方法:

void PostOrderNoR() //後續非遞歸
{
    stack<Node*> s;
    Node* cur = _root;
    Node* prev = NULL;
    while (cur || !s.empty())
    {
        while (cur)
        {
            s.push(cur);
            cur = cur->_left;
        }
        Node* top = s.top();
        if (top->_right == NULL || top->_right == prev)
        {
            cout << top->_data << "  ";
            prev = top;
            s.pop();
        }
        else
        {
            cur = top->_right;
        }
    }
    cout << endl;
}
發佈了71 篇原創文章 · 獲贊 62 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章