計(jì)數(shù)排序算法

學(xué)號(hào):20021211189? ? ? ?姓名:趙治偉

【嵌牛導(dǎo)讀】計(jì)數(shù)排序(Counting sort)是一種非基于比較的排序算法,其核心在于將輸入的數(shù)據(jù)值轉(zhuǎn)化為鍵存儲(chǔ)在額外開辟的數(shù)組空間中以達(dá)到排序的效果。

【嵌牛鼻子】計(jì)數(shù)排序算法

【嵌牛正文】

1.算法原理

給定一組取值范圍為0到9的無序序列:1慰枕、7诉濒、4胀糜、9垢油、0壕探、5飘诗、2与倡、4、7昆稿、3纺座、4,建立一個(gè)長(zhǎng)度為10的計(jì)數(shù)數(shù)組溉潭,值初始化為0

遍歷無序序列净响,將每個(gè)序列元素值對(duì)應(yīng)的計(jì)數(shù)數(shù)組下標(biāo)的元素加1

如:第一個(gè)序列元素為1,則計(jì)數(shù)數(shù)組中下標(biāo)為1的元素加1

第二個(gè)序列元素為7岛抄,計(jì)數(shù)數(shù)組中下標(biāo)為7的元素加1

繼續(xù)遍歷序列别惦,當(dāng)序列遍歷完畢,計(jì)數(shù)數(shù)組的最終狀態(tài)如下:

遍歷計(jì)數(shù)數(shù)組夫椭,輸出計(jì)數(shù)數(shù)組下標(biāo)值掸掸,元素的值是多少,就輸出幾次

輸出結(jié)果如下:0蹭秋、1扰付、2、3仁讨、4羽莺、4、4洞豁、5盐固、7、7丈挟、9

此時(shí)刁卜,元素已是有序的了

2.算法實(shí)現(xiàn)

// 計(jì)數(shù)排序

function sort(arr) {

? ? // 得到數(shù)列的最大值

? ? let max = arr[0];

? ? for (let item of arr) {

? ? ? ? if (item > max) {

? ? ? ? ? ? max = item;

? ? ? ? }

? ? }

? ? // 初始化數(shù)組

? ? let countArr = [];

? ? for (let i = 0; i <= max; i++) {

? ? ? ? countArr[i] = 0;

? ? }

? ? // 遍歷原始數(shù)組,填充計(jì)數(shù)數(shù)組

? ? for (let item of arr) {

? ? ? ? countArr[item]++;

? ? }

? ? // 遍歷計(jì)數(shù)數(shù)組曙咽,得到排序后結(jié)果

? ? let index = 0;

? ? let sortArr = [];

? ? for (let i = 0; i <= max; i++) {

? ? ? ? for (let j = 0; j < countArr[i]; j++) {

? ? ? ? ? ? sortArr[index++] = i;

? ? ? ? }

? ? }

? ? return sortArr;

}

let arr = [1, 7, 4, 9, 0, 5, 2, 4, 7, 3, 4];

let sortArr = sort(arr);

console.log(sortArr);

算法優(yōu)化

在前面的例子中蛔趴,我們以序列的最大值來確定計(jì)數(shù)數(shù)組長(zhǎng)度,假設(shè)有一個(gè)序列83例朱、80孝情、88鱼蝉、90、88箫荡、86魁亦,那么我們創(chuàng)建一個(gè)長(zhǎng)度為91的計(jì)數(shù)數(shù)組,計(jì)數(shù)數(shù)組的0到79位都浪費(fèi)了

我們可以創(chuàng)建一個(gè)長(zhǎng)度為90-80+1=11(最大值-最小值+1)的計(jì)數(shù)數(shù)組菲茬,計(jì)數(shù)數(shù)組的偏移量為序列的最小值80

如圖:計(jì)數(shù)數(shù)組下標(biāo)0對(duì)應(yīng)序列80吉挣,下標(biāo)1對(duì)應(yīng)序列81,以此類推

此外婉弹,我們前面的例子中睬魂,我們?cè)谛陆ǖ挠?jì)數(shù)數(shù)組中記錄序列中每個(gè)元素的數(shù)量,如果序列有相同的元素镀赌,則在輸出時(shí)氯哮,無法保證元素原來的排序,是一種不穩(wěn)定的排序算法商佛,可通過優(yōu)化喉钢,將其改為穩(wěn)定排序算法

以序列83、80良姆、88肠虽、90、88玛追、86為例税课,首先填充計(jì)數(shù)數(shù)組

將計(jì)數(shù)數(shù)組從第二個(gè)元素開始,每個(gè)元素都加上前面所有元素的和痊剖,此時(shí)韩玩,計(jì)數(shù)數(shù)組的值表示的是元素在序列中的排序

接下來我們創(chuàng)建輸出數(shù)組,長(zhǎng)度與待排序序列一致陆馁,從后往前遍歷待排序序列

首先找颓,遍歷最后一個(gè)元素86,我們?cè)谟?jì)數(shù)數(shù)組中找到86對(duì)應(yīng)的值為3叮贩,則在輸出數(shù)組的第3位(下標(biāo)為2)填入86击狮,計(jì)數(shù)數(shù)組86對(duì)應(yīng)的值減1,既當(dāng)前的86排序是3益老,下次遇到86則排序是2

接著帘不,遍歷下一個(gè)元素88,在計(jì)數(shù)數(shù)組中找到88對(duì)應(yīng)的值為5杨箭,在輸出數(shù)組的第5位(下標(biāo)為4)填入88,計(jì)數(shù)數(shù)組88對(duì)應(yīng)的值減1

