日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

桶排序和计数排序

發布時間:2023/11/27 生活经验 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 桶排序和计数排序 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

突然想自己寫個桶排序,然后做課后題又發現了計數排序,覺得挺有趣的。不過書上都沒有給代碼,所以就自己寫了一下代碼,超級爛0 0下面先簡單介紹下這兩種排序

桶排序

桶排序,就是根據散列的思想進行數據的排序。假設有M個桶,采用最簡單的hash(key)=key,這樣無需比較,就可以把數存入相應的桶中。針對沖突排解問題,此時查找鏈的方式顯然不再適用,采用獨立鏈法,把每個桶以鏈表的形式存儲雷同元素,定義相同元素的偏序,這樣能實現排序的穩定性。桶排序完全采用了簡單的哈希策略,是比較容易理解的。同時,完全摒棄了CBA式的方式,從而可以突破復雜度O(nlogn)的界限。通過空間換時間的策略,可以達到O(n)的時間復雜度,代價是O(M+N)的額外空間。下面是對于整型數組的桶排序,代碼很爛我也沒有改,已經測試過:

 1 struct node 
 2 {
 3     node(int v = 0, node* s = NULL) :value(v), succ(s) {}
 4     int value;
 5     node* succ;
 6 };
 7 void insert(node &a, int b)//b插入到a后面
 8 {
 9     node* t = new node(b);
10     if (a.succ) t->succ = a.succ;
11     a.succ = t;
12 }
13 node* bucketSort(int* A, int n, int k)//數的范圍為[0,k)
14 {
15     node* bucket = new node[k]();
16     for (int i = 0; i < n; i++)
17         insert(bucket[A[i]],A[i]);
18     return bucket;
19 }
20 void show(node a)
21 {
22     while (a.succ)
23     {
24         a = *(a.succ);//第一個節點作為哨兵不輸出
25         cout << a.value << " ";
26     }
27 }
28 int main()
29 {
30     int A[15] = { 2,0,1,3,3,0,1,9,7,7,15,11,13,12,10};
31     node* p = bucketSort(A, 15, 16);
32     for (int i = 0; i < 16; i++)
33         show(p[i]);
34     system("pause");
35     return 0;
36 }

下面有測試例子,已經經過了測試,不過這里僅把排序的結果存入了一個申請空間的列表然后輸出,沒有進行釋放的操作,也沒有存入原數組或者另外一個數組0 0看具體的要求可以改動

計數排序

計數排序的基本策略,基于這樣的事實:一個有序序列,元素m的秩,應當等于序列中全部元素中,小于等于m的元素數量。所以計數排序算法可以歸納如下:遍歷序列,對于每個元素,再遍歷整個序列,用一個額外的數組進行計數。不難看出,時間復雜度為O(n^2)。顯然,無法接受這樣的復雜度。

可以考慮用散列的方法來降低復雜度。同樣,對于[0,k)的元素,選取M個桶,假設元素數量為n,先遍歷序列,用桶數組進行計數。隨后,每一個后面的桶的計數=前面桶的數量+它自身的計數。這樣,每個桶的數字-1就等于桶對應元素的秩。同時,也可以處理相同元素的問題,因為當元素存在其他因素的偏序時,數字也加在了桶數組的計數中,桶數組只需要從后向前輸出,就可以維持這種偏序。實現代碼如下:

 1 /*計數排序*/
 2 int* countSort(int* A,int k,int n)//[0,k)范圍內n個數
 3 {
 4     int* tmp = new int[k];
 5     int* s = new int[n];
 6     memset(tmp, 0, sizeof(int) * k);
 7     for (int i = 0; i < n; i++)//原始數組中的計數
 8         tmp[A[i]]++;
 9     for (int i = 0; i < k - 1; i++)//記錄不大于該數的數字個數
10         tmp[i + 1] += tmp[i];
11     for (int i = n - 1; i >= 0; i--)//逆序輸出
12         s[--tmp[A[i]]] = A[i];//計數哈希數組-1即為應當對應的秩,用原數組的數賦值
13     delete[] tmp;
14     return s;
15 }

代碼已經經過了測試。可以看到,只需要兩趟原數組遍歷,一趟桶數組遍歷即可完成,時間復雜度為O(M+n)。同樣,輔助空間為桶數組,空間復雜度為O(M)。不難看出,計數排序適用的最合適情況,是M遠小于n的時候,即數據較多而范圍不大。此時,時間復雜度僅為O(n)。

轉載于:https://www.cnblogs.com/lustar/p/7308089.html

總結

以上是生活随笔為你收集整理的桶排序和计数排序的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。