二叉树知识点

简介/定义

  二叉树作为常用的数据结构之一,其特性再计算机领域被广泛应用,balabala...(自行查找)
  偷个低清无码的图给各位看看:
二叉树基本形态

二叉树存储结构

  常见的二叉树存储可以是顺序存储,也可以是链表存储。

相关术语

  树的结点:包含一个数据元素及若干指向子树的分支;
  孩子结点:结点的子树的根称为该结点的孩子;
  双亲结点:B 结点是A 结点的孩子,则A结点是B 结点的双亲;
  兄弟结点:同一双亲的孩子结点; 堂兄结点:同一层上结点;
  祖先结点: 从根到该结点的所经分支上的所有结点子孙结点:以某结点为根的子树中任一结点都称为该结点的子孙;
  结点层:根结点的层定义为1;根的孩子为第二层结点,依此类推;
  树的深度:树中最大的结点层;
  结点的度:结点子树的个数;
  树的度: 树中最大的结点度;
叶子结点:也叫终端结点,是度为 0 的结点;(重点)
  分枝结点:度不为0的结点;
  有序树:子树有序的树,如:家族树;
  无序树:不考虑子树的顺序;

划重点

  如果想要对二叉树有深入的理解,除了它的基本性质必须要了解,最重要的是要对递归有深入的了解,二叉树是递归定义的。
  二叉树有以下三种类型:
    (1)完全二叉树 -- 【若设二叉树的高度为h,除第 h层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h层有叶子结点,并且叶子结点都是从左到右依次排布,这就是完全二叉树。】
    (2)满二叉树 -- 【除了叶结点外每一个结点都有左右子叶且叶子结点都处在最底层的二叉树。】
    (3)平衡二叉树 -- 【平衡二叉树又被称为AVL树(区别于AVL算法),它是一棵二叉排序树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。】
  在二叉树的基础上,或者修改或者增加不同的规则形成了各种各样的树,树形结构在开发中运用的相当广泛理解树的基本概念有助于理解很多原理,例如数据库的索引原理等,所以树的概念必须要清楚。

废话不多说,上代码:

**
 * 
 * 类名称:Node.java <br>
 * 内容摘要: //节点。<br>
 * 修改备注: <br>
 * 创建时间: 2018年5月8日下午2:30:30<br>
 * 
 * @author Snoopy.Li<br>
 */
public class Node {
    // 左节点
    private Node left;
    // 右节点
    private Node right;
    // 内容
    private int data;

    public Node(int data) {
        this.data = data;
    }

    public Node getLeft() {
        return left;
    }

    public void setLeft(Node left) {
        this.left = left;
    }

    public Node getRight() {
        return right;
    }

    public void setRight(Node right) {
        this.right = right;
    }

    public int getData() {
        return data;
    }

    public void setData(int data) {
        this.data = data;
    }

}
import java.util.Stack;

/**
 * 
 * 类名称:BinaryTree.java <br>
 * 内容摘要: //二叉树。<br>
 * 修改备注: <br>
 * 创建时间: 2018年5月8日上午10:25:58<br>
 * 
 * @author Snoopy.Li<br>
 */
public class BinaryTree {

    // 根节点
    private Node root;

    public Node getRoot() {
        return root;
    }

    public void setRoot(Node root) {
        this.root = root;
    }

    /**
     * 递归构造二叉树
     * 
     * @param node
     * @param data
     */
    public void buildTree(Node node, int data) {
        if (root == null) {
            // 根节点下面没有子节点,即根节点为叶子节点
            root = new Node(data);
        } else {
            if (data < node.getData()) {
                // 比父节点小的放到左边
                if (node.getLeft() == null) {
                    // 父节点为叶子节点
                    node.setLeft(new Node(data));
                } else {
                    // 父节点非叶子节点
                    buildTree(node.getLeft(), data);
                }
            } else {
                // 比父节点大放到右边
                if (node.getRight() == null) {
                    // 父节点为叶子节点
                    node.setRight(new Node(data));
                } else {
                    // 父节点为非叶子节点
                    buildTree(node.getRight(), data);
                }
            }
        }
    }

    /**
     * 递归 先序遍历二叉树<br>
     * 直接访问p指向的节点,然后访问该节点的左子树,最后访问节点的右子树。
     * 
     * @param node
     */
    public void preShow(Node node) {
        if (node != null) {
            System.out.print(node.getData() + "  ");
            preShow(node.getLeft());
            preShow(node.getRight());
        }
    }

