基數(shù)排序(RadixSort)也是八大排序算法之一瞧筛,它在棋牌游戲中的應(yīng)用非常常見。基數(shù)排序是采用“分配”與“收集”的辦法奶陈,用對多關(guān)鍵碼進(jìn)行排序的思想實(shí)現(xiàn)對單關(guān)鍵碼進(jìn)行排序的方法怯屉。我們這里只分析在平常開發(fā)生活中會(huì)用到的場景蔚舀,而不具體去研究。
思路:使用鏈表存儲(chǔ)數(shù)據(jù)锨络,通過調(diào)整指針實(shí)現(xiàn)LSD(低關(guān)鍵字優(yōu)先)算法進(jìn)行排序赌躺。
舉個(gè)例子就是我們在qq游戲上的紙牌或麻將,從服務(wù)器端返回來一組數(shù)據(jù)羡儿,紙牌和麻將都是多關(guān)鍵字的對象礼患,紙牌和麻將都是有點(diǎn)數(shù)和花色劃分的,我們要對這組數(shù)據(jù)進(jìn)行排序,那使用鏈?zhǔn)交鶖?shù)排序效率是最快的缅叠。
而且這種排序是使用在對原始數(shù)據(jù)的排序咏瑟,如果有新數(shù)據(jù)添加進(jìn)來的話,那就使用希爾排序痪署。
以麻將為例码泞,請看圖:
(1)先初始化一個(gè)要存放的點(diǎn)數(shù)的集合數(shù)組,根據(jù)點(diǎn)數(shù)把數(shù)據(jù)放入對應(yīng)的數(shù)組中狼犯,把點(diǎn)數(shù)為1的數(shù)放入數(shù)組為0的下標(biāo)中, 點(diǎn)數(shù)為2的數(shù)據(jù)放入1的下標(biāo)中余寥,數(shù)組中每個(gè)下標(biāo)存放數(shù)據(jù)的都是一個(gè)集合,這樣就可以把數(shù)值為1~9的麻將分別存入對應(yīng)的數(shù)組中悯森。然后再把數(shù)組中的集合按順序依次添加到一個(gè)新的集合中宋舷。
(2)初始化一個(gè)存放花色的集合數(shù)組,根據(jù)花色把數(shù)據(jù)放入對應(yīng)的組中瓢姻,把花色為萬字的數(shù)據(jù)放入數(shù)組為0的下標(biāo)中祝蝠,花色為條字的數(shù)據(jù)放入數(shù)組為1的下標(biāo)中,花色為筒字的數(shù)據(jù)放入數(shù)組為2的下標(biāo)中幻碱,這樣就可以把花色為萬筒條的數(shù)據(jù)都存入對應(yīng)的數(shù)組中绎狭。最后再把數(shù)組中的集合桉樹按順序依次添加到一個(gè)新的集合當(dāng)中。
這樣就完成了麻將的排序褥傍。光說也是說不清楚的儡嘶,我們來看代碼就知道是怎么回事了。
1.先定義一個(gè)麻將的實(shí)體類:
static class Mahjong{
int suit; //花色 萬 筒 條
int rank; //點(diǎn)數(shù)大小
public Mahjong(int suit,int rank){
this.suit = suit;
this.rank = rank;
}
}
2.然后模擬一組麻將數(shù)據(jù):
SinglyLinkedList<Mahjong> list = new SinglyLinkedList<>(); //使用單鏈表恍风,因?yàn)樾首罡? list.add(new Mahjong(3,1));
list.add(new Mahjong(2,3));
list.add(new Mahjong(3,7));
list.add(new Mahjong(1,1));
list.add(new Mahjong(3,8));
list.add(new Mahjong(2,2));
list.add(new Mahjong(3,2));
list.add(new Mahjong(1,3));
list.add(new Mahjong(3,9));
radixSort(list);
這里就不打印了蹦狂,有興趣的同志可以自己參照思路進(jìn)行實(shí)現(xiàn)。
3.然后對麻將集合進(jìn)行鏈?zhǔn)交鶖?shù)排序
public static void radixSort(SinglyLinkedList<Mahjong> list){
//step1:先初始化要存放點(diǎn)數(shù)的集合數(shù)組
SinglyLinkedList[] rankList = new SinglyLinkedList[9];
for(int i=0;i<rankList.length;i++){
rankList[i] = new SinglyLinkedList(); //讓每個(gè)數(shù)組都放置單鏈表集合
}
//step2: 根據(jù)點(diǎn)數(shù)把數(shù)據(jù)放入對應(yīng)的組中 把點(diǎn)數(shù)為1放入數(shù)組0, 2的放入1......
while (list.size() > 0){
Mahjong mahjong = list.remove(); //注意這里是把數(shù)據(jù)進(jìn)行刪除朋贬,也可以用get方法凯楔,為了方便下面我直接用的刪除
rankList[mahjong.rank - 1].add(mahjong); //麻將的點(diǎn)數(shù)-1就是放入對應(yīng)的數(shù)組下標(biāo),因?yàn)槁閷⑹菑?開始的
}
//step3:把9個(gè)組的數(shù)據(jù)連接起來形成一個(gè)單鏈表锦募,這里就用原來的list進(jìn)行存儲(chǔ)摆屯,因?yàn)樯厦嬉呀?jīng)取空了
for(int i=0;i<rankList.length;i++){
list.addAll(rankList[i]);
}
//step4:初始化要存放花色的集合數(shù)組,這個(gè)邏輯和上面存放點(diǎn)數(shù)的是一樣的
SinglyLinkedList[] suitList = new SinglyLinkedList[3];
for (int i=0;i<suitList.length;i++){
suitList[i] = new SinglyLinkedList();
}
//step5:根據(jù)花色把數(shù)據(jù)放入對應(yīng)的組中御滩,花色為1放入0.鸥拧。。削解。富弦。。
while (list.size() > 0){
Mahjong mahjong = list.remove();
suitList[mahjong.suit - 1].add(mahjong);
}
//step6:把3個(gè)組的數(shù)據(jù)連接起來形成一個(gè)單鏈表氛驮,最后list存放的就是我們排好點(diǎn)數(shù)和花色的數(shù)據(jù)
for(int i=0;i<suitList.length;i++){
list.addAll(suitList[i]);
}
}
鏈?zhǔn)交鶖?shù)排序的應(yīng)用場景:斗地主紙牌游戲腕柜,麻將初始化的排序,不適用于在打麻將過程中摸一張打一張的排序。
小白總結(jié)盏缤,往大神指點(diǎn)砰蠢。