最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

桶排序就是這么容易

2021-01-21 18:31 作者:JavaPub  | 我要投稿


  • 前言

  • 1.桶排序(Bucket sort)

  • 2.原理

    • 2.1.關(guān)鍵

    • 2.2.算法過程

  • 3.代碼

  • 4.擴(kuò)展閱讀


前言

聲明:參考來源互聯(lián)網(wǎng),有任何爭議可以留言。站在前人的肩上,我們才能看的更遠(yuǎn)。

本教程純手打,致力于最實(shí)用教程,不需要什么獎勵,只希望多多轉(zhuǎn)發(fā)支持。 歡迎來我公眾號,希望可以結(jié)識你,也可以催更,微信搜索:JavaPub

有任何問題都可以來談?wù)?!

如果看上一篇**計(jì)數(shù)排序,你有沒有這樣疑問,當(dāng)每個數(shù)據(jù)之間跨度過大(如從 0-2億 數(shù)字中排序 20 個數(shù)),就需要大量空間消耗。桶排序就是對計(jì)數(shù)排序**的改進(jìn)。

1.桶排序(Bucket sort)

百度百科:

桶排序 (Bucket sort)或所謂的箱排序,是一個排序算法,工作的原理是將數(shù)組分到有限數(shù)量的桶子里。每個桶子再個別排序(有可能再使用別的排序算法或是以遞歸方式繼續(xù)使用桶排序進(jìn)行排序)。桶排序是 鴿巢排序 的一種歸納結(jié)果。當(dāng)要被排序的數(shù)組內(nèi)的數(shù)值是均勻分配的時候,桶排序使用線性時間(Θ(n))。但桶排序并不是 比較排序,他不受到 O(n log n) 下限的影響。

繼續(xù) -->

桶排序是**計(jì)數(shù)排序的升級版。它利用了函數(shù)的映射關(guān)系**,高效與否的關(guān)鍵就在于這個映射函數(shù)的確定。為了使桶排序更加高效,我們需要做到這兩點(diǎn):

  1. 在額外空間充足的情況下,盡量增大桶的數(shù)量

  2. 使用的映射函數(shù)能夠?qū)⑤斎氲?N 個數(shù)據(jù)均勻的分配到 K 個桶中

同時,對于桶中元素的排序,選擇何種比較排序算法對于性能的影響至關(guān)重要。

桶排序是將待排序集合中處于同一個值域的元素存入同一個桶中,也就是根據(jù)元素值特性將集合拆分為多個區(qū)域,則拆分后形成的多個桶,從值域上看是處于有序狀態(tài)的。對每個桶中元素進(jìn)行排序,則所有桶中元素構(gòu)成的集合是已排序的。

快速排序是將集合拆分為兩個值域,這里稱為兩個桶,再分別對兩個桶進(jìn)行排序,最終完成排序。桶排序則是將集合拆分為多個桶,對每個桶進(jìn)行排序,則完成排序過程。兩者不同之處在于,快排是在集合本身上進(jìn)行排序,屬于原地排序方式,且對每個桶的排序方式也是快排。桶排序則是提供了額外的操作空間,在額外空間上對桶進(jìn)行排序,避免了構(gòu)成桶過程的元素比較和交換操作,同時可以自主選擇恰當(dāng)?shù)呐判蛩惴▽ν斑M(jìn)行排序。

2.原理

2.1.關(guān)鍵

  • 元素值域的劃分,也就是元素到桶的映射規(guī)則。映射規(guī)則需要根據(jù)待排序集合的元素分布特性進(jìn)行選擇,若規(guī)則設(shè)計(jì)的過于模糊、寬泛,則可能導(dǎo)致待排序集合中所有元素全部映射到一個桶上,則桶排序向比較性質(zhì)排序算法演變。若映射規(guī)則設(shè)計(jì)的過于具體、嚴(yán)苛,則可能導(dǎo)致待排序集合中每一個元素值映射到一個桶上,則桶排序向計(jì)數(shù)排序方式演化。

  • 排序算法的選擇,從待排序集合中元素映射到各個桶上的過程,并不存在元素的比較和交換操作,在對各個桶中元素進(jìn)行排序時,可以自主選擇合適的排序算法,桶排序算法的復(fù)雜度和穩(wěn)定性,都根據(jù)選擇的排序算法不同而不同。

