数据结构——二叉树

1.二分查找和判定树:

二分查找过程可用二叉树来描述:把当前查找区间的中间位置上的结点作为根,左子表和右子表中的结点分别作为根的左子树和右子树。由此得到的二叉树,称为描述二分查找的判定树(Decision Tree)或比较树(Comparison Tree)。时间复杂度为O(logN)。

java实现代码:


    public static int commonBinarySearch(int[] arr,int key){
        int low = 0;
        int high = arr.length - 1;
        int middle = 0;         //定义middle
        
        if(key < arr[low] || key > arr[high] || low > high){
            return -1;              
        }
        
        while(low <= high){
            middle = (low + high) / 2;
            if(arr[middle] > key){
                //比关键字大则关键字在左区域
                high = middle - 1;
            }else if(arr[middle] < key){
                //比关键字小则关键字在右区域
                low = middle + 1;
            }else{
                return middle;
            }
        }
        
        return -1;      //最后仍然没有找到,则返回-1
    }

2.二叉树

2.1 特殊的二叉树

  • 1.斜树:所有的结点都只有左子树(左斜树),或者只有右子树(右斜树)。
  • 2.满二叉树:所有的分支结点都存在左子树和右子树,并且所有的叶子结点都在同一层上,这样就是满二叉树
  • 3.完全二叉树:对一棵具有n个结点的二叉树按层序排号,如果编号为i的结点与同样深度的满二叉树编号为i结点在二叉树中位置完全相同,就是完全二叉树。
    特点:
    (1)叶子结点只能出现在最下一层(满二叉树继承而来)
    (2)最下层叶子结点一定集中在左 部连续位置。
    (2)倒数第二层,如有叶子节点,一定出现在右部连续位置。
    (4)同样结点树的二叉树,完全二叉树的深度最小(满二叉树也是对的)。
    image.png

2.2普通二叉树的性质

重点:对于任何一棵非空的二叉树,如果叶节点个数为n0,度数为2的节点个数为n2,则有: n0 = n2 + 1

2.3 二叉树遍历

二叉树的核心是把二维结构变成一维序列。

  • 前序遍历基本思想:
    1.先访问根结点
    2.再先序遍历左子树
    3.最后再先序遍历右子树
image.png

如上图:前序遍历的结果是:12457836

java实现的方式:

// 前序遍历的递归实现
    public void preOrderTraverse(TreeNode node) {
        if (node == null)
            return;
        // 先根节点
        System.out.println(node.val);
        // 再左孩子
        preOrderTraverse(node.left);
        // 后右孩子
        preOrderTraverse(node.right);
    }
  • 中序遍历
    1.先中序遍历左子树
    2.然后再访问根结点
    3.最后再中序遍历右子树


    image.png
// 中序遍历的递归实现
    public void midOrderTraverse(TreeNode node) {
        if (node == null)
            return;
        // 先左孩子
        midOrderTraverse(node.left);
        // 再根节点
        System.out.println(node.val);
        // 后右孩子
        midOrderTraverse(node.right);
    }
  • 后序遍历
    1.先后序遍历左子树
    2.然后再后序遍历右子树
    3.最后再访问根结点


    image.png
// 后序遍历的递归实现
    public void endOrderTraverse(TreeNode node) {
        if (node == null)
            return;
        // 先左孩子
        endOrderTraverse(node.left);
        // 再右孩子
        endOrderTraverse(node.right);
       // 后根节点
        System.out.println(node.val);
    }

2.3 平衡二叉树(AVL树)

2.3.1 定义

平衡二叉树(AVL树)是一种二叉排序树,其中每个结点的左子树和右子树的高度差至多等于1

2.3.2 二叉树平衡树插入。

插入分为四种情况:
(1) 在结点X的左孩子结点的左子树中插入元素


图片.png

(2)在结点X的左孩子结点的右子树中插入元素


图片.png

