Linked list implementation of Binary Min Heap (Having trouble with manipulation…)

后端 未结 5 635
囚心锁ツ
囚心锁ツ 2021-01-25 21:14

So i\'m trying to implement a binary min heap. I understand what the binary min heap entails in terms of it\'s structure and it\'s properties. However I\'m hitting a wall when I

相关标签:
5条回答
  • 2021-01-25 21:54

    Well you need to insert the element on the last level of the heap and then from there figure out if you need to bubble up. So you need the lastNode pointer to indicate not the last element inserted (it could very well be the last one insterted, but it might have went all the way up being now the root; that's not helpful at all), but rather the parent of where you will insert this new element. Does that help?

    (Later edit): There is a more optimal way of building the heap, but I feel that's not what you need right now, so that's why I assumed you'll be using the simple insertion with is O(log n) for every new element.

    0 讨论(0)
  • 2021-01-25 22:02

    I had the same homework assignment. The solution I found is to step down your binary tree level by level, each time deciding to make a left or a right turn depending on the number of nodes at the bottom. I made a recursive algorithm for this.

    For example, say you want to place a new node in the following tree:

        A
       / \
      B   C
     / \ / \
    D  E X  X
    

    Starting at the top, you find that there are 2/4 full nodes at the bottom. Therefore you descend via the right branch and find yourself at the top of the tree with root C. At the bottom of this tree there are 0/2 full nodes, so you descend via the left branch and find yourself at a leaf node, so that is where you place the new element.

    Here is the Java code I used to calculate the height of a tree, the number of possible nodes at the bottom of a tree with any given height, and the number of full or "used" nodes at the bottom of a tree with size size.

    private int height(int size) {
        return (int) Math.ceil(log2(size + 1));
    }
    // returns the amount of space in the bottom row of a binary tree
    private int bottomRowSpace(int height) {
        return (int) Math.pow(2, height - 1);
    }
    // returns the amount of filled spots in the bottom row of a binary tree
    private int bottomRowFilled(int size) {
        return size - (bottomRowSpace(height(size)) - 1);
    }
    // log base2
    private double log2(double a) {
        return Math.log(a) / Math.log(2);
    }
    
    0 讨论(0)
  • 2021-01-25 22:09

    Since you have to insert nodes at the bottom level, ie breadth wise , what if you maintain a record of all nodes inserted so far in a queue? When you insert a new node in the heap, find the latest position from the queue and insert the data there. Then heapify_up that node.

    0 讨论(0)
  • 2021-01-25 22:18

    I guess one more way of doing this would be to keep the count of all child elements for each node in the Tree. Since the main aim of the Binary heap is to be completely balanced, you can decide to insert the new node or they key, either towards the left or the right depending upon which side the tree is less balanced.

    I am currently trying to write the Binary Hep code using Java and am stuck at this very same point. I have come up with this approach of balancing my Heap as well as solve the problem of where to insert the new node. This should still maintain the complexities of the Heap implementation.

    Will post the code in sometime. If someone sees any issues with this or think that this is not the right way to do it, please do correct me.

    Update: Here's the code (https://gist.github.com/naveenwashere/5607516):

    public class BinaryHeap {
    
    //Later you can implement a resizable array logic.
    int[] bH;
    
    public BinaryHeap(int N)
    {
        bH = new int[N + 1];
    }
    
    //Index of the root
    int k = 1;
    
    //The APIs
    public void put(int key)
    {
        //Place the element at the end of the array
        bH[this.k] = key;       
        if(bH[this.k] > bH[this.k/2])
        {
            //since the elements in an array implementation of the binary heap is put at the end of the array,
            //we must always check if the property of the tree holds true or not.
            swim(this.k);
        }
        this.k++;
    }
    
    public void deleteMax()
    {
        //Replace the element in the root with the element at the end of the array
        bH[1] = bH[k];
        //Restore the order of the tree
        sink(1);
        this.k--;
    }
    
    public void deleteMin()
    {
        bH[this.k - 1] = 0;
        this.k--;
    }
    
    public void swim(int k)
    {
        while((k != 1) && (bH[k] > bH[k/2]))
        {
            swap(k, k/2);
            k = k/2;
        }
    }
    
    public void sink(int k)
    {
        while(2*k <= this.k)
        {
            int j = 2*k;
            if(max(j, j+1)) j++;
            if(bH[k] < bH[j])
                swap(k, j);
            else if(bH[k] > bH[j]) 
                break;
            k = j;
        }
    }
    
    private boolean max(int i, int j) {
        if(bH[i] < bH[j])
            return true;
        return false;
    }
    
    private void swap(int i, int j) {
        int temp = 0;
        temp = bH[i];
        bH[i] = bH[j];
        bH[j] = temp;
    }
    
    private void printAll() {
        for(int i=1; i < this.k; i++)
        {
            System.out.print(bH[i] + " ");
        }       
        System.out.println();
    }
    
    public static void main(String[] args) throws Exception
    {
        int a[] = {6,5,7,8,2,9,8,1};
        BinaryHeap bh = new BinaryHeap(a.length);
        for(int i=0; i < a.length; i++)
        {
            bh.put(a[i]);
        }
    
        System.out.println("Elements in Binary Heap: ");
        bh.printAll();
    
        System.out.println("Deleting Minimum: ");
        bh.deleteMin();
        bh.printAll();
    
        System.out.println("Deleting Maximum: ");
        bh.deleteMax();
        bh.printAll();
    }}
    

    Thanks, ~N

    0 讨论(0)
  • 2021-01-25 22:18

    Use this function to reach desired node:

    function find_node($n)
    {
    $current_node = $n;
    while($current_node > 1)
    {
        if($current_node % 2 == 1) // if node is odd it is a right child
        {
          push($stack,"Right");
        }
        else // otherwise it is even and left child
        {
          push($stack,"Left");
        }
        $current_node = floor($current_node / 2); // set the current node to the parent
    }
    return $stack; // this stack now contains the path to node n
    }
    
    0 讨论(0)
提交回复
热议问题