2021-08-19

23树,二三树,Java非递归实现

public class Demo<K extends Comparable<K>, V> {

    private Node<K, V> root;

    public V find(K key) {
        Node<K, V> node = this.findNode(key, this.root, null);
        for (Entity<K, V> element : node.elements) {
            if (element.key.equals(key)) {
                return element.value;
            }
        }
        return null;
    }



    public void put(K key, V value){
        Node<K, V> putNode = createNode(this.createEntity(key, value), null);

        if(Objects.isNull(this.root)){
            root = putNode;
        }else {
            Deque<Node<K, V>> stack = new LinkedList<>();

            Node<K, V> node = this.findNode(key, this.root, (item) -> stack.push(item));
            for (Entity<K, V> element : node.elements) {
                if (element.key.equals(key)) {
                    element.value = value;
                    return;
                }
            }

            Node<K, V> item = null;
            while (!stack.isEmpty()) {
                item = stack.pop();
                this.removePre(item, putNode);

                if (this.is2Node(item)) {
                    this.addElement(item, putNode);
                    break;
                }else {
                    this.addElement(item, putNode);
                    putNode = this.split(item);
                    if(stack.isEmpty()){
                        root = putNode;
                        break;
                    }
                }

            }

        }

    }

    private void removePre(Node<K, V> current, Node<K, V> pre){
        current.childs.remove(pre);
    }

    private Node<K, V> split(Node<K, V> current){
        Entity<K, V> kvEntity0 = current.elements.get(0);
        Node<K, V> node0 = this.createNode(kvEntity0, current);
        Entity<K, V> kvEntity1 = current.elements.get(2);
        Node<K, V> node1 = this.createNode(kvEntity1, current);

        current.elements.remove(kvEntity0);
        current.elements.remove(kvEntity1);

        if(!current.childs.isEmpty()){

            node0.childs.add(current.childs.get(0));
            node0.childs.add(current.childs.get(1));

            node1.childs.add(current.childs.get(2));
            node1.childs.add(current.childs.get(3));

        }

        current.childs.clear();
        current.childs.add(node0);
        current.childs.add(node1);
        current.parent = null;
        return current;
    }

    private Node<K, V> createNode(Entity<K, V> entity, Node<K, V> parent){
        Node<K, V> node = new Node<>();
        node.parent = parent;
        node.elements.add(entity);
        return node;
    }

    private Entity<K, V> createEntity(K key, V value){
        Entity<K, V> result = new Entity<>();
        result.key = key;
        result.value = value;
        return result;
    }

    private void addElement(Node<K, V> target, Node<K, V> current){
        List<Entity<K, V>> elements = target.elements;
        List<Node<K, V>> targetChilds = target.childs;

        elements.addAll(current.elements);
        elements.sort(Comparator.comparing(kvEntity -> kvEntity.key));

        if (!current.childs.isEmpty()) {
            current.childs.forEach(child -> child.parent = target);
            targetChilds.addAll(current.childs);
            targetChilds.sort(Comparator.comparing(node -> node.elements.get(node.elements.size()-1).key));
        }

    }

    private boolean is2Node(Node<K, V> node) {
        return node.elements.size() == 1;
    }

    private boolean haveChild(Node<K, V> node) {
        return !node.childs.isEmpty();
    }

    private Node<K, V> findNode(K key, Node<K, V> node, Consumer<Node<K, V>> nodeConsumer){
        Node<K, V> item = node;

        List<Entity<K, V>> elements = null;
        int compareFlag = 0;
        Entity<K, V> entityItem = null;
        K entitiyKey = null;

        out:
        while (true) {
            if(Objects.nonNull(nodeConsumer)){
                nodeConsumer.accept(item);
            }
            elements = item.elements;
            in:
            for (int i = 0; i < elements.size(); i++) {
                entityItem = elements.get(i);
                entitiyKey = entityItem.key;
                compareFlag = entitiyKey.compareTo(key);
                if (compareFlag == 0 && entitiyKey.equals(key)) {
                    return item;
                } else {
                    if (this.haveChild(item)) {
                        if (compareFlag >= 0) {
                            item = item.childs.get(i);
                            break in;
                        } else {
                            if (this.is2Node(item)) {
                                item = item.childs.get(i + 1);
                                break in;
                            }else {
                                if (i != 0) {
                                    item = item.childs.get(i + 1);
                                    break in;
                                }
                            }
                        }
                    }else {
                        break out;
                    }
                }
            }
        }

        return item;
    }

}

class Node<K extends Comparable<K>, V> {

    List<Entity<K, V>> elements = new LinkedList();

    List<Node<K, V>> childs = new LinkedList<>();

    Node<K, V> parent;

}

class Entity<K extends Comparable<K>, V> {

    K key;
    V value;

}
原理请参考

23查找树及Java实现 - 1
23查找树及Java实现 - 2
23查找树及Java实现 - 3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值