`
leon_a
  • 浏览: 79025 次
  • 性别: Icon_minigender_1
  • 来自: 拜月神教
社区版块
存档分类
最新评论

2-3 tree

 
阅读更多

package com.leon.cc;

import com.leon.util.Stack;

/**
 * @author : Leon
 * @since : 2013-10-9
 * @see :
 */

public class Tree {
    
    Node root = new Node();
    
    public void insert(String str) {
        Node node = search_node(root, str);
        node.insert(str);
        while (need_split(node)) {
            if (node == root) {
                node = node.split();
                root = node;
            }
            else {
                node = node.split();
            }
        }
    }
    
    public void delete(String str) {
        Node node = contain(str);
        Node leaf = null;
        if (!node.is_leaf()) {
            leaf = tree_successor(node, str);
            int index = node.index_item(str);
            String temp = node.values[index];
            node.values[index] = leaf.values[0];
            leaf.values[0] = temp;
        }
        else {
            leaf = node;
        }
        leaf.delete(str);
        if (leaf.item_size == 0) {
            fix(leaf);
        }
    }
    
    private void fix(Node n) {
        if (n.parent == null) {
            root = n.disConnect(0);
        }
        else {
            Node p = n.parent;
            int[] ary = new int[3];
            int index = p.index_child(n);
            if (has_2item_sibling(n, ary)) {
                if (p.item_size == 2) {
                    if (index == 0) {
                        if (ary[1] == 2) {
                            leftRotate(0, n);
                        }
                        else {
                            leftRotate(0, n);
                            leftRotate(1, n.parent.childs[1]);
                        }
                    }
                    else if (index == 1) {
                        if (ary[2] == 2) {
                            leftRotate(1, n);
                        }
                        else {
                            rightRotate(1, n);
                        }
                    }
                    else {
                        if (ary[1] == 2) {
                            rightRotate(2, n);
                        }
                        else {
                            rightRotate(2, n);
                            rightRotate(1, n.parent.childs[1]);
                        }
                    }
                }
                else {
                    if (index == 0) {
                        leftRotate(0, n);
                    }
                    else {
                        rightRotate(1, n);
                    }
                }
            }
            else {
                if (p.item_size == 2) {
                    if (index == 0) {
                        mergeRight(0, n);
                    }
                    else if (index == 1) {
                        mergeLeft(1, n);
                    }
                    else {
                        mergeLeft(2, n);
                    }
                }
                else {
                    if (index == 0) {
                        mergeRight(0, n);
                    }
                    else {
                        mergeLeft(1, n);
                    }
                    fix(p);
                }
            }
        }
    }
    
    private void mergeLeft(int i, Node n) {
        Node child = null;
        Node p = n.parent;
        if (!n.is_leaf()) {
            child = n.childs[0];
            n.delete_child(0);
        }
        p.delete_child(i);
        if (i == 1) {
            p.childs[0].insert(p.values[0]);
            p.delete(p.values[0]);
            if (child != null) {
                p.childs[0].insert_child(2, child);
            }
        }
        else {
            int sibling_size = p.item_size;
            p.childs[1].insert(p.values[sibling_size - 1]);
            p.delete(p.values[sibling_size - 1]);
            if (child != null) {
                p.childs[1].insert_child(2, child);
            }
        }
    }
    
    private void mergeRight(int i, Node n) {
        Node child = null;
        Node p = n.parent;
        if (!n.is_leaf()) {
            child = n.childs[0];
            n.delete_child(0);
        }
        p.delete_child(0);
        p.childs[0].insert(p.values[0]);
        p.delete(p.values[0]);
        if (child != null) {
            p.childs[0].insert_child(0, child);
        }
    }
    
    private boolean has_2item_sibling(Node n, int[] ary) {
        Node p = n.parent;
        ary[0] = p.childs[0].item_size;
        ary[1] = p.childs[1].item_size;
        if (p.item_size == 2) {
            ary[2] = p.childs[2].item_size;
        }
        for (int i = 0; i < ary.length; i++) {
            if (ary[i] == 2) {
                return true;
            }
        }
        return false;
    }
    
    private void leftRotate(int index, Node n) {
        if (index == 0) {
            n.insert(n.parent.values[0]);
            n.parent.delete(n.parent.values[0]);
            n.parent.insert(n.parent.childs[1].values[0]);
            n.parent.childs[1].delete(n.parent.childs[1].values[0]);
            if (!n.is_leaf()) {
                Node node = n.parent.childs[1].delete_child(0);
                n.insert_child(1, node);
            }
        }
        else {
            n.insert(n.parent.values[1]);
            n.parent.delete(n.parent.values[1]);
            n.parent.insert(n.parent.childs[2].values[0]);
            n.parent.childs[2].delete(n.parent.childs[2].values[0]);
            if (!n.is_leaf()) {
                Node node = n.parent.childs[2].delete_child(0);
                n.insert_child(1, node);
            }
        }
        
    }
    
    private void rightRotate(int index, Node n) {
        if (index == 2) {
            n.insert(n.parent.values[1]);
            n.parent.delete(n.parent.values[1]);
            int sibling_size = n.parent.childs[1].item_size;
            n.parent.insert(n.parent.childs[1].values[sibling_size - 1]);
            n.parent.childs[1].delete(n.parent.childs[1].values[sibling_size - 1]);
            if (!n.is_leaf()) {
                Node node = n.parent.childs[1].delete_child(sibling_size);
                n.insert_child(0, node);
            }
        }
        else {
            n.insert(n.parent.values[0]);
            n.parent.delete(n.parent.values[0]);
            int sibling_size = n.parent.childs[0].item_size;
            n.parent.insert(n.parent.childs[0].values[sibling_size - 1]);
            n.parent.childs[0].delete(n.parent.childs[0].values[sibling_size - 1]);
            if (!n.is_leaf()) {
                Node node = n.parent.childs[0].delete_child(sibling_size);
                n.insert_child(0, node);
            }
        }
    }
    
    public Node tree_successor(Node node, String str) {
        if (!node.is_leaf()) {
            int index = node.index_item(str);
            Node child = node.childs[index + 1];
            return tree_mins(child);
        }
        return node;
    }
    
    private Node tree_mins(Node child) {
        Node temp = child;
        while (!temp.is_leaf()) {
            temp = temp.childs[0];
        }
        return temp;
    }
    
    public Node contain(String str) {
        Node current = root;
        while (!current.contain(str)) {
            if (current.item_size == 2) {
                String small = current.values[0];
                String large = current.values[1];
                if (str.compareTo(small) < 0) {
                    current = current.childs[0];
                }
                else if (str.compareTo(small) >= 0 && str.compareTo(large) <= 0) {
                    current = current.childs[1];
                }
                else {
                    current = current.childs[2];
                }
            }
            else {
                String small = current.values[0];
                if (str.compareTo(small) < 0) {
                    current = current.childs[0];
                }
                else {
                    current = current.childs[1];
                }
            }
        }
        return current;
    }
    
    public boolean need_split(Node node) {
        return node.item_size > 2 ? true : false;
    }
    
    public Node search_node(Node node, String str) {
        if (is_leaf(node)) {
            return node;
        }
        else {
            if (node.item_size == 2) {
                String small = node.values[0];
                String large = node.values[1];
                if (str.compareTo(small) < 0) {
                    Node next = create_node(node, 0);
                    return search_node(next, str);
                }
                else if (str.compareTo(small) >= 0 && str.compareTo(large) <= 0) {
                    Node next = create_node(node, 1);
                    return search_node(next, str);
                }
                else {
                    Node next = create_node(node, 2);
                    return search_node(next, str);
                }
            }
            else {
                String small = node.values[0];
                if (str.compareTo(small) < 0) {
                    Node next = create_node(node, 0);
                    return search_node(next, str);
                }
                else {
                    Node next = create_node(node, 1);
                    return search_node(next, str);
                }
            }
        }
    }
    
    private Node create_node(Node node, int i) {
        Node child = node.childs[i];
        if (child == null) {
            child = new Node();
            node.childs[i] = child;
            child.parent = node;
        }
        return child;
    }
    
    public boolean is_leaf(Node node) {
        return node.childs[0] == null;
    }
    
    public static void main(String[] args) {
        Tree t = new Tree();
        String[] str = new String[] { "horse", "cow", "pig", "seal", "rat", "dog", "goat", "elephant", "fish",
                "rooster", "zebra", "roach", "cat", "hen", "llama", "aardvark", "hog", "donkey", "rhino", "hippo",
                "tiger", "lamb", "lion", "leopard", "lynx", "kitty", "ant", "ape", "animal" };
        for (int i = 0; i < str.length; i++) {
            t.insert(str[i]);
        }
        
        t.delete("animal");
        t.delete("aardvark");
        t.delete("cat");
        t.delete("ape");
        t.delete("donkey");
        t.delete("ant");
        t.delete("hog");
        t.delete("hen");
        t.delete("fish");
        t.delete("goat");
        t.delete("hippo");
        t.delete("kitty");
        t.delete("cow");
        t.delete("dog");
        t.delete("elephant");
        t.delete("tiger");
        t.delete("zebra");
        t.delete("horse");
        t.delete("rat");
        t.delete("rhino");
        t.delete("pig");
        t.delete("seal");
        t.delete("lynx");
        t.delete("roach");
        t.delete("lion");
        t.delete("llama");
        t.delete("lamb");
        t.delete("rooster");
        t.delete("leopard");
        String rs = t.toString();
        System.out.println(rs);
    }
    
    public String toString() {
        if (root == null) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        sb.append("digraph g {\n");
        sb.append("\tnode[shape = record, width = .1, height = .1];\n");
        Stack<Node> stack = new Stack<Node>();
        int k = 0;
        Stack<Integer> k_stack = new Stack<Integer>();
        stack.push(root);
        k_stack.push(k);
        sb.append("\tnode" + k + "[label = \"{<n> " + root.getName() + " }\", color = lightgray, style = filled];\n");
        while (!stack.is_empty()) {
            Node parent = stack.pop();
            String parentNode = "node" + k_stack.pop();
            for (int i = 0; i < parent.childs.length; i++) {
                if (parent.childs[i] != null) {
                    String childNode = "node" + (++k);
                    sb.append("\t" + childNode + "[label = \"{<n> " + parent.childs[i].getName()
                              + " }\", color = lightgray, style = filled];\n");
                    sb.append("\t" + parentNode + ":n->" + childNode + ":n;\n");
                    stack.push(parent.childs[i]);
                    k_stack.push(k);
                }
            }
        }
        sb.append("}\n");
        return sb.toString();
    }
}

class Node {
    
    String[] values = new String[3];
    int      item_size;
    Node[]   childs = new Node[4];
    Node     parent;
    
    public Node(String str) {
        values[0] = str;
        item_size++;
    }
    
    public String getName() {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < item_size; i++) {
            sb.append(values[i] + " ");
        }
        return sb.toString();
    }
    
    public Node() {
    }
    
    public boolean contain(String str) {
        for (int i = 0; i < item_size; i++) {
            if (values[i].equals(str)) {
                return true;
            }
        }
        return false;
    }
    
    public int insert(String str) {
        int pos = item_size;
        for (int i = item_size - 1; i >= 0; i--) {
            if (values[i].compareTo(str) > 0) {
                values[i + 1] = values[i];
                pos = i;
            }
        }
        values[pos] = str;
        item_size++;
        return pos;
    }
    
    public void delete(String str) {
        int index = index_item(str);
        for (int i = index; i < item_size; i++) {
            values[i] = values[i + 1];
        }
        item_size--;
    }
    
    public void insert_child(int index, Node node) {
        for (int i = childs.length - 2; i >= index; i--) {
            childs[i + 1] = childs[i];
        }
        childs[index] = node;
        childs[index].parent = this;
    }
    
    public Node delete_child(int index) {
        Node node = childs[index];
        for (int i = index; i < childs.length - 1; i++) {
            childs[i] = childs[i + 1];
        }
        node.parent = null;
        return node;
    }
    
    public boolean is_leaf() {
        return childs[0] == null;
    }
    
    public int index_child(Node node) {
        for (int i = 0; i < childs.length; i++) {
            if (childs[i].equals(node)) {
                return i;
            }
        }
        return -1;
    }
    
    public int index_item(String str) {
        for (int i = 0; i < item_size; i++) {
            if (values[i].equals(str)) {
                return i;
            }
        }
        return -1;
    }
    
    public Node disConnect(int index) {
        Node result = childs[index];
        if (result != null) result.parent = null;
        childs[index] = null;
        return result;
    }
    
    public void connect(int index, Node child) {
        childs[index] = child;
        if (child != null) child.parent = this;
    }
    
    public Node split() {
        Node left = this;
        String middle = values[1];
        Node right = new Node(values[2]);
        left.values[1] = null;
        left.values[2] = null;
        left.item_size = 1;
        if (parent == null) {
            parent = new Node(middle);
            parent.connect(0, left);
            parent.connect(1, right);
        }
        else {
            int index = parent.insert(middle);
            parent.insert_child(index + 1, right);
        }
        
        if (!is_leaf()) {
            Node child1 = disConnect(2);
            Node child2 = disConnect(3);
            right.connect(0, child1);
            right.connect(1, child2);
        }
        return parent;
    }
}

分享到:
评论

相关推荐

    el-tree-selected-tree

    2. `package-lock.json`和`package.json`:它们管理项目依赖,包括Element UI和其他可能的npm包。 3. `README.md`:这是一个项目说明文件,可能包含了如何运行和使用此功能的指南。 4. `src`目录:存放项目的源代码...

    vakata-jstree-651d32c.zip

    3. `demo` 或 `examples` 目录:包含了一些示例页面,展示了jstree的不同用法和功能,有助于快速理解和学习如何使用该库。 4. `docs` 目录:可能包含文档或API参考,帮助开发者了解每个方法、属性和事件的详细信息...

    device-tree-xlnx-master_tree_devicetree2018.3_

    `device-tree-xlnx-master_tree_devicetree2018.3_`这个标题表明这是一个关于Xilinx设备树的源码库,针对2018.3版本。Xilinx是一家知名的FPGA(现场可编程门阵列)制造商,其设备树源码通常与他们的硬件平台相关,...

    i-Tree最新版2019年中文操作手册

    2. i-Tree Streets:此工具专注于生态服务及城市行道树的群体结构,使用样本或普查数据量化每棵树的年度环境与美学效益,并将其以美元价值计算,这些效益包括节能、改善空气质量、减少二氧化碳、雨水控制以及房地价...

    2-4 tree 的java 实现

    在IT领域,2-4树是一种特殊的自平衡二叉查找树(B-tree),它具有2个到4个孩子节点的特点。这种数据结构主要用于高效的数据库和文件系统中,以支持快速的插入、删除和查找操作。2-4树是B树的一个变种,它在节点分裂...

    cpp-kdtree一个简单的C语言库用于处理KDTrees

    3. **插入和删除**:库可能允许用户向已存在的KDTree中添加新的点,或从树中移除特定的点,同时保持树的结构尽可能平衡。 4. **优化**:cpp-kdtree可能采用了某些优化策略,如剪枝,以减少不必要的计算,提高查询...

    RED-BLACK-tree-and-2-3-4tree.rar_234树到红黑树_红黑树

    2-3-4树是另一种自平衡数据结构,它将2-3树和4-3-4树的概念结合起来。2-3-4树可以看作是一棵内部节点可以有2、3或4个子节点的树,每个节点最多可以存储3个键。这种树同样保证了查找、插入和删除操作的时间复杂度为O...

    device-tree-compiler_1.4.7-3ubuntu2_amd64.deb

    下载后ubuntu 终端安装命令:dpkg -i device-tree-compiler_1.4.7-3ubuntu2_amd64.deb 直接安装,外网下载太慢上传备用

    2-3-tree-master.zip_2-3树建立

    通过分析"2-3-tree-master.zip"的代码,我们可以深入理解2-3树的各种操作的实现细节,例如节点的创建、插入、删除和查找方法,以及树的平衡调整策略。这些实现可以帮助我们更好地应用和优化这种数据结构。

    前端开源库-parse5-htmlparser2-tree-adapter

    在`parse5-master`这个压缩包中,很可能包含了parse5库的源码和相关资源,你可以通过阅读源码、查看示例和文档来更深入地理解这个库的工作原理,以及如何有效地使用`parse5-htmlparser2-tree-adapter`。同时,熟悉这...

    v-org-tree.zip

    3. **package.json**:这个文件包含了项目的依赖管理信息,包括`v-org-tree`组件的版本以及其他必要的库,如Babel的相关插件和polyfills。开发者可能在`dependencies`或`devDependencies`字段中列出了这些依赖。 4....

    device-tree-xlnx-xilinx-v2018.3

    《Xilinx嵌入式系统设备树详解——基于device-tree-xlnx-xilinx-v2018.3》 在嵌入式系统开发中,设备树(Device Tree)扮演着至关重要的角色,它是一种用于描述硬件配置的数据结构,使得操作系统内核能够更灵活地...

    vuejstree是一个用于Vue20的树形插件

    **Vue.js与Tree组件** Vue.js,由尤雨溪创建,是一种轻量级的前端JavaScript框架,以其简单易用、高效灵活的特点深受开发者喜爱。它采用声明式编程,允许开发者通过模板语法来定义UI,实现了数据和视图的双向绑定,...

    vue el-tree 默认展开第一个节点的实现代码

    2. el-tree组件:el-tree是Element UI中的一个组件,用于展示树形结构数据。它可以帮助开发者以树形的方式展示和管理具有层级关系的数据,例如文件夹结构、组织架构等。 3. 默认展开节点功能:在树形控件el-tree中...

    2-3-tree:2-3树数据结构的简单演示

    在给定的压缩包文件"2-3-tree-master"中,很可能包含了C++实现2-3树的源代码。这个代码库可能包括了节点类的定义、插入、查找和删除等操作的实现,以及相关的测试用例,帮助用户理解和学习2-3树的工作原理。 通过...

    react-d3-tree:React组件创建交互式D3树形图

    ReactD3树 React D3 Tree是一个组件,可让您利用的tree布局,以最小的设置将层次结构数据(例如,族谱,组织结构图,文件目录)表示为交互式树形图。 是否想了解v2中的更改? 查看v2发行说明。 寻找v1? 请...

    前端开源库-node-interval-tree

    3. 创建实例:`const tree = new IntervalTree()`。 4. 插入区间:`tree.insert(intervalStart, intervalEnd, data)`,其中`intervalStart`和`intervalEnd`是区间的起始和结束,`data`是关联的数据。 5. 查询:`tree...

    vue-okr-tree:http

    更新日志 更新时间2020/12/02修复初步修改数据不渲染问题对应版本:vue-okr-tree@1.0.5 ...基于Vue 2的组织架构树组件 安装 # use npm npm i vue-okr-tree # use yarn yarn add vue-okr-tree 快速开始 import { Vu

    数据结构Advanced-Data-Structures

    2-3 tree 298 2-3-4 tree 299 Queaps 301 Fusion tree 305 Bx-tree 309 Heaps 312 Heap 312 Binary heap 315 Binomial heap 321 Fibonacci heap 326 2-3 heap 331 Pairing heap 331 Beap 334 Leftist tree 335 Skew ...

    K-D Tree_翁家翌.pdf

    2. 在左子树和右子树中递归地构造 K-D Tree。 3. 对于每个节点,存储一个 K 维空间域和一个 K 维的点坐标。 节点结构 K-D Tree 的节点结构可以使用以下形式: struct KDTree_Node { int d[MaxK]; // 存储一个点...

Global site tag (gtag.js) - Google Analytics