Heapify

Given an integer array, heapify it into a min-heap array.

For a heap array A, A[0] is the root of heap, and for each A[i], A[i 2 + 1] is the left child of A[i] and A[i 2 + 2] is the right child of A[i].

http://www.lintcode.com/en/problem/heapify/

Discussion


这里的数组是树的一种存储方式,给定i,它的左右子树分别是2i+1和2i+2,parent是(i-1)/2, 从n/2开始到n-1都是叶子节点。画个图就明白了,数据结构里也讲过的。

最小堆就是给定任意node,都比它的左右孩子(如果存在的话)小,最大堆则相反。heapify的过程就是建立这样的关系的过程。

思路1:自底向上。从有左右子树的最底层的node开始,也就是n/2-1开始,如果node的两个子节点都比node节点小,那么就swap最小的那个, 只有一个小就swap小的那个。swap之后,我们要重新heapify 被换的节点(曾经的母节点,现在的子节点)。时间复杂度O(n).

Solution 1

class Solution {
public:
    /**
     * @param A: Given an integer array
     * @return: void
     */
    void heapify(vector<int> &A) {
        // write your code here
        for(int i=A.size()/2-1; i>=0; i--) {
       // for(int i=0; i<A.size(); i++) {
            heapify(A, i);
        }
    }
    void heapify(vector<int> &A, int index) {
        int left = 2*index+1 < A.size() ? A[2*index+1] : INT_MAX;
        int right = 2*index+2 < A.size() ? A[2*index+2] : INT_MAX;
        if(left < right && left < A[index] ) {
            A[2*index+1] = A[index];
            A[index] = left;
            heapify(A, 2*index+1);
        } else if(right < A[index]) {
            A[2*index+2] = A[index];
            A[index] = right;
            heapify(A, 2*index+2);
        }
    }
};

思路2: 自定向下。给定节点node i,比较它的父节点(i-1)/2,根据堆的定义决定要不要交换,如果要交换,还要接着heapify新的父节点。

class Solution {
public:
    /**
     * @param A: Given an integer array
     * @return: void
     */
    void heapify(vector<int> &A) {
        // write your code here
        //for(int i=A.size()/2-1; i>=0; i--) {
       for(int i=0; i<A.size(); i++) {
            heapify(A, i);
        }
    }
    void heapify(vector<int> &A, int index) {
        while (true) {
            int parent = (index-1)/2;
            if(parent < 0) break;
            if(A[parent] > A[index]) {
                swap(A[parent], A[index]);
                index = parent;
            } else {
                break;
            }
        }
    }
};

逐次插入新元素到heap里:

class Solution {
public:
    /**
     * @param A: Given an integer array
     * @return: void
     */
    void heapify(vector<int> &A) {
        vector<int> heap;
        for(auto const& val : A) {
            Insert(heap, val);
        }
        A = heap;
    }

    void Insert(vector<int> &heap, int val) {
        heap.emplace_back(val);
        int i = heap.size()-1; //the postion of the new value
        //bottom-up heapify it
        while(i>0 && heap[i] < heap[(i-1)/2]) {
           swap(heap[i], heap[(i-1)/2]);
           i = (i-1)/2;
        }
    }
};

results matching ""

    No results matching ""