棧和佇列c語言版

2022-06-18 16:36:09 字數 3649 閱讀 9970

定義:棧是限定僅在表尾進行插入和刪除操作的線性表。

我們把允許插入和刪除的一端稱為棧頂(top),另一端稱為棧底(bottom),不含任何資料元素的棧稱為空棧。棧又稱為先進後出(last in first out)的線性表,簡稱lifo結構。

首先他是乙個線性表,棧元素具有線性關係,即前驅後繼關係。是一種特殊的線性表,定義中說的線性表的表尾進行插入和刪除操作,表尾是指棧頂,而不是棧底。特殊之處在於限制了這個線性表的插入和刪除位置,始終只在棧頂進行。這使得棧底是固定的,最先進棧的只能是在棧底。

棧的插入操作,叫做進棧,也稱壓棧、入棧。類似子彈入彈夾。

棧的刪除操作,叫做出棧,也稱出棧。如同彈夾中的子彈出來。

棧的抽象資料型別

adt 棧(stack)

data

同線性表。元素具有相同的型別,相鄰元素具有前驅和後繼關係。

operation

initstack ():初始化操作,建立乙個空棧s。

destroystack(*s):若棧存在,則銷毀它。

clearstack(*s):將棧清空。

push(*s,e):若棧s存在,插入新元素e到棧s中並成為棧頂新元素。

..........

endadt

棧的結構與實現

//棧的順序儲存結構定義

typedef struct stack;

//入棧

int push(stack *s, int e)

//出棧,若不為空用e返回其值

int pop(stack *s, int *e)

//鏈棧**結構

typedef struct stack_nodestack_node, *link_stack_ptr;

typedef struct link_stacklink_stack;

//判斷是否為空

int stack_empty(link_stack s)

//入棧

int push(link_stack *s, int e)

//出棧,用e返回其值,假設用變數p儲存要刪除的棧頂結點

int pop(link_stack *s, int *e)

兩棧共享空間

兩個棧底分別在陣列的兩端,向中間靠攏,當top+1 == top2為棧滿。

//兩棧共享空間結構

typedef struct double_stack;

//入棧時需要有個判斷是棧1還是棧2的引數

int ds_push(double_stack *s, int e, int stack_number)

//出棧

int ds_pop(double_stack *s, int *e, int stack_number)

else if (stack_number == 2)

return 1;

}

棧的應用

遞迴,例如斐波那契數列

int fbi(int i)
四則運算表示式求值

定義:佇列是之允許在一端進行插入操作,而在另一端進行刪除操作的線性表。

佇列是一種先進先出(first in first out)的線性表,簡稱fifo允許插入的一端稱為隊尾,允許刪除的一端稱為隊頭。

佇列的抽象資料型別

同樣是線性表,佇列也有類似線性表的各種操作,不同的是插入資料只能在隊尾進行,刪除資料只能在隊頭進行。

adt佇列(queue)

data

同線性表。元素具有相同的型別,相鄰元素具有前驅和後繼關係。

operation

initqueue(*q):初始化操作,建立乙個空佇列q.

destroyqueue(*q):若佇列q存在,則銷毀它.

clearqueue(*q):將佇列q清空.

gethead(q,*e):若佇列q存在且非空,用e返回佇列q的隊頭元素.

........

endadt

迴圈佇列

順序儲存的侷限性很大,使用迴圈佇列實現佇列的順序儲存。

避免當只有乙個元素時,隊頭和對尾重合使處理變得麻煩,引用兩個指標,front指標指向隊頭元素,rear指標指向對尾元素的下乙個位置。當隊列為空時,條件就是front = rear,當佇列滿時,我們修改條件,保留乙個元素空間。也就是說,佇列滿時,陣列中還有乙個空閒單元,但我們認為已經滿了。

由於rear可能比front大,也有可能比它小,所以它們可能差整整一圈。若佇列的最大尺寸為queuesize,那麼佇列滿的條件是(rear+1)%queuesize,佇列的長度分別為兩段,一段是queuesize-front,另一段是0+rear,因此通用的計算佇列長度公式為(rear-front+queuesize)%queuesize。現在迴圈佇列的**就不難了。

//迴圈佇列的順序儲存結構

typedef struct queue;

//初始化

int init_queue(queue *q)

//佇列當前的長度

int queue_length(queue q)

//入佇列

int en_queue(queue *q, int e)

//出佇列

int de_queue(queue *q, int *e)

單是順序儲存有著時間效能,陣列溢位等問題,所以還需要研究不需要擔心佇列長度的鏈式儲存結構。

佇列的鏈式儲存結構

//鏈佇列的結構

typedef struct q_nodeq_node,*queue_ptr;

typedef struct link_queue;

//入隊操作,就是在鍊錶的尾部插入結點

int en_queue(link_queue *q, int e)

//出隊操作,若隊不為空,刪除隊頭元素,用e返回其值

int de_queue(link_queue *q, int *e)

簡單總結

棧和佇列都是特殊的線性表,只不過是對插入和刪除操作做了限制。

棧(stack)是限定僅在表尾進行插入和刪除操作的線性表。

佇列(queue)是只允許在一端進行插入操作,而在另一端進行刪除操作的線性表。

它們都可以用線性表的順序儲存結構來實現,但存在一定的弊端,因此有各自的技巧來解決這個問題。

對於棧來說,如果是兩個相同資料型別的棧,則可以用陣列的兩端作為棧底的方法來讓兩個棧共享資料,最大化利用陣列空間。

對於佇列來說,為了避免陣列插入和刪除時需要移動資料,於是引入了迴圈佇列,使得隊頭和隊尾可以在陣列中迴圈變化,解決了移動資料的時間損耗,使得本來插入和刪除是o(n)的時間複雜度變成了o(1)。

當然,都可以使用鏈式儲存結構來實現,原則與線性表相同。

棧 C語言版

棧 lifo 運算所限的線性表,限制它的插入和刪除操作僅在表的一段進行。棧頂 top 插入 刪除。另一端為棧底。n 0稱為空棧,插入新元素稱為入棧 進棧。刪除稱為出棧 退棧。特點 先進後出。基本運算 初始化棧 判斷空 入棧 出棧 讀棧頂元素。順序棧儲存結構 初始化棧 stack init 判斷空 入...

棧和佇列面試題(C語言版)

1.判斷出入棧的合法性 2.使用兩個棧實現乙個佇列 思想 1.棧1中的所有資料彈到棧2中 棧2為空棧 2.再從棧2彈出所有資料,則可出現佇列的效果 預設壓資料壓到佇列1中,從佇列2出資料 typedef struct stack stack void stackinit stack p void s...

棧與佇列經典問題合集(c語言版)

棧與佇列作為資料結構中順序型別的熱門型別,近年來一直是各大公司筆試面試的常考題目型別,本次合集收錄了較為常見的棧與佇列問題,偏基礎。1.實現乙個棧,要求實現push 出棧 pop 入棧 min 返回最小值 的時間 複雜度為o 1 我們定義棧的結構體時除了棧儲存的資料data外可以額外儲存乙個min,...