不知道大家有沒有玩過乙個叫《拖板車》的撲克遊戲(貌似暴露了年齡。。),本篇我們嘗試讓計算機來玩這個遊戲,並且我們在確定雙方的牌和順序後就能立馬知道誰將是贏家。在玩這個遊戲前我們需要先了解下佇列和棧。佇列是一種特殊的線性結構,它只允許在佇列的首部進行刪除操作,這稱作「出隊」,而在佇列的尾部進行插入操作,這稱為「入隊"。這和我們實際生活中排隊買東西的場景一樣,先買東西的肯定是隊首的第乙個,新來的人肯定是排隊在最後面。我們稱之為先進先出(fifo)原則。
佇列的資料結構實現起來比較簡單,用乙個陣列控制先進先出即可,.net平台已經內建了這種資料結構,我們一起看一下萬能的微軟是如何實現佇列的。**較多,我們看一下關鍵部分入隊和出隊的**。
private t[
] _array;
private
int _head;
private
int _tail;
private
int _size;
private
int _version;
//出隊
public
tdequeue()
//取得隊首元素,作為返回結果
t result = _array[_head]
;//將隊首元素重置為預設值
_array[_head]
=default
(t);
//_head指向隊首下乙個元素
_head =
(_head +1)
% _array.length;
//佇列長度減一
_size--
;//版本更新
_version++
;return result;
}//入隊
public
void
enqueue
(t item)
setcapacity
(num);}
//將新元素加到陣列末尾
_array[_tail]
= item;
//_tail指向末尾後乙個索引
_tail =
(_tail +1)
% _array.length;
//佇列長度+1
_size++
; _version++
;}
棧和佇列類似,也是一種特殊的線性結構,同樣在尾部進行插入操作,但是刪除元素同樣是在隊尾,採用先進後出原則。假如我們往乙個直徑只有桌球大小的水杯分別放入2,3,1號桌球,那麼我們想要拿出2號球就必須先分別拿出1號球和3號球,這裡的水杯就是典型的棧結構。同樣地我們看下微軟關於棧的關鍵**實現。
private t[
] _array;
private
int _size;
private
int _version;
//出棧
public
tpop()
//版本+1
_version++
;//取的陣列尾部元素作為返回結果,並且長度記錄-1
t result = _array[
--_size]
;//將原來的尾部元素重置為預設值
_array[_size]
=default
(t);
return result;
}//入棧
public
void
push
(t item)
//將新元素新增到陣列尾部同時長度記錄+1
_array[_size++
]= item;
_version++
;}
將一副撲克牌隨機分為兩份,小明和小紅各乙份。小明先將手中的第一張撲克牌放在桌上,然後小紅也拿出手中的第一張牌放在小明剛打出的撲克牌上面,就像這樣兩人交替出牌。出牌時,如果某人打出的牌和桌上某張牌數字相同,即可將這兩張牌及中間所夾的牌全部收走並放到自己手牌的末尾。當其中任意一人手中牌為空的時候,遊戲結束,對手獲勝。
我們分析下這個遊戲過程,兩個人的操作都是一樣的,手裡的牌相當於乙個佇列,出牌是出隊,贏牌是入隊。而桌上的牌相當於乙個棧,出牌的時候是入棧,贏牌的時候是出棧。這樣我們的實現思路就清晰了,下面我們用程式來模擬這個遊戲。
static
void
main
(string
args)
else}}
}//然後將54張牌隨機分到小明和小紅手裡
//定義兩個佇列用來記錄小明和小紅的手牌
queue<
string
> xiaoming =
newqueue
<
string
>()
; queue<
string
> xiaohong =
newqueue
<
string
>()
;var strming =
"小明手上的牌依次為:"
;var strhong =
"小紅手上的牌依次為:"
;for
(int i =
0; i <
52; i++
)else
all.
removeat
(random);}
console.
writeline
(strming)
; console.
writeline
(strhong)
;//開始遊戲
//先定義乙個棧來記錄桌面上的牌
var stack =
newstack
<
string
>()
;while
(xiaoming.count>
0&&xiaohong.count>0)
xiaoming.
enqueue
(stack.
pop())
; console.
write
("小明贏得一輪,桌上剩餘牌為:");
foreach
(var item in stack)
console.
writeline(""
);}else
first = xiaohong.
dequeue()
;//小紅出牌
console.
writeline
("小紅出牌:"
+ first)
;//判斷桌面上是否有剛出的牌
if(stack.
contains
(first)
) xiaohong.
enqueue
(stack.
pop())
; console.
write
("小紅贏得一輪,桌上剩餘牌為:");
foreach
(var item in stack)
console.
writeline(""
);}else}if
(xiaoming.count==0)
else
console.
readkey()
;}
來看一下執行結果,輸出較多,只截了第一張和最後一張:
有趣的拖板車就到此為止啦~
歡迎關注我的演算法系列部落格:
演算法(
資料結構之棧和佇列
棧 stack 是限定僅在表尾進行插入和刪除操作的線性表。我們把允許插入和刪除的一端稱為棧頂 top 另一端稱為棧底 bottom 不含任何資料元素的棧稱為空棧。棧又稱為後進先出 last in first out 的線性表,簡稱lifo結構。棧的插入操作,叫做進棧,也稱壓棧 入棧。類似子彈入彈夾。...
資料結構之棧和佇列
棧是乙個非常常見的資料結構,它在計算機領域中被廣泛的使用,比如作業系統會給每個執行緒分配乙個棧。用來儲存函式呼叫時各個函式的引數,返回值以及臨時變數等。棧的特點是先進後出。通常棧是乙個不考慮排序的資料結構,我們需要o n 時間才能找到棧中的最大值或者最小值,如果想要在o 1 時間內找到棧中的最大值或...
資料結構之棧和佇列
讀自 資料結構 c語言版 嚴蔚敏 吳偉民 清華大學出版社 棧 棧是限定僅在表尾進行插入或刪除操作的線性表。因此對於棧來說,表尾端有其特殊含義,稱為棧頂 top 相應地,表頭端稱為棧底 bottom 不含元素的空表稱為空棧。後進先出lifo 棧的順序儲存表示 define stack init siz...