美文网首页
数据结构Step by Step之树(1)- 二叉树 前序、中序

数据结构Step by Step之树(1)- 二叉树 前序、中序

作者: nlpjoe | 来源:发表于2016-04-14 01:58 被阅读340次

    一、二叉树的基本概念

    每个结点最多有两棵子树,左子树和右子树,次序不可以颠倒。
    性质:
    1. 非空二叉树的第n层上至多有2^(n-1)个元素。
    2. 深度为h的二叉树至多有2^h-1个结点。

    完全二叉树:除了最大的层次即成为一颗满二叉树且层次最大那层所有的结点均向左靠齐,即集中在左面的位置上,不能有空位置。
    对于完全二叉树,设一个结点为i则其父节点为i/22i为左子节点,2i+1为右子节点。

    满二叉树:所有终端都在同一层次,且非终端结点的度数为2
    在满二叉树中若其深度为h,则其所包含的结点数必为2^h-1

    完全二叉树与满二叉树.jpg

    二、存储结构

    1.通常以链式结构存储(主流
    struct TreeNode {
    datatype val;
    TreeNode left,right;
    TreeNode(datatype x) : val(x), left(NULL), right(NULL) {}
    };
    2.也有用数组的顺序结构存储(非主流:速度较快,占有空间大)
    struct TreeNode {
    datatype val;
    int left, int right;
    TreeNode(datatype x) : val(x), left(NULL), right(NULL) {}
    };

    三、二叉树的遍历

    遍历即将树的所有结点访问且仅访问一次。按照根节点位置的不同分为前序遍历,中序遍历,后序遍历。

     前序遍历:根节点->左子树->右子树
     中序遍历:左子树->根节点->右子树
     后序遍历:左子树->右子树->根节点
    

    总结:就是遍历时 根节点 的位置不同。

    例如:求下面树的三种遍历顺序

    二叉树.png

    前序:abdfegc
    中序:dfebgac
    后序:fedgbca

    四、练习题LeetCode105 Construct Binary Tree from Preorder and Inorder Traversal

    题目:给定一棵树的前序遍历和中序遍历序列,构建这棵树。
    注意:可以假定树中不存在重复的值。
    分析:
    1. 前序遍历序列第一个点是根结点x
    2. 中序遍历序列中找到这个点x的下标
    3. 中序遍历序列中的x的左边序列对应左子树
    4. 中序遍历序列中的x的右边序列对应右子树

    AC代码:

    class Solution {
    public:
        TreeNode* help(vector<int>& preorder, vector<int>& inorder, int fromp, int fromi, int size) {
            if(size == 0) return 0;
            TreeNode *root = new TreeNode(preorder[fromp]);
            int i;
            for(i = fromi; inorder[i] != preorder[fromp]; ++i)
            ;
            root->left = help(preorder, inorder, fromp + 1, fromi, i - fromi);
            root->right = help(preorder, inorder, fromp + 1 + i - fromi, i + 1, size - 1 - i + fromi);
            return root;
        }
        TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
            return help(preorder, inorder, 0, 0, (unsigned int)preorder.size());
        }
    };
    

    这里比较纠结的是递归的fromp和fromi,需要细心的思考。这里给出一个递归的样例,假设树是我们的这个例子,即给出的前序遍历和中序遍历序列的顺序为:
    前序:abdfegc
    中序:dfebgac
    函数调用的顺序如下:
    ('-':表示深度,HELP函数,结点类型,结点值):
    HELP(Pre, In, 0, 0, 7) root a
    -HELP(Pre, In, 1, 0, 5) left b
    --HELP(Pre, In, 2, 0, 3) left d
    ---HELP(Pre, In, 3, 0, 0) left NULL
    ---HELP(Pre, In, 3, 1, 2) right e
    ----HELP(Pre, In, 4, 1, 1) left f
    -----HELP(Pre, In, 5, 1, 0) left NULL
    -----HELP(Pre, In, 5, 2, 0) right NULL
    ----HELP(Pre, In, 5, 3, 0) right NULL
    --HELP(Pre, In, 5, 4, 1) right g
    ---HELP(Pre, In, 6, 4, 0) left NULL
    ---HELP(Pre, In, 6, 5, 0) right NULL
    -HELP(Pre, In, 6, 6, 1) right c
    --HELP(Pre, In, 7, 6, 0) left NULL
    --HELP(Pre, In, 7, 7, 0) right NULL


    二叉树.png

    五、思考题:LeetCode106 根据前序和后序遍历序列构建树

    相关文章

      网友评论

          本文标题:数据结构Step by Step之树(1)- 二叉树 前序、中序

          本文链接:https://www.haomeiwen.com/subject/avrglttx.html