zoukankan      html  css  js  c++  java
  • 二叉树遍历&构建


    二叉树的遍历分为三类:前序遍历、中序遍历和后序遍历。

    这里写图片描述

    (1)前序遍历

    先访问根节点,再遍历左子树,最后遍历右子树;并且在遍历左右子树时,仍需先遍历左子树,然后访问根节点,最后遍历右子树。
    这里写图片描述

    (2)中序遍历

    先遍历左子树、然后访问根节点,最后遍历右子树;并且在遍历左右子树的时候。仍然是先遍历左子树,然后访问根节点,最后遍历右子树。

    这里写图片描述

    (3)后序遍历

    先遍历左子树,然后遍历右子树,最后访问根节点;同样,在遍历左右子树的时候同样要先遍历左子树,然后遍历右子树,最后访问根节点。
    这里写图片描述

    (4)层序遍历

    用BFS每一层的向下遍历。


    代码实现

    二叉树的构建、查找、删除

    #include<iostream>
    #include<string>
    #include<string.h>
    #include<algorithm>
    #include<iomanip>
    #include<cstdio>
    #include<queue>
    #include<stack> 
    using namespace std;
    
    struct node {
        int val;
        node *lch, *rch;
    };
    
    //插入数值
    node *insert(node *p, int x)
    {
        if (p == NULL)
        {
            node *q = new node;
            q->val = x;
            q->lch = q->rch = NULL;
            return q;
        }
        else
        {
            if (x < p->val) p->lch = insert(p->lch, x);
            else p->rch = insert(p->rch, x);
            return p;
        }
    }
    
    //查找数值
    bool find(node *p, int x)
    {
        if (p == NULL) return false;
        else if (x == p->val) return true;
        else if (x < p->val) return find(p->lch, x);
        else return find(p->rch, x);
    }
    
    //删除数值
    node *remove(node *p, int x)
    {
        if (p == NULL) return NULL;
        else if (x < p->val) p->lch = remove(p->lch, x);
        else if (x > p->val) p->rch = remove(p->rch, x);
        else if (p->lch == NULL)
        {
            node *q = p->rch;
            delete p;
            return q;
        }
        else if (p->lch->rch == NULL)
        {
            node *q = p->lch;
            q->rch = p->rch;
            delete p;
            return q;
        }
        else
        {
            node *q;
            for (q = p->rch; q->rch->rch != NULL; q = q->rch);
            node *r = q->rch;
            q->rch = r->lch;
            r->lch = p->lch;
            r->rch = p->rch;
            delete p;
            return r;
        }
        return p;    //没有找到p点
    }
    
    int main()
    {
        node *head = NULL;
        int n;
        cout << "1:  insert     2:  find     3:  remove
    ";
        while (cin >> n)
        {
            int x;
            if (n == 1)
            {
                cin >> x;
                head = insert(head, x);
            }
            else if (n == 2)
            {
                cin >> x;
                if (find(head, x))
                {
                    cout << "Find it!
    ";
                }
                else
                {
                    cout << "Not find!
    ";
                }
            }
            else
            {
                cin >> x;
                head = remove(head, x);
            }
        }
    }

    非递归遍历

    先序遍历

    void PreOrder2(node *p)
    {
        stack<node*> stack;
        while (p || stack.size())
        {
            if (p)
            {
                stack.push(p);
                cout << p->val<<" ";
                p = p->lch;
            }
            else
            {
                p = stack.top();
                stack.pop();
                p = p->rch;
            }
        }
    }

    中序遍历

    void InOrder2(node *p)
    {
        stack<node*> stack;
        while (p || stack.size())
        {
            if (p)
            {
                stack.push(p);
                p = p->lch;
            }
            else
            {
                p = stack.top();
                stack.pop();
                cout << p->val << " ";
                p = p->rch;
            }
        }
    }

    后序遍历

    void PostOrder2(node *p)
    {
        stack<node*> stack;
        while (p || stack.size())
        {
            while (p)
            {
                p->left = 1;
                p = p->lch;
                stack.push(p);
            }
            while ((stack.top()->left) && (stack.top()->right) && stack.size())
            {
                p = stack.top();
                stack.pop();
                cout << p->val << " ";
            }
            if (stack.size())
            {
                p->right = 1;
                p = p->rch;
            }
        }
    }

    递归遍历

    void view(node *p)
    {
        if (p)
        {
            cout << p->val << " ";
        }
    }

    先序遍历

    void PreOrder(node *p)
    {
        if (p)
        {
            view(p);
            PreOrder(p->lch);
            PreOrder(p->rch);
        }
    }

    中序遍历

    void InOrder(node *p)
    {
        if (p)
        {
            InOrder(p->lch);
            view(p);
            InOrder(p->rch);
        }
    }

    后序遍历

    void PostOrder(node *p)
    {
        if (p)
        {
            PostOrder(p->lch);
            PostOrder(p->rch);
            view(p);
        }
    }

    层序遍历

    void LevelOrder(node *p)
    {
        queue<node*> queue;
        queue.push(p);
        while (queue.size())
        {
            p = queue.front();
            queue.pop();
            cout << p->val << " ";
            if (p->lch) queue.push(p->lch);
            if (p->rch) queue.push(p->rch);
        }
    }

    整体代码测试

    #include<iostream>
    #include<string>
    #include<string.h>
    #include<algorithm>
    #include<iomanip>
    #include<cstdio>
    #include<queue>
    #include<stack> 
    using namespace std;
    
    struct node {
        int val;
        node *lch, *rch;
        bool left, right;
    };
    
    //插入数值
    node *insert(node *p, int x)
    {
        if (p == NULL)
        {
            node *q = new node;
            q->val = x;
            q->lch = q->rch = NULL;
            return q;
        }
        else
        {
            if (x < p->val) p->lch = insert(p->lch, x);
            else p->rch = insert(p->rch, x);
            return p;
        }
    }
    
    //查找数值
    bool find(node *p, int x)
    {
        if (p == NULL) return false;
        else if (x == p->val) return true;
        else if (x < p->val) return find(p->lch, x);
        else return find(p->rch, x);
    }
    
    //删除数值
    node *remove(node *p, int x)
    {
        if (p == NULL) return NULL;
        else if (x < p->val) p->lch = remove(p->lch, x);
        else if (x > p->val) p->rch = remove(p->rch, x);
        else if (p->lch == NULL)
        {
            node *q = p->rch;
            delete p;
            return q;
        }
        else if (p->lch->rch == NULL)
        {
            node *q = p->lch;
            q->rch = p->rch;
            delete p;
            return q;
        }
        else
        {
            node *q;
            for (q = p->rch; q->rch->rch != NULL; q = q->rch);
            node *r = q->rch;
            q->rch = r->lch;
            r->lch = p->lch;
            r->rch = p->rch;
            delete p;
            return r;
        }
        return p;    //没有找到p点
    }
    
    void view(node *p)
    {
        if (p)
        {
            cout << p->val << " ";
        }
    }
    
    void PreOrder(node *p)
    {
        if (p)
        {
            view(p);
            PreOrder(p->lch);
            PreOrder(p->rch);
        }
    }
    
    void InOrder(node *p)
    {
        if (p)
        {
            InOrder(p->lch);
            view(p);
            InOrder(p->rch);
        }
    }
    
    void PostOrder(node *p)
    {
        if (p)
        {
            PostOrder(p->lch);
            PostOrder(p->rch);
            view(p);
        }
    }
    
    void PreOrder2(node *p)
    {
        stack<node*> stack;
        while (p || stack.size())
        {
            if (p)
            {
                stack.push(p);
                cout << p->val<<" ";
                p = p->lch;
            }
            else
            {
                p = stack.top();
                stack.pop();
                p = p->rch;
            }
        }
    }
    
    void InOrder2(node *p)
    {
        stack<node*> stack;
        while (p || stack.size())
        {
            if (p)
            {
                stack.push(p);
                p = p->lch;
            }
            else
            {
                p = stack.top();
                stack.pop();
                cout << p->val << " ";
                p = p->rch;
            }
        }
    }
    
    void PostOrder2(node *p)
    {
        stack<node*> stack;
        while (p || stack.size())
        {
            while (p)
            {
                p->left = 1;
                p = p->lch;
                stack.push(p);
            }
            while ((stack.top()->left) && (stack.top()->right) && stack.size())
            {
                p = stack.top();
                stack.pop();
                cout << p->val << " ";
            }
            if (stack.size())
            {
                p->right = 1;
                p = p->rch;
            }
        }
    }
    
    void LevelOrder(node *p)
    {
        queue<node*> queue;
        queue.push(p);
        while (queue.size())
        {
            p = queue.front();
            queue.pop();
            cout << p->val << " ";
            if (p->lch) queue.push(p->lch);
            if (p->rch) queue.push(p->rch);
        }
    }
    
    int main()
    {
        node *head = NULL;
        int n;
        cout << "1:  insert     2:  find     3:  remove
    ";
        cout << "4:  PreOrder   5:  InOrder  6:  PostOrder
    ";
        cout << "7:  PreOrder2  8:  InOrder2 9:  PostOrder2
    ";
        cout << "10: LevelOrder
    ";
        while (cin >> n)
        {
            int x;
            if (n == 1)
            {
                cin >> x;
                head = insert(head, x);
            }
            else if (n == 2)
            {
                cin >> x;
                if (find(head, x))
                {
                    cout << "Find it!
    ";
                }
                else
                {
                    cout << "Not find!
    ";
                }
            }
            else if (n == 3)
            {
                cin >> x;
                head = remove(head, x);
            }
            else if (n == 4)
            {
                PreOrder(head);
                cout << endl;
            }
            else if (n == 5)
            {
                InOrder(head);
                cout << endl;
            }
            else if (n == 6)
            {
                PostOrder(head);
                cout << endl;
            }
            else if (n == 7)
            {
                PreOrder2(head);
                cout << endl;
            }
            else if (n == 8)
            {
                InOrder2(head);
                cout << endl;
            }
            else if (n == 9)
            {
                PostOrder(head);
                cout << endl;
            }
            else if (n == 10)
            {
                LevelOrder(head);
                cout << endl;
            }
        }
    }

    其他详解

    CSDN中关于二叉树遍历的其他详解


    练习

    PAT 1020. Tree Traversals (25)

    Fighting~
  • 相关阅读:
    数组和排序算法(冒泡、选择、插入排序)
    异常
    线程的五个状态,sleep和wait
    ArrayList、Vector、LinkedList
    String,StringBuffer,StringBuilder的区别
    Math.round(),Math.ceil(),Math.floor()的区别
    单例模式之双重锁模式、静态内部类模式、饿汉模式、懒汉模式,和安全的懒汉模式
    工厂模式简单的汽车工厂
    存储过程的优点
    数据库SQL特点数据查询,数据操纵,数据定义,数据控制,建立索引, 事务acid,数据库隔离级别
  • 原文地址:https://www.cnblogs.com/Archger/p/12774801.html
Copyright © 2011-2022 走看看