二叉树遍历——递归、非递归版

Posted on 2021-08-29 10:20  foghorn  阅读(39)  评论(0编辑  收藏  举报

前序遍历

 1 /* 前序遍历递归版 */
 2 void PreOrderRec(Node * node)
 3 {
 4     if (node == nullptr)
 5         return;
 6     cout << node->data << " ";   // 先输出当前结点   
 7     PreOrderRec(node->left);     // 然后输出左孩子
 8     PreOrderRec(node->right);    // 最后输出右孩子
 9 }
10 
11 /* 前序遍历非递归版 */
12 void PreOrderNonRec(Node * node)
13 {
14     if (node == nullptr)
15         return;
16 
17     stack<Node*> S;
18     cout << node->data << " ";
19     S.push(node);
20     node = node->left;
21 
22     while (!S.empty() || node)
23     {
24         while (node)
25         {
26             cout << node->data << " "; // 先输出当前结点  
27             S.push(node);
28             node = node->left;         // 然后输出左孩子
29         }                              // while 结束意味着左孩子已经全部输出
30 
31         node = S.top()->right;         // 最后输出右孩子
32         S.pop();
33     }
34 }

 中序遍历

/* 中序遍历递归版 */
void InOrderRec(Node * node)
{
    if (node == nullptr)
        return;

    InOrderRec(node->left);     // 先输出左孩子
    cout << node->data << " ";  // 然后输出当前结点
    InOrderRec(node->right);    // 最后输出右孩子
}

/* 中序遍历非递归版 */
void InOrderNonRec(Node * node)
{
    if (node == nullptr)
        return;

    stack<Node*> S;
    S.push(node);
    node = node->left;

    while (!S.empty() || node)
    {
        while (node)
        {
            S.push(node);
            node = node->left;
        }                             // while 结束意味着左孩子为空

        cout << S.top()->data << " "; // 左孩子已经全部输出,接着输出当前结点
        node = S.top()->right;        // 左孩子全部输出,当前结点也输出后,最后输出右孩子
        S.pop();
    }
}

后序遍历

/* 后序遍历递归版 */
void PostOrderRec(Node * node)
{
    if (node == nullptr)
        return;

    PostOrderRec(node->left);   // 先输出左孩子
    PostOrderRec(node->right);  // 然后输出右孩子
    cout << node->data << " ";  // 最后输出当前结点
}

/* 后序遍历非递归版 */
void PostOrderNonRec(Node * node)
{
    if (node == nullptr)
        return;

    Node * pre = nullptr;
    stack<Node*> S;
    S.push(node);

    while (!S.empty())
    {
        node = S.top();

        if ((!node->left && !node->right) ||                    // 第一个输出的必是无左右孩子的叶子结点,只要第一个结点输出,
            (pre && (pre == node->left || pre == node->right))) // 以后的 pre 就不会是空。此处的判断语句加入一个 pre,只是用来
        {                                                       // 确保可以正确输出第一个结点。
            cout << node->data << " ";  // 左右孩子都全部输出,再输出当前结点
            pre = node;
            S.pop();
        }
        else
        {
            if (node->right)
                S.push(node->right);  // 先进右孩子,再进左孩子,取出来的才是左孩子
            if (node->left)
                S.push(node->left);
        }
    }
}

 

Copyright © 2024 foghorn
Powered by .NET 9.0 on Kubernetes