经典排序算法(9)——桶排序算法详解
桶排序(Bucket sort)或所謂的箱排序,并不是比較排序,它不受到 O(nlogn) 下限的影響。
一、算法基本思想
(1)基本思想
桶排序工作的原理是將數組分到有限數量的桶子里,每個桶子再個別排序,有可能再使用別的排序算法或是以遞歸方式繼續使用桶排序進行排序。桶排序是鴿巢排序的一種歸納結果。當要被排序的數組內的數值是均勻分配的時候,桶排序使用線性時間O(n)。
(2)運行過程
桶排序算法的運行過程如下:
1、設置一個定量的數組當作空桶子。
2、尋訪序列,并且把項目一個一個放到對應的桶子去。
3、對每個不是空的桶子進行排序。
4、從不是空的桶子里把項目再放回原來的序列中。
(3)示例
二、算法實現(核心代碼)
C++實現:假設數據分布在[0,100)之間,每個桶內部用鏈表表示,在數據入桶的同時插入排序。然后把各個桶中的數據合并。
#include<iterator> #include<iostream> #include<vector> using namespace std; const int BUCKET_NUM = 10;struct ListNode{explicit ListNode(int i=0):mData(i),mNext(NULL){}ListNode* mNext;int mData; };ListNode* insert(ListNode* head,int val){ListNode dummyNode;ListNode *newNode = new ListNode(val);ListNode *pre,*curr;dummyNode.mNext = head;pre = &dummyNode;curr = head;while(NULL!=curr && curr->mData<=val){pre = curr;curr = curr->mNext;}newNode->mNext = curr;pre->mNext = newNode;return dummyNode.mNext; }ListNode* Merge(ListNode *head1,ListNode *head2){ListNode dummyNode;ListNode *dummy = &dummyNode;while(NULL!=head1 && NULL!=head2){if(head1->mData <= head2->mData){dummy->mNext = head1;head1 = head1->mNext;}else{dummy->mNext = head2;head2 = head2->mNext;}dummy = dummy->mNext;}if(NULL!=head1) dummy->mNext = head1;if(NULL!=head2) dummy->mNext = head2;return dummyNode.mNext; }void BucketSort(int n,int arr[]){vector<ListNode*> buckets(BUCKET_NUM,(ListNode*)(0));for(int i=0;i<n;++i){int index = arr[i]/BUCKET_NUM;ListNode *head = buckets.at(index);buckets.at(index) = insert(head,arr[i]);}ListNode *head = buckets.at(0);for(int i=1;i<BUCKET_NUM;++i){head = Merge(head,buckets.at(i));}for(int i=0;i<n;++i){arr[i] = head->mData;head = head->mNext;} }
三、性能(算法時間、空間復雜度、穩定性)分析
假設有n個數字,有m個桶,如果數字是平均分布的,則每個桶里面平均有n/m個數字。如果 對每個桶中的數字采用快速排序,那么整個算法的復雜度是 O(n + m * (n/m) * log(n/m)) =O(n + nlogn – nlogm) 。
從上式看出,當m接近n的時候,桶排序時間復雜度接近O(n)。當然,以上復雜度的計算是基于輸入的n個數字是平均分布這個假設的。這個假設是很強的 ,實際應用中效果并沒有這么好。
如果所有的數字都落在同一個桶中,那就退化成一般的排序了。 前面說的幾大排序算法 ,大部分時間復雜度都是O(n^2),也有部分排序算法時間復雜度是O(nlogn)。而桶式排序卻能實現O(n)的時間復雜度。
但桶排序的缺點是: 1)首先是空間復雜度比較高,需要的額外開銷大。排序有兩個數組的空間開銷,一個存放待排序數組,一個就是所謂的桶,比如待排序值是從0到m-1,那就需要m個桶,這個桶數組就要至少m個空間。 2)其次待排序的元素都要在一定的范圍內等等。
通排序的空間復雜度為O(n+m)。
桶排序的穩定性依賴于桶內排序。如果我們使用了快排,顯然,算法是不穩定的。
總結
以上是生活随笔為你收集整理的经典排序算法(9)——桶排序算法详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 经典排序算法(8)——归并排序算法详解
- 下一篇: 经典排序算法(10)——基数排序算法详解