2.2.算法過程

  1. 根據(jù)待排序集合中最大元素和最小元素的差值范圍和映射規(guī)則,確定申請的桶個數(shù);

  2. 遍歷待排序集合,將每一個元素移動到對應(yīng)的桶中;

  3. 對每一個桶中元素進(jìn)行排序,并移動到已排序集合中。

步驟 3 中提到的已排序集合,和步驟 1、2 中的待排序集合是同一個集合。與計(jì)數(shù)排序不同,桶排序的步驟 2 完成之后,所有元素都處于桶中,并且對桶中元素排序后,移動元素過程中不再依賴原始集合,所以可以將桶中元素移動回原始集合即可。

  • 示意圖

元素分配到不同桶中:

然后,元素在每個桶中排序:

3.代碼

基于 Java 的代碼,代碼邏輯很好理解,使用到插入排序,如果不理解,點(diǎn)擊傳送。

package?utils;

import?java.util.Arrays;

/**
?*?@author?wangshiyu?rodert
?*?@date?2020/6/21?15:13
?*?@description
?*/

public?class?BucketSort?{

????public?static?void?main(String[]?args)?throws?Exception?{
????????int[]?array?=?{2,?1,?5,?3,?4};

????????BucketSort?bucketSort?=?new?BucketSort();
????????int[]?sort?=?bucketSort.sort(array);
????????System.out.println(Arrays.toString(sort));
????}

????private?static?final?InsertSort?insertSort?=?new?InsertSort();

????public?int[]?sort(int[]?sourceArray)?throws?Exception?{
????????//?對?arr?進(jìn)行拷貝,不改變參數(shù)內(nèi)容
????????int[]?arr?=?Arrays.copyOf(sourceArray,?sourceArray.length);

????????return?bucketSort(arr,?5);
????}

????private?int[]?bucketSort(int[]?arr,?int?bucketSize)?throws?Exception?{
????????if?(arr.length?==?0)?{
????????????return?arr;
????????}

????????int?minValue?=?arr[0];
????????int?maxValue?=?arr[0];
????????for?(int?value?:?arr)?{
????????????if?(value?<?minValue)?{
????????????????minValue?=?value;
????????????}?else?if?(value?>?maxValue)?{
????????????????maxValue?=?value;
????????????}
????????}

????????int?bucketCount?=?(int)?Math.floor((maxValue?-?minValue)?/?bucketSize)?+?1;//向下取整?+?1
????????int[][]?buckets?=?new?int[bucketCount][0];

????????//?利用映射函數(shù)將數(shù)據(jù)分配到各個桶中
????????for?(int?i?=?0;?i?<?arr.length;?i++)?{
????????????int?index?=?(int)?Math.floor((arr[i]?-?minValue)?/?bucketSize);
????????????buckets[index]?=?arrAppend(buckets[index],?arr[i]);
????????}

????????int?arrIndex?=?0;
????????for?(int[]?bucket?:?buckets)?{
????????????if?(bucket.length?<=?0)?{
????????????????continue;
????????????}
????????????//?對每個桶進(jìn)行排序,這里使用了插入排序
????????????bucket?=?insertSort.sort(bucket);
????????????for?(int?value?:?bucket)?{
????????????????arr[arrIndex++]?=?value;
????????????}
????????}

????????return?arr;
????}

????/**
?????*?自動擴(kuò)容,并保存數(shù)據(jù)
?????*
?????*?@param?arr
?????*?@param?value
?????*/

????private?int[]?arrAppend(int[]?arr,?int?value)?{
????????arr?=?Arrays.copyOf(arr,?arr.length?+?1);
????????arr[arr.length?-?1]?=?value;
????????return?arr;
????}

}

