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...