博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
二叉树
阅读量:6719 次
发布时间:2019-06-25

本文共 4617 字,大约阅读时间需要 15 分钟。

  1. 二叉树的性质
    (1) 在二叉树的第 i 层最多有 2^i-1 个结点 (i>=1).
    (2) 深度为 k 的二叉树最多有 2^k - 1 个结点 (k>=1).
    (3) 对任何一棵二叉树,如果其叶子结点数为 n0, 度为 2 的结点数为 n2, 则 n0 = n2 + 1. 原因:设度为 1 的结点数为 n1, 则结点总数 n = n0 + n1 + n2; 设分支数为 B, 由于只有根结点没有分支进入, 因此 n = B + 1; 由于分支都是从度为 1 或 2 的结点引出的, 因此 B = n1 + 2 * n2; 联立上述等式可得 n0 = n2 + 1.
  2. 满二叉树
    深度为 k 且有 2^k - 1 个结点的二叉树。
  3. 完全二叉树

    (1) 深度为 k、有 n 个结点的二叉树,其每个结点的编号与深度为 k 的满二叉树中编号从 1~n 的结点一一对应.
    (2) 叶子结点只可能在层数最大的两层上出现。
    (3) 对任意结点,若其右下分支下的子孙的最大层次为 lv, 则其左下分支下的子孙的最大层次必为 lv / lv + 1
    (4) 结点数为 n 的完全二叉树,其深度为 logn + 1.
    (5) 结点数为 n 的完全二叉树,结点按层编号,则对编号为 i 的结点 (1 <= i <= n):

    若 i==1, 则结点 i 为二叉树的根, 无双亲;     若 i>1 , 则结点 i 的双亲是 i/2;     若 2i>n, 则结点 i 无左孩子, 否则其左孩子是结点 2i;     若 2i+1>n, 则结点 i 无右孩子, 否则其右孩子是结点 2i+1.
  4. 存储结构

    二叉链表的存储表示

    class BiTNode {    int data;    BiTNode lchild, rchild;}
  5. 先序遍历: 根-左-右

    (1) 递归

    void preOrderRecursive(BiTNode tree) {        if(tree!=null) {            visit(tree);            preOrderRecursive(tree.lchild);            preOrderRecursive(tree.rchild);        }    }

    (2) 非递归

    :初始化栈,并且树的根结点进栈;每次循环都将栈顶结点出栈并打印,然后先后将该结点的右子结点左子结点进栈,直到栈为空。

    void preOrder(BiTNode tree) {        if(tree==null) {            return;        }        LinkedList
    stack = new LinkedList
    (); stack.push(tree); while(stack.size()>0) { BiTNode node = stack.pop(); visit(node); if(node.rchild!=null) { stack.push(node.rchild); } if(node.lchild!=null) { stack.push(node.lchild); } } }
  6. 中序遍历: 左-根-右

    (1) 递归

    void inOrderRecursive(BiTNode tree) {        if(tree!=null) {            inOrderRecursive(tree.lchild);            visit(tree);            inOrderRecursive(tree.rchild);        }    }

    (2) 非递归

    :初始化栈,并且树的根结点进栈。每次循环中,首先向左走到尽头并将访问到的每个结点进栈,此时栈顶存在空指针,需要将其出栈,然后将栈顶结点出栈,并访问该结点,同时将该结点的右孩子进栈;直到栈为空。

    void inOrder(BiTNode tree) {        if(tree==null) {            return;        }        LinkedList
    stack = new LinkedList
    (); stack.push(tree); while(stack.size()>0) { BiTNode node = stack.peek(); while(node!=null) { stack.push(node.lchild); node = stack.peek(); } stack.pop(); if(stack.size()>0) { node = stack.pop(); visit(node); stack.push(node.rchild); } } }

    :初始化栈。每次循环中,若当前结点不空时将该结点进栈,并遍历其左子树;否则将该结点出栈并访问该结点,同时将该结点的右孩子进栈;直到当前结点为空并且栈为空。

    void inOrder(BiTNode tree) {        if(tree==null) {            return;        }        LinkedList
    stack = new LinkedList
    (); BiTNode node = tree; while(node!=null || stack.size()>0) { if(node!=null) { stack.push(node); node = node.lchild; } else { node = stack.pop(); visit(node); node = node.rchild; } } }
  7. 后序遍历: 左-右-根

    (1) 递归

    void postOrderRecursive(BiTNode tree) {        if(tree!=null) {            postOrderRecursive(tree.lchild);            postOrderRecursive(tree.rchild);            visit(tree);        }    }

    (2) 非递归

    :为每个结点增加一个访问标志位 visited; 初始化栈。每次循环中,首先将根结点及其左子树进栈,并将每个结点的访问标志位置为 true,使得栈顶为最左边的左孩子,栈底为根结点;然后将栈顶结点出栈,若该结点的访问标志位为 true, 即该结点被访问了一次,要将该结点重新进栈, 并置其访问标志位为 false, 再访问该结点的右孩子;若该结点的访问标志位为 false, 即该结点被访问了两次, 要输出该结点的值,并将当前结点置为空;直到当前结点为空而且栈为空。

    void postOrder(BiTNode tree) {        if(tree==null) {            return;        }        List
    stack = new LinkedList
    (); BiTNode node = tree; while(node!=null || stack.size()>0) { while(node!=null) { node.visited = true; stack.push(node); node = node.lchild; } if(stack.size()>0) { BiTNode temp = stack.pop(); if(temp.visited) { temp.visited = false; stack.push(temp); node = temp.rchild; } else { visit(temp); node = null; } } } }
  8. 层次遍历

    void levelOrder(BiTNode tree) {        if(tree==null) {            return;        }        LinkedList
    queue = new LinkedList
    (); queue.add(tree); while(queue.size()>0) { BiTNode node = queue.remove(); visit(node); if(node.lchild!=null) { queue.add(node.lchild); } if(node.rchild!=null) { queue.add(node.rchild); } } }

转载地址:http://mdjmo.baihongyu.com/

你可能感兴趣的文章
Oracle 序列(自增ID)
查看>>
这应该是你们想要的 DOS 命令
查看>>
浅谈ES6中的扩展运算符 (三个点...)
查看>>
iOS WKWebView添加Cookie
查看>>
swift4.2 - 距离传感器
查看>>
【BZOJ】1086: [SCOI2005]王室联邦
查看>>
更新cocoapods 时遇到问题及解决
查看>>
MySQL必知必会总结(一)
查看>>
从零开始写一个 redux(第四讲)
查看>>
构造函数和析构函数
查看>>
转 思杰南京笔试
查看>>
Apache添加到windows服务和移除Apache的windows服务
查看>>
React Native 学习笔记(二)组件生命周期函数
查看>>
前端三大框架有哪些异同呢
查看>>
java IO 包源码解析
查看>>
CSS3 线性渐变(linear-gradient)
查看>>
学术休假-银行储蓄系统
查看>>
[CodeForces - 463B] Caisa and Pylons
查看>>
Java时间和时间戳的相互转换
查看>>
Java对象序列化与反序列化
查看>>