class?InsertSort?{
????//插入排序
????public?int[]?sort(int[]?sourceArray)?throws?Exception?{
????????//?對?arr?進(jìn)行拷貝,不改變參數(shù)內(nèi)容
????????int[]?arr?=?Arrays.copyOf(sourceArray,?sourceArray.length);

????????//?從下標(biāo)為1的元素開始選擇合適的位置插入,因?yàn)橄聵?biāo)為0的只有一個元素,默認(rèn)是有序的
????????for?(int?i?=?1;?i?<?arr.length;?i++)?{

????????????//?記錄要插入的數(shù)據(jù)
????????????int?tmp?=?arr[i];

????????????//?從已經(jīng)排序的序列最右邊的開始比較,找到比其小的數(shù)
????????????int?j?=?i;
????????????while?(j?>?0?&&?tmp?<?arr[j?-?1])?{
????????????????arr[j]?=?arr[j?-?1];
????????????????j--;
????????????}

????????????//?存在比其小的數(shù),插入
????????????if?(j?!=?i)?{
????????????????arr[j]?=?tmp;
????????????}

????????}
????????return?arr;
????}
}

返回結(jié)果:

[1,?2,?3,?4,?5]

Arrays.copyOf() 方法理解:用于復(fù)制指定的數(shù)組內(nèi)容以達(dá)到擴(kuò)容的目的,該方法對不同的基本數(shù)據(jù)類型都有對應(yīng)的重載方法。

4.擴(kuò)展閱讀

真題:347. Top K Frequent Elements (Medium),給定一個非空的整數(shù)數(shù)組,返回其中出現(xiàn)頻率前 k 高的元素。

Given a non-empty array of integers, return the k most frequent elements.

  • 題解:

//基于桶排序求解「前?K?個高頻元素」
class?Solution?{
????public?List<Integer>?topKFrequent(int[]?nums,?int?k)?{
????????List<Integer>?res?=?new?ArrayList();
????????//?使用字典,統(tǒng)計(jì)每個元素出現(xiàn)的次數(shù),元素為鍵,元素出現(xiàn)的次數(shù)為值
????????HashMap<Integer,Integer>?map?=?new?HashMap();
????????for(int?num?:?nums){
????????????if?(map.containsKey(num))?{
???????????????map.put(num,?map.get(num)?+?1);
?????????????}?else?{
????????????????map.put(num,?1);
?????????????}
????????}
????????
????????//桶排序
????????//將頻率作為數(shù)組下標(biāo),對于出現(xiàn)頻率不同的數(shù)字集合,存入對應(yīng)的數(shù)組下標(biāo)
????????List<Integer>[]?list?=?new?List[nums.length+1];
????????for(int?key?:?map.keySet()){
????????????//?獲取出現(xiàn)的次數(shù)作為下標(biāo)
????????????int?i?=?map.get(key);
????????????if(list[i]?==?null){
???????????????list[i]?=?new?ArrayList();
????????????}?
????????????list[i].add(key);
????????}
????????
????????//?倒序遍歷數(shù)組獲取出現(xiàn)順序從大到小的排列
????????for(int?i?=?list.length?-?1;i?>=?0?&&?res.size()?<?k;i--){
????????????if(list[i]?==?null)?continue;
????????????res.addAll(list[i]);
????????}
????????return?res;
????}
}
```桶排序就是這么容易


桶排序就是這么容易的評論 (共 條)

分享到微博請遵守國家法律
资溪县| 兴化市| 昂仁县| 甘德县| 师宗县| 文山县| 交口县| 和政县| 白朗县| 喀喇沁旗| 武威市| 深圳市| 乌什县| 哈尔滨市| 宁德市| 黄龙县| 合阳县| 白沙| 麻阳| 丰台区| 武义县| 女性| 平江县| 民县| 繁昌县| 左云县| 墨脱县| 富民县| 江山市| 磐安县| 沧源| 永康市| 巴林左旗| 关岭| 阿拉善右旗| 通辽市| 盐津县| 泽普县| 齐河县| 绥阳县| 高碑店市|