線性表的應用 箱子排序 桶排序 和基數排序

2021-09-24 02:30:08 字數 3261 閱讀 8584

箱子排序

箱子排序的思想簡單而言就是分配range(比如[0,9],range=10)個箱子,然後把每個相同的元素放入乙個箱子,最後把箱子連線起來得到新的有序的線性表。箱子排序是一種穩定排序,它不會改變排序前線性表中相同元素的相對次序。

雖然可以用陣列來表示箱子,但是涉及到箱子的合併(鍊錶的合併操作為θ(1)),我們使用單向鍊錶來實現使其更高效。單向鍊錶的定義實現見線性表–單向鍊錶的c++描述。

用於箱子排序的乙個結構體例子

因為使用到我們定義的鍊錶,因此用於箱子排序的型別t必須實現對成員函式operator size_t()bool operator!=()運算子的過載。另外我們還需要對型別t實現operator<<運算子的過載。

//********************====箱子排序********************====

//用於排序的乙個結構體例子

//鍊錶中的t必須擁有定義的 operator int() 和 operator!= 和 opeartor《的過載操作

struct studentrecord

string name;

//學生姓名

int score;

//學生成績

operator

int(

)const

bool

operator!=(

const studentrecord& rhs)

const};

std::ostream&

operator

<<

(std::ostream&os,

const studentrecord& sr)

使用鍊錶的多個方法進行箱子排序

//********************===binsort********************===

//用鍊錶的多個方法進行箱子排序

template

<

typename t>

void

binsort

(myextendedchainlist

& chain, size_t range)

//再把箱子中的節點鏈結成有序鍊錶

for(size_t i =

0; i < range +1;

++i)

}delete

bin;

}

如果我們在乎效率,我們可以注意到,把binsort定義為鍊錶的乙個成員函式就可以省略很多操作(如不斷inser/erase帶來的new/delete操作),提高效率且節省空間。

將箱子排序作為鍊錶的乙個成員方法

//********************===成員函式myextendedchainlist::binsort********************==

template

<

typename t>

void myextendedchainlist

::binsort

(size_t range)

//把鍊錶的節點分配到箱子中

for(

; firstnode !=

nullptr

; firstnode = firstnode-

>next)

}//把箱子中的節點收集到有序鍊錶

mychainnode

* nodeptr=

nullptr

;//節點指標

for(size_t i =

0; i < range +1;

++i)}if

(nodeptr !=

nullptr

)//排序完成

//將最後乙個箱子中最後的節點的next置空 避免部分節點形成環形鍊錶

//(因為排序後最後乙個節點可能不是原鍊錶的最後乙個節點,沒有在排序中重新賦值它的next而仍然指向原煉表中它的後繼節點)

nodeptr-

>next =

nullptr

;delete

top;

delete

bottom;

}

測試

#include

#include

intmain()

//cout << chain << endl;

//binsort(chain,10); //呼叫非成員函式版本的排序

chain.

binsort(10

);//呼叫成員函式版本的排序

cout << chain << endl;

return0;

}

結果截圖:

基數排序

基數排序是對箱子排序的一種擴充套件。與箱子排序不同,基數排序不直接對原數字排序,而是把原數字按照基數(radix)進行分解。例如把985按照十進位制基數10分解為9、8、5(985=9*102 + 8*101 + 5*100),然後分三次依此對5、8、9進行排序。這就是基數排序的思想。它僅在θ(n)的時間內,就可以對0~nc-1(c>=0,整數常量)之間的n個元素進行排序。箱子排序可以看做基數為radix=range的基數排序。

基數排序的基礎是基於箱子排序的穩定性(不改變原始線性表中相同值元素的相對次序)。我們可以先對低位次(即個位)排序,使所有元素按照個位數字排列。然後再對十位進行排序,得到的序列在十位數字相同的情況下,它們的個位數字保持有序。然後再對百位進行排序,得到的序列在百位數字相同的情況下,它們的十位、個位數字保持有序……直到排序完成。

例如我們要對0~106-1的1000個整數排序,如果使用箱子排序則基數range=radix=106,我們要分配106個箱子來裝這1000個整數,無論是時間效率還是空間效率都是不可取的。這時我們將基數設定為radix=10,則只需要進行6次range=radix=10的箱子排序即可。依此次呼叫chain.binsort(range%10)(對個位排序),chain.binsort((range%100)/10)(對十位排序),chain.binsort((range%1000)/100)(對百位排序)……

鍊錶應用 箱子排序

1 問題描述 假定乙個鍊錶中包含了乙個班級內所有學生的資訊,每個節點中含有這樣的域 學生姓名 社會保險號碼 每次作業和考試的分數以及所有作業和考試的加權總分。假定所有的分數均為0 1 0 0範圍內的整數。如果採用第 2章中所給出的任一種排序演算法對錶中的學生按分數進行排序,所需要花費的時間均為 o ...

排序。。。用於排序的線性表

shuzu.h標頭檔案 ifndef shuzu define shuzu include using namespace std define n 10 include 產生隨機數的標頭檔案.include 定義乙個順序表的結構體 struct sqlist 定義的線性表中的兩個數交換的函式 vo...

桶排序的應用

題目 在乙個無序陣列中,求取有序之後相鄰數差值最大的在乙個無序陣列中,求取有序之後相鄰數差值最大的 要求 時間複雜度為o n 且存在資料範圍特別大 即不允許使用桶排序 解法 只是借鑑了桶的概念,而並沒有使用桶排序來求取。這一次是取決於給定的陣列中的元素個數,過程如下 1 陣列的大小是n,需要準備n ...