然后储狭,遍歷下一個(gè)元素90互婿,在計(jì)數(shù)數(shù)組中找到90對(duì)應(yīng)的值為6捣郊,在輸出數(shù)組的第6位(下標(biāo)為5)填入90,計(jì)數(shù)數(shù)組90對(duì)應(yīng)的值減1

繼續(xù)遍歷下一個(gè)元素88慈参,在計(jì)數(shù)數(shù)組中找到88對(duì)應(yīng)的值為4呛牲,在輸出數(shù)組的第4位(下標(biāo)為3)填入88,計(jì)數(shù)數(shù)組88對(duì)應(yīng)的值減1

以此類推驮配,將所有元素遍歷完娘扩,填入輸出數(shù)組

原序列第3位、第5位均為88壮锻,從上面的步驟我們可以看到琐旁,在第二步,第5位的88填入輸出數(shù)組的第5位猜绣,在第四步灰殴,第3位的88填入輸出數(shù)組的第4位,沒有改變?cè)蛄邢嗤氐捻樞?/p>

優(yōu)化后代碼如下:

// 計(jì)數(shù)排序優(yōu)化

function sort(arr) {

? ? // 得到數(shù)列的最大值掰邢、最小值牺陶,并計(jì)算計(jì)數(shù)數(shù)組長(zhǎng)度

? ? let max = arr[0];

? ? let min = arr[0];

? ? for (let item of arr) {

? ? ? ? if (item > max) {

? ? ? ? ? ? max = item;

? ? ? ? }

? ? ? ? if (item < min) {

? ? ? ? ? ? min = item;

? ? ? ? }

? ? }

? ? let length = max - min + 1;

? ? // 初始化計(jì)數(shù)數(shù)組

? ? let countArr = [];

? ? for (let i = 0; i < length; i++) {

? ? ? ? countArr[i] = 0;

? ? }

? ? // 遍歷原始數(shù)組,填充計(jì)數(shù)數(shù)組

? ? for (let item of arr) {

? ? ? ? countArr[item - min]++;

? ? }

? ? // 計(jì)數(shù)數(shù)組形變辣之,后面的元素等于前面的元素之和

? ? let sum = 0;

? ? for (let i = 0; i < length; i++) {

? ? ? ? sum += countArr[i];

? ? ? ? countArr[i] = sum;

? ? }

? ? console.log(11111111, countArr);

? ? // 倒序遍歷計(jì)數(shù)數(shù)組掰伸,從計(jì)數(shù)數(shù)組中找到正確位置,輸入到輸出數(shù)組

? ? let sortArr = [];

? ? for (let i = arr.length - 1; i >= 0; i--) {

? ? ? ? sortArr[countArr[arr[i] - min] - 1] = arr[i];

? ? ? ? countArr[arr[i] - min]--;

? ? ? ? console.log(arr[i], countArr, sortArr);

? ? }

? ? return sortArr;

}

let arr = [83, 80, 88, 90, 88, 86];

let sortArr = sort(arr);

console.log(sortArr);

計(jì)數(shù)排序算法特點(diǎn)

1.時(shí)間復(fù)雜度

計(jì)數(shù)排序算法遍歷了3次原始數(shù)組怀估,一次計(jì)數(shù)數(shù)組狮鸭,所以算法的時(shí)間復(fù)雜度是O(N+M)

2.空間復(fù)雜度

計(jì)數(shù)排序算法排序過程中新建了一個(gè)計(jì)數(shù)數(shù)組和一個(gè)輸出數(shù)組,所以算法的空間復(fù)雜度是O(N+M)

3.穩(wěn)定性

優(yōu)化后的計(jì)數(shù)排序算法在排序過程中奏夫,相同元素的前后順序不會(huì)發(fā)生改變怕篷,是一種穩(wěn)定排序算法

4.局限性

當(dāng)待排序序列的最大值和最小值差值特別大時(shí),不適合使用計(jì)數(shù)排序算法

當(dāng)待排序序列的值不是整數(shù)時(shí)酗昼,不適合使用計(jì)數(shù)排序算法

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末廊谓,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子麻削,更是在濱河造成了極大的恐慌蒸痹,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件呛哟,死亡現(xiàn)場(chǎng)離奇詭異叠荠,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)扫责,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門榛鼎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事者娱÷樟” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵黄鳍,是天一觀的道長(zhǎng)推姻。 經(jīng)常有香客問我,道長(zhǎng)框沟,這世上最難降的妖魔是什么藏古? 我笑而不...
    開封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮忍燥,結(jié)果婚禮上拧晕,老公的妹妹穿的比我還像新娘。我一直安慰自己灾前,他們只是感情好防症,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著哎甲,像睡著了一般蔫敲。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上炭玫,一...
    開封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天奈嘿,我揣著相機(jī)與錄音,去河邊找鬼吞加。 笑死裙犹,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的衔憨。 我是一名探鬼主播叶圃,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼践图!你這毒婦竟也來了掺冠?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤码党,失蹤者是張志新(化名)和其女友劉穎德崭,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體揖盘,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡眉厨,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了兽狭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片憾股。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鹿蜀,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出荔燎,到底是詐尸還是另有隱情耻姥,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布有咨,位于F島的核電站,受9級(jí)特大地震影響蒸健,放射性物質(zhì)發(fā)生泄漏座享。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一似忧、第九天 我趴在偏房一處隱蔽的房頂上張望渣叛。 院中可真熱鬧,春花似錦盯捌、人聲如沸淳衙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽箫攀。三九已至,卻和暖如春幼衰,著一層夾襖步出監(jiān)牢的瞬間靴跛,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來泰國打工渡嚣, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留梢睛,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓识椰,卻偏偏與公主長(zhǎng)得像绝葡,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子腹鹉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容