撲克牌排序:基於基數排序的方法
拿到這個問題,我首先想到的是:一個完全不懂程式設計的人碰到這個問題,他會怎麼做? 我覺得,一般人會把根據花色分成四堆,然後分別排序(這裡怎麼排每個人就會有不同的方法了),最後再收集起來。這個思想就很類似於基數排序了。
基數排序是比較穩定而且相對高效率的排序演算法。於是我就用基數排序實現了。
先根據點數分成13堆,收集起來,再根據花色分成4堆,再收集,就okay了。
值得一提的是,我必須使用連結串列來組織牌堆,因為如果用陣列的話,用基排就有“直接計算下標”的嫌疑,就犯規了;而現實中整理撲克的時候,我們的桌子上並沒有52個格子,來讓你排放撲克牌,所以用連結串列來表示還是比較符合實際情況的……實際上,這個問題其實還是直接根據牌面計算下標最快——但是規則不允許這麼做——所以我們實際上是在尋找儘可能快但是不能是最快的演算法。但是如果把問題改成“排序缺失了若干張未知牌的一副撲克”,就不存在這個問題了。而使用連結串列的基數排序仍然可以解決——所以我說了這麼多,用意其實是在於說明,我沒有犯規……
以下是C語言程式碼:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
typedef struct poker poker;
struct poker{
int suit;//0-spade, 1-heart, 2-flower, 3-box;
int number;//J-11, Q-12, K-13, A-14;
poker* next;
};
int _random(x){
srand((int)time(0));
return rand()%x;
}
poker* create_pile(){
int n, i;
int a[52];
for(i = 0; i < 52; i++)
a[i] = i;
poker* pile = 0;
for(n = 52; n > 0; n--){
int t = _random(n);
poker* p = malloc(sizeof(poker));
p->suit = a[t]/13;
p->number = a[t]%13 + 2;
p->next = pile;
pile = p;
a[t] = a[n-1];
}
return pile;
}
poker* sort(poker* pile){
poker* head[13];
poker* tail[13];
int i;
for(i = 0; i < 13; i++){
head[i] = tail[i] = 0;
}
//first round allocate;
while(pile != 0){
poker* p = pile;
pile = pile->next;
p->next = 0;
int number = p->number;
if(tail[number-2] == 0){
head[number-2] = tail[number-2] = p;
}
else{
tail[number-2]->next = p;
tail[number-2] = p;
}
}
//collect;
pile = head[0];
for(i = 0; i < 12; i++){
tail[i]->next = head[i+1];
head[i] = tail[i] = 0;
}
//second round allocate;
while(pile != 0){
poker* p = pile;
pile = pile->next;
p->next = 0;
int suit = p->suit;
if(tail[suit] == 0){
head[suit] = tail[suit] = p;
}
else{
tail[suit]->next = p;
tail[suit] = p;
}
}
//collect;
pile = head[0];
for(i = 0; i < 3; i++){
tail[i]->next = head[i+1];
head[i] = tail[i] = 0;
}
return pile;
}
int main(){
poker* pile = create_pile();
poker* p = pile;
printf("Before sorted:\n");
while(p != 0){
printf("%d, %d\n", p->suit, p->number);
p = p->next;
}
printf("=============\nAfter sorted:\n");
pile = sort(pile);
p = pile;
while(p != 0){
printf("%d, %d\n", p->suit, p->number);
p = p->next;
}
return 0;
}
相關文章
- 基於桶的排序之基數排序以及排序方法總結排序
- 基於桶的排序之計數排序排序
- 基於 SplPriorityQueue 實現的排序方法排序
- 桶排序和基數排序排序
- 計數排序vs基數排序vs桶排序排序
- Java第三季撲克牌作業 參考了幕友的排序方法 非常感謝Java排序
- 排序演算法__基數排序排序演算法
- 歸併排序和基數排序排序
- java 基數排序Java排序
- Python程式設計基礎練習——撲克牌發牌問題Python程式設計
- 基數排序 LSD py排序
- 基數排序的簡單理解排序
- 【資料結構與演算法】非比較排序(計數排序、桶排序、基數排序)資料結構演算法排序
- 【演算法】基數排序演算法排序
- (戀上資料結構筆記):計數排序、基數排序 、桶排序資料結構筆記排序
- 拓撲排序排序
- 看動畫學演算法之:排序-基數排序動畫演算法排序
- 基於勝率矩陣的PageRank排序矩陣排序
- 拓撲排序,YYDS排序
- 2018年第七週-基礎的排序方法(三種基礎排序演算法簡介)排序演算法
- Python八大演算法的實現,插入排序、希爾排序、氣泡排序、快速排序、直接選擇排序、堆排序、歸併排序、基數排序。Python演算法排序
- 【YOLOv5】實現撲克牌的點數識別YOLO
- 經典十大排序演算法(含升序降序,基數排序含負數排序)排序演算法
- C#基數排序演算法C#排序演算法
- 基數排序就這麼簡單排序
- rust-algorithms:12-基數排序RustGo排序
- 第 30 題:如何理解基數排序?排序
- 第三章:查詢與排序(下)----------- 3.21基數排序排序
- 圖論——拓撲排序圖論排序
- 筆記:拓撲排序筆記排序
- 拓撲排序小結排序
- 經常提及的幾個js排序方法(氣泡排序、選擇排序、計數排序)JS排序
- 撲克牌速算24 -窮舉(JavaScript)JavaScript
- JZ-045-撲克牌順子
- 劍指Offer 撲克牌順子
- 八大排序演算法—16張圖搞懂基數排序排序演算法
- 資料結構與演算法——排序演算法-基數排序資料結構演算法排序
- 基於AI排序演算法的指數增強策略【附原始碼】AI排序演算法原始碼
- Reward (圖論+拓撲排序)圖論排序