Implement Heap using a Binary Tree

后端 未结 7 1648
栀梦
栀梦 2020-12-14 03:49

This question has been asked before in Stack Exchange but it went unanswered.

Link to the previously asked question: Binary Heap Implemented via a Binary Tree Struct

相关标签:
7条回答
  • 2020-12-14 04:23
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @author Harish R
     */
    public class HeapPractise<T extends Comparable<T>> {
    
        private List<T> heapList;
    
        public List<T> getHeapList() {
            return heapList;
        }
    
        public void setHeapList(List<T> heapList) {
            this.heapList = heapList;
        }
    
        private int heapSize;
    
        public HeapPractise() {
            this.heapList = new ArrayList<>();
            this.heapSize = heapList.size();
        }
    
        public void insert(T item) {
            if (heapList.size() == 0) {
                heapList.add(item);
            } else {
                siftUp(item);
            }
    
        }
    
        private void siftUp(T item) {
            heapList.add(item);
            heapSize = heapList.size();
            int currentIndex = heapSize - 1;
            while (currentIndex > 0) {
                int parentIndex = (int) Math.floor((currentIndex - 1) / 2);
                T parentItem = heapList.get(parentIndex);
                if (parentItem != null) {
                    if (item.compareTo(parentItem) > 0) {
                        heapList.set(parentIndex, item);
                        heapList.set(currentIndex, parentItem);
                        currentIndex = parentIndex;
                        continue;
                    }
                }
                break;
            }
        }
    
        public T delete() {
            if (heapList.size() == 0) {
                return null;
            }
            if (heapList.size() == 1) {
                T item = heapList.get(0);
                heapList.remove(0);
                return item;
            }
            return siftDown();
        }
    
        private T siftDown() {
            T item = heapList.get(0);
            T lastItem = heapList.get(heapList.size() - 1);
            heapList.remove(heapList.size() - 1);
            heapList.set(0, lastItem);
            heapSize = heapList.size();
            int currentIndex = 0;
            while (currentIndex < heapSize) {
                int leftIndex = (2 * currentIndex) + 1;
                int rightIndex = (2 * currentIndex) + 2;
                T leftItem = null;
                T rightItem = null;
                int currentLargestItemIndex = -1;
                if (leftIndex <= heapSize - 1) {
                    leftItem = heapList.get(leftIndex);
                }
                if (rightIndex <= heapSize - 1) {
                    rightItem = heapList.get(rightIndex);
                }
                T currentLargestItem = null;
                if (leftItem != null && rightItem != null) {
                    if (leftItem.compareTo(rightItem) >= 0) {
                        currentLargestItem = leftItem;
                        currentLargestItemIndex = leftIndex;
                    } else {
                        currentLargestItem = rightItem;
                        currentLargestItemIndex = rightIndex;
                    }
                } else if (leftItem != null && rightItem == null) {
                    currentLargestItem = leftItem;
                    currentLargestItemIndex = leftIndex;
                }
                if (currentLargestItem != null) {
                    if (lastItem.compareTo(currentLargestItem) >= 0) {
                        break;
                    } else {
                        heapList.set(currentLargestItemIndex, lastItem);
                        heapList.set(currentIndex, currentLargestItem);
                        currentIndex = currentLargestItemIndex;
                        continue;
                    }
                } else {
                    break;
                }
            }
            return item;
    
        }
    
        public static void main(String[] args) {
            HeapPractise<Integer> heap = new HeapPractise<>();
    
            for (int i = 0; i < 32; i++) {
                heap.insert(i);
            }
            System.out.println(heap.getHeapList());
            List<Node<Integer>> nodeArray = new ArrayList<>(heap.getHeapList()
                    .size());
            for (int i = 0; i < heap.getHeapList().size(); i++) {
                Integer heapElement = heap.getHeapList().get(i);
                Node<Integer> node = new Node<Integer>(heapElement);
                nodeArray.add(node);
            }
            for (int i = 0; i < nodeArray.size(); i++) {
                int leftNodeIndex = (2 * i) + 1;
                int rightNodeIndex = (2 * i) + 2;
                Node<Integer> node = nodeArray.get(i);
                if (leftNodeIndex <= heap.getHeapList().size() - 1) {
                    Node<Integer> leftNode = nodeArray.get(leftNodeIndex);
                    node.left = leftNode;
                }
                if (rightNodeIndex <= heap.getHeapList().size() - 1) {
                    Node<Integer> rightNode = nodeArray.get(rightNodeIndex);
                    node.right = rightNode;
                }
            }
            BTreePrinter.printNode(nodeArray.get(0));
            System.out.println(heap.delete());
            nodeArray = new ArrayList<>(heap.getHeapList().size());
            for (int i = 0; i < heap.getHeapList().size(); i++) {
                Integer heapElement = heap.getHeapList().get(i);
                Node<Integer> node = new Node<Integer>(heapElement);
                nodeArray.add(node);
            }
            for (int i = 0; i < nodeArray.size(); i++) {
                int leftNodeIndex = (2 * i) + 1;
                int rightNodeIndex = (2 * i) + 2;
                Node<Integer> node = nodeArray.get(i);
                if (leftNodeIndex <= heap.getHeapList().size() - 1) {
                    Node<Integer> leftNode = nodeArray.get(leftNodeIndex);
                    node.left = leftNode;
                }
                if (rightNodeIndex <= heap.getHeapList().size() - 1) {
                    Node<Integer> rightNode = nodeArray.get(rightNodeIndex);
                    node.right = rightNode;
                }
            }
            BTreePrinter.printNode(nodeArray.get(0));
        }
    }
    
    public class Node<T extends Comparable<?>> {
        Node<T> left, right;
        T data;
    
        public Node(T data) {
            this.data = data;
        }
    }
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    
    class BTreePrinter {
    
        public static <T extends Comparable<?>> void printNode(Node<T> root) {
            int maxLevel = BTreePrinter.maxLevel(root);
    
            printNodeInternal(Collections.singletonList(root), 1, maxLevel);
        }
    
        private static <T extends Comparable<?>> void printNodeInternal(
                List<Node<T>> nodes, int level, int maxLevel) {
            if (nodes.isEmpty() || BTreePrinter.isAllElementsNull(nodes))
                return;
    
            int floor = maxLevel - level;
            int endgeLines = (int) Math.pow(2, (Math.max(floor - 1, 0)));
            int firstSpaces = (int) Math.pow(2, (floor)) - 1;
            int betweenSpaces = (int) Math.pow(2, (floor + 1)) - 1;
    
            BTreePrinter.printWhitespaces(firstSpaces);
    
            List<Node<T>> newNodes = new ArrayList<Node<T>>();
            for (Node<T> node : nodes) {
                if (node != null) {
                    String nodeData = String.valueOf(node.data);
                    if (nodeData != null) {
                        if (nodeData.length() == 1) {
                            nodeData = "0" + nodeData;
                        }
                    }
                    System.out.print(nodeData);
                    newNodes.add(node.left);
                    newNodes.add(node.right);
                } else {
                    newNodes.add(null);
                    newNodes.add(null);
                    System.out.print("  ");
                }
    
                BTreePrinter.printWhitespaces(betweenSpaces);
            }
            System.out.println("");
    
            for (int i = 1; i <= endgeLines; i++) {
                for (int j = 0; j < nodes.size(); j++) {
                    BTreePrinter.printWhitespaces(firstSpaces - i);
                    if (nodes.get(j) == null) {
                        BTreePrinter.printWhitespaces(endgeLines + endgeLines + i
                                + 1);
                        continue;
                    }
    
                    if (nodes.get(j).left != null)
                        System.out.print("//");
                    else
                        BTreePrinter.printWhitespaces(1);
    
                    BTreePrinter.printWhitespaces(i + i - 1);
    
                    if (nodes.get(j).right != null)
                        System.out.print("\\\\");
                    else
                        BTreePrinter.printWhitespaces(1);
    
                    BTreePrinter.printWhitespaces(endgeLines + endgeLines - i);
                }
    
                System.out.println("");
            }
    
            printNodeInternal(newNodes, level + 1, maxLevel);
        }
    
        private static void printWhitespaces(int count) {
            for (int i = 0; i < 2 * count; i++)
                System.out.print(" ");
        }
    
        private static <T extends Comparable<?>> int maxLevel(Node<T> node) {
            if (node == null)
                return 0;
    
            return Math.max(BTreePrinter.maxLevel(node.left),
                    BTreePrinter.maxLevel(node.right)) + 1;
        }
    
        private static <T> boolean isAllElementsNull(List<T> list) {
            for (Object object : list) {
                if (object != null)
                    return false;
            }
    
            return true;
        }
    
    }
    

    Please note that BTreePrinter is a code I took somewhere in Stackoverflow long back and I modified to use with 2 digit numbers.It will be broken if we move to 3 digit numbers and it is only for simple understanding of how the Heap structure looks.A fix for 3 digit numbers is to keep everything as multiple of 3. Also due credits to Sesh Venugopal for wonderful tutorial on Youtube on Heap data structure

    0 讨论(0)
提交回复
热议问题