    /**
     * 非递归先序遍历二叉树
     */
    public void preShow() {
        Stack<Node> stack = new Stack<>();
        Node node = root;
        while ((node != null) || stack.empty() != true) {
            if (node != null) {
                // 打印根节点
                System.out.print(node.getData() + "  ");
                // 将根节点压栈
                stack.push(node);
                node = node.getLeft();
            } else {
                // 当该节点为叶子节点时,弹栈
                node = stack.pop();
                node = node.getRight();
            }
        }

    }

    /**
     * 递归 中序遍历二叉树<br>
     * 先遍历节点的左子树,遍历完毕之后访问此节点,之后访问节点的右子树
     * 
     * @param node
     */
    public void inorderShow(Node node) {
        if (node != null) {
            inorderShow(node.getLeft());
            System.out.print(node.getData() + "  ");
            inorderShow(node.getRight());
        }
    }

    /**
     * 非递归中序遍历二叉树
     */
    public void inorderShow() {
        Stack<Node> stack = new Stack<>();
        Node node = root;
        while (true) {
            // 左子树压栈
            while (node != null) {
                stack.push(node);
                node = node.getLeft();
            }
            if (stack.empty() == true) {
                return;
            }
            node = stack.pop();
            System.out.print(node.getData() + "  ");
            // 右子树压栈
            node = node.getRight();
        }
    }

    /**
     * 递归 后序遍历二叉树<br>
     * 先遍历节点的左子树,然后遍历节点的右子树,最后遍历该节点
     * 
     * @param node
     */
    public void posShow(Node node) {
        if (node != null) {
            posShow(node.getLeft());
            posShow(node.getRight());
            System.out.print(node.getData() + "  ");
        }
    }

    /**
     * 非递归后序遍历二叉树
     */
    public void posShow() {
        Stack<Node> stack = new Stack<>();
        // 构造一个中间栈来存储逆后续遍历的结果
        Stack<Node> output = new Stack<Node>();
        Node node = root;
        while (node != null || stack.size() > 0) {
            if (node != null) {
                output.push(node);
                stack.push(node);
                node = node.getRight();
            } else {
                node = stack.pop();
                node = node.getLeft();
            }
        }
        while (output.size() > 0) {
            System.out.print(output.pop().getData() + "  ");
        }
    }

    public static void main(String[] args) {

        BinaryTree binaryTree = new BinaryTree();
        int[] sample = { 9, 5, 10, 25, 3, 4, 6, 1, 40, 29 };
        for (int i = 0; i < sample.length; i++) {
            binaryTree.buildTree(binaryTree.getRoot(), sample[i]);
        }
        System.out.print("递归先序遍历:[  ");
        binaryTree.preShow(binaryTree.getRoot());
        System.out.println("]");
        System.out.print("非递归先序遍历:[  ");
        binaryTree.preShow();
        System.out.println("]");

        System.out.print("递归中序遍历:[  ");
        binaryTree.inorderShow(binaryTree.getRoot());
        System.out.println("]");
        System.out.print("非递归中序遍历:[  ");
        binaryTree.inorderShow();
        System.out.println("]");

        System.out.print("递归后序遍历:[  ");
        binaryTree.posShow(binaryTree.getRoot());
        System.out.println("]");
        System.out.print("非递归后序遍历:[  ");
        binaryTree.posShow();
        System.out.println("]");
    }

}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容

  • 二叉树 二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(...
    n油炸小朋友阅读 769评论 0 1
  • 数据结构与算法--从平衡二叉树(AVL)到红黑树 上节学习了二叉查找树。算法的性能取决于树的形状,而树的形状取决于...
    sunhaiyu阅读 7,638评论 4 32
  • 前言 树是数据结构中的重中之重,尤其以各类二叉树为学习的难点。一直以来,对于树的掌握都是模棱两可的状态,现在希望通...
    MrHorse1992阅读 353,372评论 51 536
  • 数据结构和算法--二叉树的实现 几种二叉树 1、二叉树 和普通的树相比,二叉树有如下特点: 每个结点最多只有两棵子...
    sunhaiyu阅读 6,426评论 0 14
  • 四、树与二叉树 1. 二叉树的顺序存储结构 二叉树的顺序存储就是用数组存储二叉树。二叉树的每个结点在顺序存储中都有...
    MinoyJet阅读 1,499评论 0 7