實現資料結構中的棧 後進先出LIFO

2021-10-07 06:59:43 字數 4456 閱讀 8825

棧是什麼?如果用生活中最常見的例子,我想到是書本的放置(當然這是部分人喜歡的做法)。但是給人的感覺是非常直接的,書本整齊跨一疊在一起,放在最上面的那本最先拿走,放在最底下那本書就最後拿走,形象吧,生活中有很多後進先出的栗子,就不一一說明了,用圖來說明應該很好理解。

放在最上面的那本書的位置叫棧頂,棧頂是可變的,比如說你拿走了西遊記,那麼棧頂就是紅樓夢得位置。相對應的棧底是不可操作的一端。

棧是一種特殊的線性表,特殊之處在於只能在一端對其進行操作,把元素放到棧中,這操作叫壓棧(push),壓棧之後,棧頂指標就向上移動。把元素從棧頂彈出,這叫出棧(pop),出棧後棧頂指標向下移動。訪問棧只能從棧頂元素進行。棧是很重要的資料結構,在很多演算法都有應用,比如圖的深度優先遍歷演算法(dfs),dijkstra演算法的中轉站。

棧的實現分為兩種,一是順序棧,用陣列來實現,二是鏈式棧,用指標將結點串聯起來,與鍊錶相似,但僅能在棧頂進行操作。

先實現簡單的順序棧,順序棧簡直不要太簡單,上**:

#ifndef staticstack_h

#define staticstack_h

template

<

typename t,

int n>

class

staticstack

bool

push

(const t& obj)

// 壓棧操作,就是往陣列增加乙個元素

return ret;

}bool

pop(

)// 出棧操作

return ret;}

t top()

// 獲取棧頂元素

void

clear()

// 把棧清空

intsize()

// 獲取棧的大小

~staticstack()

};#endif

來用一下這個簡單順序棧。記住,後進先出!

#include

#include

"staticstack.h"

using

namespace std;

intmain

(int argc,

const

char

* ar**)

// 入棧的時候是 0123456789 的順序

輸出正確。ok,順序棧就可以跳過了,因為順序棧的實現依賴於原生陣列,所以在定義的時候必須給定大小,並且在使用的過程中不能動態改變其大小,這是順序棧的乙個缺點,另外,當順序棧存放的元素是類型別,那麼在定義順序棧時就會自動呼叫類的建構函式,有多少個元素就會呼叫多少次,這樣做顯然會降低效率,所以順序棧的使用相對較少。

現在重點來實現鏈式棧吧,有了順序棧的基礎,實現鏈式棧也相當容易。

直接上**:

#ifndef linkstack_h

#define linkstack_h

template

<

typename t>

class

linkstack

;mutable node header;

// 使用頭節點會方便各種操作

int m_size;

public

:linkstack()

bool

push

(const t& obj)

// 壓棧操作

else

return ret;

}bool

pop(

)// 出棧操作

else

return ret;}

t top()

const

// 獲取棧頂元素

intsize()

const

void

clear()

// 清空棧}~

linkstack()

};#endif

僅僅是實現乙個棧好像沒有什麼好玩的,順序棧操作乙個陣列,鏈式就幾個指標操作。現在用棧來實現乙個掃瞄函式,將字串中的左右符號進行匹配。舉個栗子,「( a k)」,這樣乙個看起來複雜l凌亂的字串,怎麼知道它的左右符號匹不匹配呢?人工智慧嘛,人工來數一下不就可以了嗎?good idea!簡單的數幾分鐘就應該知道結果了,要是一本書那麼多的字串怎麼來數?當然是把工作交給計算機!寫個程式來檢查左右符號是否匹配不就得了。主要注意的地方是左符號、右符號以及引號的處理,其他字元直接忽略。知道重點了,實現就容易了,說幹就幹,動手!

#include

#include

"linkstack.h"

// 需要提前準備相應的輔助函式

bool

is_left

(const

char c)

// 判斷是否為左符號

bool

is_right

(const

char c)

// 判斷是否為右符號')

||(c ==

'>')||

(c ==

']');}

bool

is_quot

(const

char c)

// 判斷是否為引號

bool

is_match

(const

char l,

const

char r)

// 進行匹配判斷')

)||((l ==

'[')

&&(r ==

']'))||

((l ==

'(r ==

'>'))

||((l ==

'\'')&&

(r ==

'\''))

||((l ==

'\"')&&

(r ==

'\"'))

;return ret;

}bool

scan_func

(const

char

* str)

// 掃瞄字串的函式

elseif(

is_right

(str[i]))

// 右符號,判斷棧是否為空

else

}elseif(

is_quot

(str[i]))

// 引號判斷

// 與棧頂元素匹配,那就將棧頂的引號出棧

elseif(

is_match

(stack.

top(

), str[i]))

}}return

(ret &&

(stack.

size()

==0))

;}intmain

(int argc,

const

char

* ar**)

] ) > "

;const

char

* str2 =

" \" \' 123 \' \" "

;const

char

* str3 =

"< 123 "

; cout << endl;

cout << str1 <<

" result of match : "

<<

(scan_func

(str1)

?" true "

:" false "

)<< endl;

cout << endl;

cout << str2 <<

" result of match : "

<<

(scan_func

(str2)

?" true "

:" false "

)<< endl;

cout << endl;

cout << str3 <<

" result of match : "

<<

(scan_func

(str3)

?" true "

:" false "

)<< endl;

return0;

}

看看輸出結果,多easy,要是用人工的智慧型來數,得花點點點時間。

C 棧 後進先出 佇列實現與解析

stack 集合類實現了 後入先出的棧 也是一種線性表 所有的插入 push 和刪除 pop 通常還有所有的訪問 都在頂部進行。queue 集合類實現了 先入先出佇列 也是一種線性表 所有的插入 enqueue 都在佇列 表 的佇列最末端 進行,所有刪除 dequeue 通常還有所有的訪問 都在佇列...

資料結構 實現棧

include include include define node len sizeof node 1 pstack ptop pstack pbottom都指向節點 typedef struct node pnode,node typedef struct stack pstack,stack...

資料結構 棧實現

棧和佇列不一樣,棧是後進先出。實現時用了陣列儲存棧,陣列大小根據內容自動擴充。廢話不多說,上 c mystack.h pragma once templateclass mystack templateint mystack getcount templatet mystack top templa...