STL系列之四 heap 堆

下面再介绍STL中与堆相关的4个函数——建立堆make_heap(),在堆中添加数据push_heap(),在堆中删除数据pop_heap()和堆排序sort_heap():

头文件 #include <algorithm>

下面的_First与_Last为可以随机访问的迭代器(指针),_Comp为比较函数(仿函数),其规则——如果函数的第一个参数小于第二个参数应返回true,否则返回false。

建立堆

make_heap(_First, _Last, _Comp)

默认是建立最大堆的。对int类型,可以在第三个参数传入greater<int>()得到最小堆。

 

在堆中添加数据

push_heap (_First, _Last)

要先在容器中加入数据,再调用push_heap ()

 

在堆中删除数据

pop_heap(_First, _Last)

要先调用pop_heap()再在容器中删除数据

 

堆排序

sort_heap(_First, _Last)

排序之后就不再是一个合法的heap了

 

    //by MoreWindows( http://blog.csdn.net/MoreWindows )  
    #include <cstdio>  
    #include <vector>  
    #include <algorithm>  
    #include <functional>  
    using namespace std;  
    void PrintfVectorInt(vector<int> &vet)  
    {  
        for (vector<int>::iterator pos = vet.begin(); pos != vet.end(); pos++)  
            printf("%d ", *pos);  
        putchar('\n');  
    }  
    int main()  
    {  
        const int MAXN = 20;  
        int a[MAXN];  
        int i;  
        for (i = 0; i < MAXN; ++i)  
            a[i] = rand() % (MAXN * 2);  
      
        //动态申请vector 并对vector建堆  
        vector<int> *pvet = new vector<int>(40);  
        pvet->assign(a, a + MAXN);  
      
        //建堆  
        make_heap(pvet->begin(), pvet->end());  
        PrintfVectorInt(*pvet);  
      
        //加入新数据 先在容器中加入,再调用push_heap()  
        pvet->push_back(25);  
        push_heap(pvet->begin(), pvet->end());  
        PrintfVectorInt(*pvet);  
      
        //删除数据  要先调用pop_heap(),再在容器中删除  
        pop_heap(pvet->begin(), pvet->end());  
        pvet->pop_back();  
        pop_heap(pvet->begin(), pvet->end());  
        pvet->pop_back();  
        PrintfVectorInt(*pvet);  
      
        //堆排序  
        sort_heap(pvet->begin(), pvet->end());  
        PrintfVectorInt(*pvet);  
      
        delete pvet;  
        return 0;  
    }  

 

    // by MoreWindows( http://blog.csdn.net/MoreWindows )  
    #include <cstdio>  
    #include <algorithm>  
    #include <ctime>  
    using namespace std;  
    //------------------------快速排序----------------------------  
    void quick_sort(int s[], int l, int r)  
    {  
        if (l < r)  
        {  
            int i = l, j = r, x = s[l];  
            while (i < j)  
            {  
                while(i < j && s[j] >= x) // 从右向左找第一个小于x的数  
                    j--;    
                if(i < j)   
                    s[i++] = s[j];  
      
                while(i < j && s[i] < x) // 从左向右找第一个大于等于x的数  
                    i++;    
                if(i < j)   
                    s[j--] = s[i];  
            }  
            s[i] = x;  
            quick_sort(s, l, i - 1); // 递归调用   
            quick_sort(s, i + 1, r);  
        }  
    }  
    //------------------------归并排序----------------------------  
    //将有二个有序数列a[first...mid]和a[mid...last]合并。  
    void mergearray(int a[], int first, int mid, int last, int temp[])  
    {  
        int i = first, j = mid + 1;  
        int m = mid,   n = last;  
        int k = 0;  
      
        while (i <= m && j <= n)  
        {  
            if (a[i] < a[j])  
                temp[k++] = a[i++];  
            else  
                temp[k++] = a[j++];  
        }  
      
        while (i <= m)  
            temp[k++] = a[i++];  
      
        while (j <= n)  
            temp[k++] = a[j++];  
      
        for (i = 0; i < k; i++)  
            a[first + i] = temp[i];  
    }  
    void mergesort(int a[], int first, int last, int temp[])  
    {  
        if (first < last)  
        {  
            int mid = (first + last) / 2;  
            mergesort(a, first, mid, temp);    //左边有序  
            mergesort(a, mid + 1, last, temp); //右边有序  
            mergearray(a, first, mid, last, temp); //再将二个有序数列合并  
        }  
    }  
    bool MergeSort(int a[], int n)  
    {  
        int *p = new int[n];  
        if (p == NULL)  
            return false;  
        mergesort(a, 0, n - 1, p);  
        return true;  
    }  
    //------------------------堆排序---------------------------  
    inline void Swap(int &a, int &b)  
    {  
        int c = a;  
        a = b;  
        b = c;  
    }  
    //建立最小堆  
    //  从i节点开始调整,n为节点总数 从0开始计算 i节点的子节点为 2*i+1, 2*i+2  
    void MinHeapFixdown(int a[], int i, int n)  
    {  
        int j, temp;  
      
        temp = a[i];  
        j = 2 * i + 1;  
        while (j < n)  
        {  
            if (j + 1 < n && a[j + 1] < a[j]) //在左右孩子中找最小的  
                j++;  
      
            if (a[j] >= temp)  
                break;  
      
            a[i] = a[j];     //把较小的子结点往上移动,替换它的父结点  
            i = j;  
            j = 2 * i + 1;  
        }  
        a[i] = temp;  
    }  
    //建立最小堆  
    void MakeMinHeap(int a[], int n)  
    {  
        for (int i = n / 2 - 1; i >= 0; i--)  
            MinHeapFixdown(a, i, n);  
    }  
    void MinheapsortTodescendarray(int a[], int n)  
    {  
        for (int i = n - 1; i >= 1; i--)  
        {  
            Swap(a[i], a[0]);  
            MinHeapFixdown(a, 0, i);  
        }  
    }  
    const int MAXN = 5000000;  
    int a[MAXN];  
    int b[MAXN], c[MAXN], d[MAXN];  
    int main()  
    {  
        int i;  
        srand(time(NULL));  
        for (i = 0; i < MAXN; ++i)  
            a[i] = rand() * rand(); //注rand()产生的数在0到65536之间  
      
        for (i = 0; i < MAXN; ++i)  
            d[i] = c[i] = b[i] = a[i];  
      
        clock_t ibegin, iend;  
      
        printf("--当前数据量为%d--By MoreWindows(http://blog.csdn.net/MoreWindows)--\n", MAXN);  
        //快速排序  
        printf("快速排序:  ");  
        ibegin = clock();  
        quick_sort(a, 0, MAXN - 1);  
        iend = clock();  
        printf("%d毫秒\n", iend - ibegin);  
      
          
        //归并排序  
        printf("归并排序:  ");  
        ibegin = clock();  
        MergeSort(b, MAXN);  
        iend = clock();  
        printf("%d毫秒\n", iend - ibegin);  
      
        //堆排序  
        printf("堆排序:  ");  
        ibegin = clock();  
        MakeMinHeap(c, MAXN);  
        MinheapsortTodescendarray(c, MAXN);  
        iend = clock();  
        printf("%d毫秒\n", iend - ibegin);  
      
        //STL中的堆排序  
        printf("STL中的堆排序: ");     
        ibegin = clock();  
        make_heap(d, d + MAXN);  
        sort_heap(d, d + MAXN);  
        iend = clock();  
        printf("%d毫秒\n", iend - ibegin);  
        return 0;  
    }  

 

转载于:https://www.cnblogs.com/long735/archive/2012/04/04/2432417.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值