關於棧和佇列的面試題

2021-08-17 19:43:37 字數 4119 閱讀 4125

1.實現乙個棧,要求實現push,pop ,min(返回最小值)的時間複雜度為o(1)

方法一:

解題思路:首先我們在之前封裝的棧結構外面再封裝一層,將其封裝為乙個最小棧, 與之前不同的是,我們在棧中存放的是乙個結構體,這個結構體中有兩個成員, 乙個是資料本身的值,另乙個為棧內所有存放元素中的最小值,這樣即可實現壓棧,出棧,取最小值操作都為o(1)

**如下:

//用當前元素值和棧內最小元素值封裝乙個結構體

typedef struct elem

elem;

//最小棧

typedef struct minstack

minstack;

//初始化最小棧

void initminstack(minstack *s)

//壓棧

void minstackpush(minstack *s, int data)

}//出棧

void minstackpop(minstack *s)

//取棧頂

int minstacktop(minstack *s)

上述方法存在缺陷,每次壓棧需壓入乙個結構體兩個資料,有些情況下,每次壓入的最小值都是相同的,重複操作,因此我們採用另一種方式。

方法二:

思路:封裝乙個結構,其中包括兩個棧,乙個棧儲存所有的資料,另乙個棧儲存最小值, 每次進來乙個值都將其壓入儲存資料的棧中,若該資料比最小值棧的棧頂元素小,也將該值壓入最小值棧中,否則不操作。出棧時,每次從資料棧中彈出乙個元素,若該元素與最小值棧的棧頂元素相同時,最小值棧也要進行出棧操作,否則不出元素,這種方式 獲取最小值更為簡單,直接取最小值棧的棧頂元素,他們的時間複雜度都為o(1)。

**如下:

//將這兩個棧封裝成乙個結構體

typedef struct minstack

minstack;

//初始化兩個棧

void initminstack(minstack *s)

//壓棧

void minstackpush(minstack *s, datatype data)

}//出棧

void minstackpop(minstack *s)

stackpop(&s->_data);

}//獲取棧頂

datatype minstacktop(minstack *s)

注意:若連續向棧中壓入相同的最小資料時,最小棧只能進行一次壓棧,而出棧時,最小棧就會將該最小值彈出來,從而導致錯誤,因此要使用這種方式,我們需要對最小棧中的每個元素的個數進行計數,當其計數為0時再出棧。**有待完善。

2.使用兩個棧實現乙個佇列

解題思路:

其中一號棧用來入佇列,二號棧用來出佇列

入佇列:直接對一號棧進行壓棧操作

出佇列:對二號棧進行出棧操作,當二號棧中沒有元素時,將一號棧的元素倒入二號棧中

取隊頭:獲取二號棧的棧頂元素,當二號棧中沒有元素時,將一號棧的元素倒入二號棧中

取隊尾:獲取一號棧的棧頂元素,當一號棧中沒有元素時,將二號棧的元素重新倒到二號棧中

**如下:

//將兩個棧封裝成乙個佇列

typedef struct queuebystack

queuebystack;

//初始化該佇列

void queuebystackinit(queuebystack *q)

//入佇列

void queuebystackpush(queuebystack *q,datatype data)

//佇列判空

int queuebystackempty(queuebystack *q)

//出佇列

void queuebystackpop(queuebystack *q)

}stackpop(&q->s2);

}//獲取隊頭

datatype queuebystackfront(queuebystack *q)

}return stacktop(&q->s2);

}//獲取隊尾

datatype queuebystackback(queuebystack *q)

}return stacktop(&q->s1);

}//求佇列中元素個數

int queuebystacksize(queuebystack *q)

3.通過兩個佇列實現乙個棧

解題思路:

入棧:哪個佇列不空就向哪個佇列進行入佇列操作

出棧:從不空的佇列向另一空佇列中倒元素,直至該佇列中剩餘乙個元素,將該元素出佇列

取棧頂:即獲取非空佇列的隊尾元素

**如下:

//將兩個佇列封裝為乙個棧

typedef struct stackbyqueue

stackbyqueue;

//初始化兩佇列

void stackbyqueueinit(stackbyqueue *s)

//入棧

void stackbyqueuepush(stackbyqueue *s,datatype data)

//對棧判空

int stackbyqueueempty(stackbyqueue *s)

//出棧

void stackbyqueuepop(stackbyqueue *s)

queuepop(&s->q1);

}else

queuepop(&s->q2);

}}//取棧頂

datatype stackbyqueuetop(stackbyqueue *s)

//獲取棧元素個數

int stackbyqueuesize(stackbyqueue *s)

4.判斷元素出棧、入棧順序的合法性。如入棧的序列(1,2,3,4,5),出棧序列為(4,5,3,2,1)

給出**:

int teststackinandoutvalid(int *in, int insize, int *out, int outsize)

//此時棧頂元素等於出棧索引指定元素,進行chuzhan

stackpop(&s);

outidx++;//出棧索引向後走一步

}//此時出棧序列中元素已全部出棧,說明序列合法

return

1;}

5.乙個陣列實現兩個棧(共享棧)

方法一:以陣列的兩端分別為兩個棧的棧底,入棧時兩個棧向中間靠攏

方法二:以陣列下標為積數的空間作為一號棧的空間,偶數下標空間作為二號棧的空間 每次入棧,棧頂向後走兩步

相比之下,方法一比方法二要好些,可以重複利用這段空間。

#define max_size 10

//在乙個陣列上搭建共享棧

typedef

struct sharedstack

sharedstack;

//初始化共享棧

void sharedstackinit(sharedstack *s)

//入棧

void sharedstackpush(sharedstack *s, datatype data,int which)

//判斷一號棧或二號棧是否為空

int sharedstackempty(sharedstack *s, int which)

//出棧

void sharedstackpop(sharedstack *s, int which)

//獲取一號棧或二號棧的棧頂

datatype sharedstacktop(sharedstack *s, int which)

//獲取一號棧或二號棧的元素個數

int sharedstacksize(sharedstack *s, int which)

測試共享棧:

void testsharedstack()

執行結果:

關於佇列和棧的幾道面試題

1 實現乙個棧,要求實現push 入棧 pop 出棧 min 返回最小值的操作 的時間複雜度為o 1 第一道題,我們需要分析,我想一般的思維肯定是想到,開闢一塊空間,進行儲存最小值,這種方法也是大家通常地一下就可以想到的。但是在這裡會有乙個問題,就是如果你的最小值在棧頂,當你pop了棧頂以後,下面的...

STL 關於棧和佇列的面試題

題目分別為 1.實現乙個棧,要求實現push 出棧 pop 入棧 min 返回最小值的操作 的時間複雜度為o 1 2.使用兩個棧實現乙個佇列。3.使用兩個佇列實現乙個棧。4.判斷元素出棧 入棧順序的合法性。如 入棧的序列 1,2,3,4,5 出棧序列為 4,5,3,2,1 是合法序列,入棧的序列 1...

棧和佇列面試題

遞迴反轉乙個棧 void reverse stack s reverse s int tmp2 s.top s.pop reverse s s.push tmp1 reverse s s.push tmp2 遞迴排序乙個棧 void sort stack s sort s int tmp2 s.to...