資料結構之佇列和棧

2021-09-28 21:58:06 字數 4068 閱讀 2202

不知道大家有沒有玩過乙個叫《拖板車》的撲克遊戲(貌似暴露了年齡。。),本篇我們嘗試讓計算機來玩這個遊戲,並且我們在確定雙方的牌和順序後就能立馬知道誰將是贏家。在玩這個遊戲前我們需要先了解下佇列和棧。

佇列是一種特殊的線性結構,它只允許在佇列的首部進行刪除操作,這稱作「出隊」,而在佇列的尾部進行插入操作,這稱為「入隊"。這和我們實際生活中排隊買東西的場景一樣,先買東西的肯定是隊首的第乙個,新來的人肯定是排隊在最後面。我們稱之為先進先出(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...