二叉树学习

二叉树

每个节点最多有两个叶子节点

二叉树的优势

在实际使用时会根据链表和有序数组等数据结构的不同优势进行选择。有序数组的优势在于二分查找,链表的优势在于数据项的插入和数据项的删除。但是在有序数组中插入数据就会很慢,同样在链表中查找数据项效率就会很低。综合以上情况,二叉树可以利用链表和有序数组的优势,同时合并有序数组和链表的优势,二叉树也是一种常用的数据结构

二叉树

二叉树的构成

红色是根节点(root),蓝色是子节点也是父节点,绿色是子节点。其余的是线是边。节点和链表中节点一样都可以存放数据信息。树中的边可以用自引用表示,这种引用就是C/C++里面的指针。通常来说树就是顶部小,底部大,且树呈分层结构。root节点时第0层,以此类推,二叉树最多有两个节点

二叉树搜素

二叉树一个节点左子节点的关键字小于这个节点,右子节点的关键字大于或等于这个父节点。

创建一个树节点

创建一个树节点包括左节点引用和右节点引用

    // 创建一个树的节点
    // 每个node存放两个数据
    // 一个左node引用和一个右node引用
    class Node {
        public int iData;
        public double dData;
        public Node leftNode;
        public Node rightNode;

        // 显示树节点信息
        public void showNode() {
            System.out.println("{ " + iData + "," + dData + " }");
        }
    }

创建一个树结构

创建一个树结构,首先是向一个树中插入树节点。当一棵树为null时,数据项时从树的root节点处开始插入,之后的插入顺序是根据搜素节点顺序规则进行插入。具体规则是:如果数据项比父节点的数据项要小,则插在父节点的左节点(leftNode),如果比父节点的数据项要大,则将新的node插入在父节点右节点处(rightNode)

    private Node root;

    // 插入Node
    // 插入之前需要判断是否为null
    // 为null需要比较大小直到currentNode为null就插入
    public void insert(int iData, double dData) {
        // 创建node节点
        Node newNode = new Node();
        newNode.iData = iData;
        newNode.dData = dData;
        // 判断root node是否为null
        if (root == null) {
            root = newNode;
        } else {
            Node current = root;
            Node parent;
            while (true) {
                // 保存当current变为null之前的那一个父节点
                parent = current;
                if (iData < current.iData) {
                    // 插入左节点
                    current = current.leftNode;
                    // 不断向左node寻找是否为null
                    if (current == null) {
                        parent.leftNode = newNode;
                        return;
                    }
                } else {
                    // 插入右节点
                    current = current.rightNode;
                    if (current == null) {
                        parent.rightNode = newNode;
                        return;
                    }
                }
            }
        }
    }

插入节点过程图

插入节点流程图

在插入节点的过程中其实也是对tree遍历的过程,最终根据条件遍历左右节点为null时进行添加新的节点

查找关键字

查找关键字是树结构的一项重要操作项,在有序数组中通过二分排序效率非常高。在二叉树中的查找效率也比较高。因为二叉树的添加node的过程就是根据数据项的大小进行有序添加的,并不是毫无秩序的插入数据项。在有序的基础上进行查找关键字的效率就会快很多

    // 在tree中寻找关键字
    // 返回一个Node
    // 显示这个Node
    public Node find(int key) {
        Node current = root;
        while (current.iData != key) {
            if (current.iData > key) {
                current = current.leftNode;
            } else {
                current = current.rightNode;
            }
            if (current == null)
                return null;
        }
        return current;
    }

树的最值查找

树的最值查找在树中查找是比较容易的,因为从root开始查找,最小值只会出现所有父节点的左节点处,同样最大值只会出现在所有父节点的沿着最右节点搜素的最底层右节点处

    // 查找树中的最大值和最小值
    // 最小值存在于一棵树的最下层的最左node
    // 最大值存在于一棵树的最下层的最右node
    public Node[] mVal() {
        Node minNode = null;
        Node maxNode = null;
        Node[] maxminVal = new Node[2];
        Node current = root;//从树的顶部开始搜索
        while (current != null) {
            minNode = current;
            current = current.leftNode;
        }
        maxminVal[0] = minNode;
        current = root;
        while (current != null) {
            maxNode = current;
            current = current.rightNode;
        }
        maxminVal[1] = maxNode;
        return maxminVal;
    }

以上是通过node数组存放两个最值的方法

测试及结果

public static void main(String[] args) {
        NodeTest tree = new NodeTest();
        tree.insert(3, 3.333);
        tree.insert(1, 1.111);
        tree.insert(2, 2.222);
        tree.insert(4, 4.444);
        tree.insert(5, 5.555);
        tree.insert(6, 6.666);
        Node node = tree.find(3);
        if (node == null) {
            System.out.println("we can not find it");
        } else {
            node.showNode();
        }
        //查找tree中的最值
        Node[] temp = tree.mVal();
        temp[0].showNode();
        temp[1].showNode();
    }
{ 3,3.333 }
{ 1,1.111 }
{ 6,6.666 }

由于第一个插入节点就是在root节点处进行插入不管其数据项大小,该节点都是root节点,处于树的最高层

github源码整理

github.com/it-wwh/myTest/blob/master/src/com/wanghonghui/java/node/NodeTest.java

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

推荐阅读更多精彩内容