min heap

Original blog: The eighth of the classic vernacular algorithm series MoreWindows vernacular classic algorithm seven sorting summary articles

/*
 illustrate:
 1. The subscript of the heap array starts from 0;
 2. The subscript of the parent node with subscript i is (i-1)/2, and its child nodes are 2*i+1 and 2*i+2;
 3. The parent node of the last leaf node (subscript i-1) is (n-1-1)/2, that is, n/2-1.
 */
#include <iostream>
#include <vector>
using namespace std;

void MinHeapFixup(vector<int> &vi){
    //This is adjusted upwards from the element at the end, which is called by the insertion function
    // One assumption here is: the last element is the element in the newly inserted heap, and the elements before the last element form a legal min-heap.
    if(vi.size()<=1) return ;
    int i=vi.size()-1;
    int temp = vi [i];
    int j=i/2-1;
    while(j>=0){//This is the same as insertion sort.
        if(vi[j]<=vi[i]) break;
        vi [i] = vi [j];
        i=j;
        j=(i-1)/2;
    }
    vi [i] = temp;
}
//Use swap for MinHeapFixup to optimize the structure, but the efficiency will be lower, the same as the optimization of insertion sort.
void MinHeapFixup1(vector<int> &vi){
    if(vi.size()<=1) return ;
    for(int i=vi.size()-1,j=(i-1)/2; j>=0 && vi[j]>vi[i]; i=j,j=(i-1)/2)
        swap (vi [j], vi [i]);
}

void insertMinHeap(vector<int> &vi, int value){//The insertion function of the minimum heap
    vi.push_back(value);
    if(vi.size()<=1) return ;
    MinHeapFixup (vi);
// MinHeapFixup1 (vi);
}

void MinHeadFixdown(vector<int> &vi,int index=0){
    if(vi.size()<=1) return ;
    //This function is called by the min heap delete function
    //In the delete function, the first element and the last element have been exchanged, and the last element has been given to erase, and now it is adjusted downward from the first element
    int n = vi.size ();
    int i=index;//The adjustment starts from the root by default. Since this function will also be called by the createMinHeap function, an index parameter is added to indicate the node subscript to start the adjustment.
    int j=i*2+1;
    int temp=vi[index];
    while(j<n){
        if(j+1<n && vi[j+1]<vi[j]) ++j;//j marks the current smallest parent node subscript, which is clever
        if(vi[j]>temp) break;
        vi[i]=vi[j];//The smaller value moves up
        i=j;
        j=i*2+1;
    }
    vi [i] = temp;
}

void deleteMinHeap(vector<int> &vi){
    if(vi.size()==0) return ;
    vi [0] = vi.back ();
    vi.erase(--vi.end());//Delete the last element
    if(vi.size()<=1) return ;
    MinHeadFixdown (vi);
}

void createMinHeap(vector<int> &vi){
    // There are two ways to build the minimum heap from an array. One is to keep inserting and adjusting from the bottom to the top. This method is slightly troublesome and inefficient;
    //The second is to adjust the array directly, from the most present parent node to the root, call the downward adjustment method for each parent node to build the minimum heap, this method is the simplest and efficient.
    if(vi.size()<=1) return ;
    int n = vi.size ();
    //n/2-1 is the subscript of the parent node of the last element, see the top description.
    for(int i=n/2-1;i>=0;--i)
        MinHeadFixdown (vi, i);
}

void sortMinHeap(vector<int> &vi,int isdown=true){
    // get non-incrementing array from min heap
    //Because the deleteMinHeap I implemented really deleted the element, so a temporary vector is needed here,
    //Through this temporary vector we can get a non-incrementing or non-decreasing array.
    //Since the min heap is generally used to quickly get the first minimum values, the default here is to return a non-increasing array, which is consistent with the sorting result of the traditional min heap.
    vector<int> vitp;
    while(!vi.empty()){
        vitp.push_back(vi[0]);
        deleteMinHeap(vi);
    }
    if(isdown){//Get a non-incrementing array
        //copy(vitp.begin(),vitp.end(),vi.begin()); here must satisfy that vi has enough space to accommodate vitp, otherwise, only vi.size() elements will be copied from vitp
        //copy(vitp.begin(),vitp.end(),back_inserter(vi));
        //vi.swap(vitp);
        vi.assign(vitp.begin(), vitp.end());
    }
    else{
        //copy(vitp.rbegin(),vitp.rend(),back_inserter(vi));
        //reverse(vitp.begin(),vitp.end());
        //vi.swap(vitp);
        vi.assign (vitp.rbegin (), vitp.rend ());
    }
}

int main(){
    vector<int> vi;
    vi = {1,8,2,3,7,6,9,5,4};
    createMinHeap(vi);
    insertMinHeap(vi, 6);
    sortMinHeap (vi);
// sortMinHeap (vi, false);
    for (auto ieh: vi)
        cout<<ieh<<" ";
    cout<<endl;
    return 0;
}


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325859426&siteId=291194637