撲克牌排序:基於基數排序的方法
拿到這個問題,我首先想到的是:一個完全不懂程式設計的人碰到這個問題,他會怎麼做? 我覺得,一般人會把根據花色分成四堆,然後分別排序(這裡怎麼排每個人就會有不同的方法了),最後再收集起來。這個思想就很類似於基數排序了。
基數排序是比較穩定而且相對高效率的排序演算法。於是我就用基數排序實現了。
先根據點數分成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;
}
相關文章
- 用SQL實現撲克牌排序SQL排序
- 用C實現撲克牌排序排序
- 用Java實現撲克牌排序Java排序
- 用C#實現撲克牌排序C#排序
- 基於桶的排序之基數排序以及排序方法總結排序
- 編碼也快樂活動:撲克牌排序排序
- 編碼也快樂!撲克牌排序JAVA排序Java
- 用cpp0.5實現撲克牌排序排序
- 撲克牌排序-Scala之畫蛇添足版排序
- 編碼也快樂:撲克牌排序 - Python排序Python
- 編碼也快樂活動:撲克牌排序(JavaScript)排序JavaScript
- 撲克牌排序(JS版) 編碼也快樂!排序JS
- 基於桶的排序之計數排序排序
- 計數排序、桶排序和基數排序排序
- Java第三季撲克牌作業 參考了幕友的排序方法 非常感謝Java排序
- 基數排序排序
- 桶排序和基數排序排序
- 基於 SplPriorityQueue 實現的排序方法排序
- 計數排序vs基數排序vs桶排序排序
- 排序演算法__基數排序排序演算法
- 歸併排序和基數排序排序
- java 基數排序Java排序
- Python程式設計基礎練習——撲克牌發牌問題Python程式設計
- 排序(2)--選擇排序,歸併排序和基數排序排序
- 【筆記】基數排序筆記排序
- 基數排序 LSD py排序
- 基數排序的簡單理解排序
- 【演算法】基數排序演算法排序
- (戀上資料結構筆記):計數排序、基數排序 、桶排序資料結構筆記排序
- 【資料結構與演算法】非比較排序(計數排序、桶排序、基數排序)資料結構演算法排序
- 【YOLOv5】實現撲克牌的點數識別YOLO
- 看動畫學演算法之:排序-基數排序動畫演算法排序
- 拓撲排序排序
- 三言兩語說清【基數排序】與【計數排序】排序
- java程式:簡易撲克牌遊戲Java遊戲
- 撲克牌速算24 -窮舉(JavaScript)JavaScript
- [基礎訓練]數列排序排序
- 基於勝率矩陣的PageRank排序矩陣排序