设计一个没有扩容负担的堆结构

来源:互联网 发布:dns 默认端口 编辑:程序博客网 时间:2024/06/08 19:54
import java.util.Comparator;/** * Created by lxw, liwei4939@126.com on 2017/11/4. * 设计一个没有扩容负担的堆结构 */class Node{    public int value;    public Node left;    public Node right;    public Node parent;    public Node(int data){        this.value = data;    }}public class myHeap {    private Node head;  // 堆头结点    private Node last;  // 堆尾结点    private long size;  // 堆的大小    private Comparator<Integer> comp; // 大根堆或小根堆    public myHeap(Comparator<Integer> compare){        head = null;        last = null;        size = 0;        comp = compare;    }    public int getHead(){        return head == null ? null : head.value;    }    public long getSize(){        return size;    }    public boolean isEmpty(){        return size == 0 ? true : false;    }    // 添加一个新节点到堆中    public void add(int value){        Node newNode = new Node(value);        if(size ==0){            head = newNode;            last = newNode;            size++;            return;        }        Node node = last;        Node parent = node.parent;        // 找到正确的位置,插入到新节点        while (parent != null && node != parent.left){            node = parent;            parent = node.parent;        }        Node nodeToAdd = null;        if(parent == null){            nodeToAdd  =mostLeft(head);            nodeToAdd.left = newNode;            newNode.parent = nodeToAdd;        } else if(parent.right == null){            parent.right = newNode;            newNode.parent = parent;        } else {            nodeToAdd = mostLeft(parent.right);            nodeToAdd.left = newNode;            newNode.parent = nodeToAdd;        }        last = newNode;        // 建堆及其调整        heapInsertModify();        size++;    }    // 建堆和调整的过程    private void heapInsertModify(){        Node node = last;        Node parent = node.parent;        if(parent != null && comp.compare(node.value, parent.value) < 0){            last = parent;        }        while (parent != null && comp.compare(node.value, parent.value) < 0){            swapClosedTwoNodes(node, parent);            parent = node.parent;        }        if(head.parent != null){            head = head.parent;        }    }    // 堆heapify过程    private void heapify(Node node){        Node left = node.left;        Node right = node.right;        Node most = node;        while (left != null){            if(left != null && comp.compare(left.value, most.value) < 0){                most = left;            }            if(right != null && comp.compare(right.value, most.value) < 0){                most = right;            }            if(most != node){                swapClosedTwoNodes(most, node);            } else {                break;            }            left = node.left;            right = node.right;            most = node;        }        if(node.parent == last){            last = node;        }        while (node.parent != null){            node = node.parent;        }        head = node;    }    //交换两个相近的结点    private void swapClosedTwoNodes(Node node, Node parent){        if(node == null || parent == null){            return;        }        Node parentparent = parent.parent;        Node parentLeft = parent.left;        Node parentRight = parent.right;        Node nodeLeft = node.left;        Node nodeRight = node.right;        node.parent  =parentparent;        if(parentparent != null){            if(parent == parentparent.left){                parentparent.left = node;            } else {                parentparent.right = node;            }        }        if(nodeLeft != null){            nodeLeft.parent = parent;        }        if(nodeRight != null){            nodeRight.parent = parent;        }        parent.parent = node;        parent.left = nodeLeft;        parent.right = nodeRight;        if(node == parent.left){            node.left = parent;            node.right = parentRight;            if(parentRight != null){                parentRight.parent = node;            }        } else {            node.left = parentLeft;            node.right = parent;            if(parentLeft != null){                parentLeft.parent = parent;            }        }    }    // 找到以node为头的子树中,最左的结点    private Node mostLeft(Node node){        while (node.left !=null){            node = node.left;        }        return node;    }    public int popHead(){        if(size == 0){            return 0;        }        Node res = head;        if(size == 1){            head = null;            last = null;            size--;            return res.value;        }        Node oldLast = popLastAndSetPrevoiusLast();        // 若弹出堆尾结点后,堆大小为1        if(size ==1){            head = oldLast;            last = oldLast;            return res.value;        }        // 若弹出堆结点后,堆大小大于1        Node headLeft = res.left;        Node headRight = res.right;        oldLast.left = headLeft;        if(headLeft != null){            headLeft.parent = oldLast;        }        oldLast.right = headRight;        if(headRight != null){            headRight.parent = oldLast;        }        res.left = null;        res.right = null;        head = oldLast;        // 堆heapify过程        heapify(oldLast);        return res.value;    }    // 在树中弹出堆尾结点,找到倒数第二个结点设置为新的堆尾结点    private Node popLastAndSetPrevoiusLast(){        Node node = last;        Node parent  =node.parent;        while (parent != null && node != parent.right){            node = parent;            parent = node.parent;        }        if(parent == null){            node = last;            parent = node.parent;            node.parent = null;            if(node == parent.left){                parent.left = null;            } else {                parent.right = null;            }            last = mostRight(head);        } else {            Node newlast = mostRight(parent.left);            node =last;            parent = node.parent;            node.parent = null;            if(node == parent.left){                parent.left = null;            } else {                parent.right = null;            }            last = newlast;        }        size--;        return node;    }        // 找到以node为头的子树中,最右的节点    private Node mostRight(Node node){        while (node.right != null){            node = node.right;        }        return node;    }        }

阅读全文
0 0
原创粉丝点击