處理海量資料的三大排序之——堆排序(C++)

來源:互聯網
上載者:User

標籤:style   blog   http   color   使用   os   io   strong   

 

在面對大資料量的排序時(100W以上量級資料),通常用以下三種的排序方法:快速排序、歸併排序,堆排序。在這個量級上,其他冒泡,選擇,插入排序等已經根本沒法看了,效率極低,跟前面三種排序差了千百倍,因此不作比較。

這三種排序的平均時間複雜度均為O(nlogn),快速排序,歸併排序在面對基本有序序列排序時,效率反會降低。且歸併排序需要用到O(n)的臨時儲存空間。而堆排序沒有明顯缺點,特別在面對經常會插入新元素的排序需求,堆排序效果最好。

下面是三種排序對100W個無序數組進行排序的時間對比,可以看出在平均情況下,時間效率:快排>歸併>堆排序

 

 

基礎概念                                                                                                                                                                                                       

什麼是堆?

:一種資料結構,全稱為:二元堆積資料結構,是一種數組對象。

當所有節點都大於各自左右子節點時,叫大頂堆;

當所有節點都小於各自左右子節點時,叫小頂堆。

在堆排序中,使用大頂堆結構。

排序原理                                                                                                                                                                                                       

若輸出堆頂的最大值之後,使得剩餘n-1個元素的序列重新又建成一個堆,則得到n個元素中個次大值。如此反覆執行,便能得到一個有序序列,這個過程就稱之為堆排序。

因此堆排序的實現思路,可以細分為兩部分:

1、如何將一個無序數組排列成大頂堆(建堆過程)

2、拿走最大值後如何從剩下的堆中找出次大值,重建立立大頂堆(篩選過程)

時間複雜度                                                                                                                                                                                                    

堆排序可分細分為兩部分:建堆過程+排序過程。

建堆過程時間複雜度為O(n),即將一個無序數組建立成堆只需要線性時間。

排序過程需要對n個資料進行篩選時,每次篩選需要O(logn)時間,所以整個排序過程的時間為O(nlogn)

因此堆排序總的已耗用時間為: O(nlogn) = O(n) + O(nlogn)

演算法實現                                                                                                                                                                                                        

#include "stdafx.h"#include <iostream>#include <ctime>using namespace std;int a[1000000];#define BEGIN_RECORD            \{                                clock_t ____temp_begin_time___;    ____temp_begin_time___=clock();#define END_RECORD(dtime)        \dtime=float(clock()-____temp_begin_time___)/CLOCKS_PER_SEC;}/*    目標:篩選區域為以索引i為樹根的子樹,找出該子樹最大值,將其存放到索引i    過程:從索引為i的結點開始往下,與較大的子節點交換值,向下搜尋直到子樹底部    a - 待排序數組    i - 篩選起始結點索引    len - 排序元素數量*/void sift(int a[], int i, int len)    {    int temp = a[i];    int j = 2 * i;    while(j <= len)    {        if(j < len && a[j] < a[j+1])    //如果右結點比左結點大,則拿右結點跟父節點比較            j++;        if(a[i] < a[j])                 //如果子節點比父節點大,則兩者交換值,子節點成為新的父節點,繼續向下篩選        {            a[i] = a[j];            a[j] = temp;            i = j;            j = 2 * i;        }        else                            //如果父節點比子節點大,則說明找到了該子樹的最大值,結束篩選        {            break;        }    }    a[i] = temp;}/*堆排序(大頂堆)a - 待排序的數組len - 數組長度*/void heapSort(int a[], int len){    int temp;    int i;    for (i = len-1; i > 0; i--)      //堆排序只能從下標為1開始排序,因此要把數組所有資料後一移位。下標0的資料不處理    {        a[i] =  a[i - 1];    }        for (i = len/2; i >= 1; i--)     //建堆過程(使得全樹的父節點都比子節點大)    {        sift(a, i, len);    }    for (i = len - 1; i >= 2; i--)   //排序過程:每次從樹根取值(該值必為最大值),放到樹的最後一個結點n,並把該結點從樹中移除。重複排序過程,直到將所有結點從樹移除,排序結束    {        temp = a[1];        a[1] = a[i];        a[i] = temp;        sift(a, 1, i - 1);        //從樹根取出最大值,取最尾樹結點放到樹根,此時樹根不再為最大值,需要再對樹根進行一次篩選過程,以確保樹根仍然為最大值    }}void printArray(int a[], int length){    cout << "數組內容:";    for(int i = 0; i < length; i++)    {        if(i == 0)            cout << a[i];        else            cout << "," << a[i];    }    cout << endl;}int _tmain(int argc, _TCHAR* argv[]){    float tim;    BEGIN_RECORD    //int a[1000000];    for (int i = 0; i < 1000000; i++)    {        a[i] = int(rand() % 100000);    }    //printArray(a, sizeof(a)/sizeof(int));    heapSort(a, sizeof(a)/sizeof(int));    //printArray(a, sizeof(a)/sizeof(int));    END_RECORD(tim)        cout << "已耗用時間:" << tim << "s" <<  endl;    system("pause");    return 0;}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.