二叉树(哈夫曼)

特点:结合有序组和链表的优点

查找

public Node find(int key) {
        Node current = root;
        while(current.iData != key) {
            if(key<current.iData)
                current = current.leftChild;
            else
                current = current.rightChild;
            if(current == null) {
                return null;
            }
        }
        return current;
    }

插入:顺着查找的思路,在返回前插入

public void insert(int id, double dd) {
        Node newNode = new Node();
        newNode.iData = id;
        newNode.dData = dd;
        if(root == null) {
            root = newNode;
        } else {
            Node current = root;
            Node parent;
            while(true) {
                parent = current;
                if(id < current.iData) {
                    current = current.leftChild;
                    if(current == null) {
                        parent.leftChild = newNode;
                        return;
                    }
                }else {
                    current = current.rightChild;
                    if(current == null) {
                        parent.rightChild = newNode;
                        return;
                    }
                }
            }
        }
    }

遍历树
中序遍历:
1.调用自身来遍历节点的左子树
2.访问自己节点
3....右子树

private void inOrder(node localRoot) {
  if(localRoot != null) {
      inOrder(localRoot.leftChild);
      System.out.println(localRoot.iData + "");
      inOrder(localRoot.rightChild);
    }
}  

前序:
1.访问自己节点
2.自身左子树
3.自身右子树
后序:自己想

最小值和最大值:最下最左左子树,最下最右右子树

删除节点
三种情况:
1.该节点是叶节点(没有子节点)
2.该节点有一个子节点
3.该节点有两个子节点

public boolean delete(int key) {
        Node current = root;
        Node parent = root;
        boolean isLeftChild = true;
        
        //和查找一样
        while(current.iData != key) {
            parent = current;
            if(key<current.iData) {
                isLeftChild = true;
                current = current.leftChild;
            }
            else {
                isLeftChild = false;
                current = current.rightChild;
            }
            if(current == null) {
                return null;
            }
        }
        
        //找到之后
        //第一种情况
        if(current.leftChild == null && current.rightChild == null) {
            if(current == root)
                root = null;
            else if(isLeftChild)
                parent.leftChild = null;
            else
                parent.rightChild = null;
        }
        //第二种情况:没有左节点或没有右节点,都要考虑被删除节点可能是根
        else if(current.rightChild == null) {
            if(current == root)
                root = current.leftChild;
            else if(isLeftChild)
                parent.leftChild = current.leftChild;
            else
                parent.rightChild = current.rightChild;
        }
        else if(current.leftChild == null) {
            if(current == root)
                root = current.rightChild;
            else if(isLeftChild)
                parent.leftChild = current.leftChild;
            else
                parent.rightChild = current.rightChild;
        }
        
        
        //第三种情况:双节点又分两种情况,第一种后继节点是delNode的右节点参考图8.19,第二种后继节点是delNode右子节点的左后代参考图8.20
        Node successor = getSuccessor(current);
        
        if(current == root) 
            root = successor;
        else if(isLeftChild)
            parent.leftChild = successor;
        else
            parent.rightChild = current.leftChild;
    }
    return true;
}

//查找后继节点,参照图8.17和8.18是两种情况
private node getSuccessor(node delNode) {
    Node SuccessorParent = delNode;
    Node successor = delNode;
    Node current = delNode.rightChild;
        //参照图8.17,38是需要删除的节点
    while(current != null) {
        SuccessorParent = successor;
        successor = current;
        current = current.leftChild;
    }
    
    //参照图8.18,假如不等于,这两句代码是实现第二种情况的树旋转
    if(successor != delNode.rightChild){
        SuccessorParent.leftChild = successor.rightChild;
        successor.rightChild = delNode.rightChild;
    }
    return successor;
}
Paste_Image.png
Paste_Image.png
Paste_Image.png

哈夫曼
专用于压缩文本

Paste_Image.png
Paste_Image.png
Paste_Image.png

重点解释:用10表示S,用00表示空格后,不能再用01和11,因为它们是其它字符的前缀,不够就用三位来组合:000,001,010,011,100,110,111. A是010,I是110,因为除去10和00开始的组合,在用四位表示其它字符,依此类推

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

推荐阅读更多精彩内容