(3)在结点X的右孩子结点的左子树中插入元素


图片.png

(4) 在结点X的右孩子结点的右子树中插入元素


图片.png

参考文档:java数据结构与算法之平衡二叉树(AVL树)的设计与实现

3.Huffman树(最优二叉树)

3.2 Huffman树的定义:

Huffman树是一种特殊结构的二叉树,由Huffman树设计的二进制前缀编码。
要介绍Huffman树,首先我们需要知道什么是树的带权路径长度,它指的是所有叶子节点的带权路径长度之和

有了如上的概念,对于Huffman树,其定义为:

给定n权值作为n个叶子节点,构造一棵二叉树,若这棵二叉树的带权路径长度达到最小,则称这样的二叉树为最优二叉树,也称为Huffman树。

3.2 Huffman树的构造:

假设有n个权值,则构造出的哈夫曼树有n个叶子结点。 n个权值分别设为 w1、w2、…、wn,哈夫曼树的构造规则为:

  1. 将w1、w2、…,wn看成是有n 棵树的森林(每棵树仅有一个结点);
  2. 在森林中选出根结点的权值最小的两棵树进行合并,作为一棵新树的左、右子树,且新树的根结点权值为其左、右子树根结点权值之和;
  3. 从森林中删除选取的两棵树,并将新树加入森林;
  4. 重复(02)、(03)步,直到森林中只剩一棵树为止,该树即为所求得的哈夫曼树。

3.3 Huffman树Java实现:

public Huffman(int a[]) {
    HuffmanNode parent = null;
    MinHeap heap;

    // 建立数组a对应的最小堆
    heap = new MinHeap(a);

    for(int i=0; i<a.length-1; i++) {   
        HuffmanNode left = heap.dumpFromMinimum();  // 最小节点是左孩子
        HuffmanNode right = heap.dumpFromMinimum(); // 其次才是右孩子

        // 新建parent节点,左右孩子分别是left/right;
        // parent的大小是左右孩子之和
        parent = new HuffmanNode(left.key+right.key, left, right, null);
        left.parent = parent;
        right.parent = parent;

        // 将parent节点数据拷贝到"最小堆"中
        heap.insert(parent);
    }

    mRoot = parent;

    // 销毁最小堆
    heap.destroy();
}

首先创建最小堆,然后进入for循环。
每次循环时:
(1) 首先,将最小堆中的最小节点拷贝一份并赋值给left,然后重塑最小堆(将最小节点和后面的节点交换位置,接着将"交换位置后的最小节点"之前的全部元素重新构造成最小堆);
(2) 接着,再将最小堆中的最小节点拷贝一份并将其赋值right,然后再次重塑最小堆;
(3) 然后,新建节点parent,并将它作为left和right的父节点;
(4) 接着,将parent的数据复制给最小堆中的指定节点。

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

推荐阅读更多精彩内容

  • 转载请标明出处,谢谢!https://www.jianshu.com/p/de829eab944c 关联文章冒泡、...
    若无初见阅读 2,023评论 0 3
  • 关于树的定义和存储结构可以查看上一篇文章树的定义和树的三种存储结构 一、二叉树的定义 二叉树的定义 二叉树(Bin...
    NotFunGuy阅读 1,880评论 5 25
  • 树,是一种在实际编程中经常遇到的数据结构。它的逻辑很简单,除根节点之外,每个节点只有一个父节点,根节点没有父节点。...
    doudo阅读 711评论 0 0
  • 定义 一个有穷的结点集合,可以为空。若不为空,则它是由根结点和称为其左子树和右子树的两个互不相交的二叉树组成。 二...
    IAM四十二阅读 2,489评论 0 2
  • 照片会慢慢褪色 记忆却依旧清晰 问我还哀伤什么 也只是 不再有一个笑颜 我依赖这笑颜 在每一个星星的夜晚 每一阵微...
    何四金mile阅读 151评论 0 1