桶排序
一.演算法思想
分治思想*
舉個例子:把1000士兵按身高分為四個方陣隊,你會如何劃分?
思考30秒後,往下看:
可能你會讓每個士兵報出身高,兩兩比較然後設定區域劃分?
這樣方法可以,但是會顯得很混亂,需要記錄特別多的資料。
換一種簡單的思路:
- 找出身高最高和最矮,並且記錄未Max,Min;
- (Max-Min)/4
- 記錄每個人的身高
- 分到相應的組(桶)中,直接丟進去,像丟到垃圾桶中一樣,此時是無序的
- 再把桶中垃圾分類(即把桶中資料排序)
- 最後把桶排序,當然桶中資料也按序拿出來
注:這裡的4是因為分為四組;容易出現的錯誤是,有人會以為把1000人分為四組,每一組250個人,但是這樣是不對的,你想身高這個並不是有規律的,大多人在170-175之間,所以並不是根據人數劃分,而是求出最大值和最小值,然後平均一下,只樣誤差會小一點,但是還會有誤差。
這樣就可以把對應資料丟到相應的桶中了。
這就是桶排序實現的過程;
當然會有比較正規的桶排序實現流程:
1. 設定一個定量的陣列當作空桶;
2. 遍歷輸入資料,並且把資料對映完之後,一個一個放到對應的桶裡去;
3. 對每個不是空的桶進行排序;
4. 從不是空的桶裡把排好序的資料拼接起來。
這就是基本實現流程了。
接下來就是程式碼實現了:
對於新手來說:如果對於語言的熟練度不是特別高的話,嘗試先寫出其核心演算法的虛擬碼;所謂虛擬碼,簡言之就是你能看懂,編譯軟體看不懂的程式碼:
for(i=0;i<n;i++)
{
求出最大值MAX,最小值MIN;
}
(MAX-MIN)/4=T
A1=MIN+T;
A2=A1+T;;
A3=A2+T;
A4=A3+T//求出四個組
for(i=0;i<n;i++)
{
比較範圍 a[i]在A1裡面或者在A2,A3,A4中
}
流程圖略了:但是附上一個有虛擬碼和流程圖的參考連結:
演算法流程圖
接下來程式碼實現了:
這裡實現的話,我採用最簡單的方式,參考《啊哈!演算法》一書。
假設一個編號就是一個桶,如果這個數有重複的,則這個桶加一;
#include<stdio.h>
int main()
{
int book[1001];
int i,j,t,n;
for(i=0;i<=1000;i++)
book[i]=0;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&t);
book[t]++;//計數
}
for(i=1000;i>=0;i--)//判斷編號 1000-0的桶
{
for(j=1;j<=book[i];j++)
printf("%d ",i);
}
getchar();//用於暫停程式,方便檢視結果
return 0;
}
這裡採用的是一維陣列實現儲存資料以及儲存桶。這個缺點顯而易見,一維陣列必需大於最大的數,但是提前分配記憶體的判斷大小肯定很難,所以容易造成空間浪費,而且有的桶內資料可能很多,有的桶內資料很少,像身高來說,集中在165-170的肯定會最多,但是其他桶內就會少,但是分配的話還是一樣的多的記憶體,由此也造成一定的浪費。
引出:結構體方式
倘若你還沒學到,則到此為止,當然你也可以提前瞭解。
using namespace std;
struct ListNode
{
double value;
ListNode *next;
};
//桶排序主程式
void bucketSort(double* arr, int length)
{
ListNode key[bucket_num]; // 對映關係: int key <- ElemNum/bucket_num
int number = 0;
ListNode *p, *q; //插入節點臨時變數
int counter = 0;
for(int i = 0; i < bucket_num; i++)
{
key[i].value = 0;
key[i].next = NULL;
}
for(int i = 0; i < length; i++)
{
ListNode *insert = new ListNode();
insert->value = arr[i];
insert->next = NULL;
number = arr[i] * bucket_num;
if(key[number].next == NULL)
{
key[number].next = insert;
}
else
{
p = &key[number];
q = key[number].next;
while((q != NULL) && (q->value <= arr[i]))
{
q = q->next;
p = p->next;
}
insert->next = q;
p->next = insert;
}
}
for(int i = 0; i < bucket_num; i++)
{
p = key[i].next;
if(p == NULL)
continue;
while(p != NULL)
{
arr[counter++] = p->value;
p = p->next;
}
}
}
這個程式碼只是展示了思想。不可執行。
相關文章
- 桶排序2排序
- 排序演算法__桶排序排序演算法
- 桶排序和基數排序排序
- 桶排序bucket sort排序
- (四)桶排序法排序
- 有趣的桶排序排序
- 排序演算法之——桶排序排序演算法
- 桶排序 選擇,插入排序排序
- 非交換排序-計數排序和桶排序排序
- 計數排序、桶排序和基數排序排序
- hive分桶表排序Hive排序
- 常用排序演算法之桶排序排序演算法
- 計數排序vs基數排序vs桶排序排序
- 基於桶的排序之計數排序排序
- 資料結構(python) —— 【18排序: 桶排序】資料結構Python排序
- 三分鐘搞懂桶排序排序
- rust-algorithms:3-桶排序RustGo排序
- 【JS面試向】選擇排序、桶排序、氣泡排序和快速排序簡介JS面試排序
- 基於桶的排序之基數排序以及排序方法總結排序
- Elasticsearch聚合的巢狀桶如何排序Elasticsearch巢狀排序
- (戀上資料結構筆記):計數排序、基數排序 、桶排序資料結構筆記排序
- 複習資料結構:排序演算法(七)——桶排序資料結構排序演算法
- 【資料結構與演算法】非比較排序(計數排序、桶排序、基數排序)資料結構演算法排序
- 第三章:查詢與排序(下)----------- 3.20桶排序排序
- 資料結構 桶排序 基數排序MSD c++ swift 版本資料結構排序C++Swift
- 基數排序--陣列模擬桶結構排序陣列
- .net版 字串陣列桶排序演算法字串陣列排序演算法
- 資料結構與演算法——桶排序資料結構演算法排序
- 手寫演算法並記住它:桶排序演算法排序
- 排序演算法之歸併,快速,堆和桶排序演算法
- 《演算法筆記》5. 字首樹、桶排序、排序演算法總結演算法筆記排序
- 【資料結構與演算法】內部排序之五:計數排序、基數排序和桶排序(含完整原始碼)資料結構演算法排序原始碼
- 每天一道演算法題--排序之桶排序實現求排序後相鄰最大差值問題演算法排序
- 【我就瞎記記,你就瞎看看】小演算法-桶排序演算法排序
- vue全家桶Vue
- SwnoRabbit全家桶
- 漏桶、令牌桶限流的Go語言實現Go
- 山東省第六屆ACM大學生程式設計競賽-Lowest Unique Price(桶排序)ACM程式設計排序