本篇博客列举和实现了关于栈和队列的一些面试题:
1.实现一个栈,要求实现Push(出栈)、pop(入栈)、Min(返回最小值)的时间复杂度为O(1)
2.使用两个栈实现一个队列
3.使用两个队列实现一个栈
4.元素出栈,入栈的合法性。如入栈的序列(1,2,3,4,5),出栈序列为(4,5,3,2,1)
5.一个数组实现两个栈(共享栈)
实现:
1.实现一个栈,要求实现Push(出栈)、pop(入栈)、Min(返回最小值)的时间复杂度为O(1)
通过封装一个结构体,结构体中第一个元素放值,第二个元素放最小值,将结构体放入到栈中,这样返回最小值的时候从栈顶取结构体,再从结构体中取出最小值,代码实现如下:
头文件:
typedef int MSDataType;
//结构体,第一个元素放值,第二个元素放最小值
typedef struct SElem
{
MSDataType _data;
MSDataType _mindata;
}SElem;
//栈里放的元素为结构体SElem
typedef struct MinStack
{
Stack _s;
}MinStack;
//初始化
void MStackInit(MinStack* ms);
//入栈
void MStackPush(MinStack* ms, MSDataType data);
//出栈
void MStackpop(MinStack* ms);
//判断栈是否为空
int MStackEmpty(MinStack* ms);
//取栈顶元素
MSDataType MStackTop(MinStack* ms);
//取出最小的元素
MSDataType GetMinData(MinStack* ms);
//栈的大小
MSDataType MStackSize(MinStack* ms);
源文件:
//栈的初始化
void MStackInit(MinStack* ms)
{
assert(ms);
StackInit(&ms->_s);
}
//入栈
void MStackPush(MinStack* ms, MSDataType data)
{
assert(ms);
SElem elem;
//先把元素的值和最小值用data构造好
elem._data = elem._mindata = data;
if (!StackEmpty(&ms->_s))
{
//取栈里面的最小值
MSDataType minData = GetMinData(ms);
//若最小值比放入的数据小进行更新
if (minData < data)
{
elem._mindata = minData;
}
}
//将elem压栈
StackPush(&ms->_s, elem);
}
//出栈
void MStackpop(MinStack* ms)
{
assert(ms);
assert(!MStackEmpty(ms));
StackPop(&ms->_s);
}
//判断栈是否为空
int MStackEmpty(MinStack* ms)
{
assert(ms);
return StackEmpty(&ms->_s);
}
//取栈顶元素
MSDataType MStackTop(MinStack* ms)
{
assert(ms);
return StackTop(&ms->_s)._data;
}
//取栈的大小
MSDataType MStackSize(MinStack* ms)
{
assert(ms);
return StackSize(&ms->_s);
}
//取最小值
MSDataType GetMinData(MinStack* ms)
{
assert(ms);
return StackTop(&ms->_s)._mindata;
}
2.使用两个栈实现一个队列
头文件:
typedef int QDataType;
//用两个栈来封装一个队列
typedef struct QueueBy2Stack
{
Stack _s1;
Stack _s2;
}QueueBy2Stack;
//队列初始化
void QueueBy2StackInit(QueueBy2Stack* q);
//入队列
void QueueBy2StackPush(QueueBy2Stack* q,QDataType data);
//出队列
void QueueBy2StackPop(QueueBy2Stack* q);
//取队头
QDataType QueueBy2StackFront(QueueBy2Stack* q);
//取队尾
QDataType QueueBy2StackBack(QueueBy2Stack* q);
//队列大小
int QueueBy2StackSize(QueueBy2Stack* q);
//检测队列是否为空
int QueueBy2StackEmpty(QueueBy2Stack* q);
源文件:
//队列初始化
void QueueBy2StackInit(QueueBy2Stack* q)
{
assert(q);
//将两个栈初始化
StackInit(&q->_s1);
StackInit(&q->_s2);
}
//入队列
void QueueBy2StackPush(QueueBy2Stack* q, QDataType data)
{
assert(q);
//将元素放到第一个栈中
StackPush(&q->_s1, data);
}
//出队列
void QueueBy2StackPop(QueueBy2Stack* q)
{
assert(q);
assert(!QueueBy2StackEmpty(q));
//第二个栈为空时,当第一个栈非空时就将第一个栈里的数据倒到第二个栈里面
if (StackEmpty(&q->_s2))
{
while (!StackEmpty(&q->_s1))
{
StackPush(&q->_s2, StackTop(&q->_s1));
StackPop(&q->_s1);
}
}
StackPop(&q->_s2);
}
//取队头
QDataType QueueBy2StackFront(QueueBy2Stack* q)
{
assert(q);
assert(!QueueBy2StackEmpty(q));
//第二个栈为空时,当第一个栈非空时就将第一个栈里的数据倒到第二个栈里面
if (StackEmpty(&q->_s2))
{
while (!StackEmpty(&q->_s1))
{
StackPush(&q->_s2, StackTop(&q->_s1));
StackPop(&q->_s1);
}
}
//第二个栈的栈顶元素就是队头
return StackTop(&q->_s2);
}
//取队尾
QDataType QueueBy2StackBack(QueueBy2Stack* q)
{
assert(q);
//若第一个栈为空时,第二个栈非空,就把第二个栈里的元素倒到第一个栈中
if (StackEmpty(&q->_s1))
{
while (!StackEmpty(&q->_s2))
{
StackPush(&q->_s1, StackTop(&q->_s2));
StackPop(&q->_s2);
}
}
//第一个栈的栈顶就是队尾
return StackTop(&q->_s1);
}
//大小
int QueueBy2StackSize(QueueBy2Stack* q)
{
assert(q);
//两个栈里面元素之和
return StackSize(&q->_s1) + StackSize(&q->_s2);
}
//队列是否为空
int QueueBy2StackEmpty(QueueBy2Stack* q)
{
assert(q);
//当两个栈都为空时,队列也就为空了
return StackEmpty(&q->_s1) && StackEmpty(&q->_s2);
}
3.使用两个队列实现一个栈
头文件:
#include"Queue.h"
typedef struct StackBy2Queueq
{
Queue q1;
Queue q2;
}StackBy2Queue;
void StackBy2QueueInit(StackBy2Queue* s);
void StackBy2QueuePush(StackBy2Queue* s, DataType data);
void StackBy2QueuePop(StackBy2Queue* s);
DataType StackBy2QueueTop(StackBy2Queue* s);
int StackBy2QueueSize(StackBy2Queue* s);
int StackBy2QueueEmpty(StackBy2Queue* s);
源文件
//初始化
void StackBy2QueueInit(StackBy2Queue* s)
{
assert(s);
QueueInit(&s->q1);
QueueInit(&s->q2);
}
//入栈
void StackBy2QueuePush(StackBy2Queue* s, DataType data)
{
assert(s);
//将元素放入第一个队列中
QueuePush(&s->q1, data);
}
//出栈
void StackBy2QueuePop(StackBy2Queue* s)
{
assert(s);
assert(!StackBy2QueueEmpty(s));
//如果第一个队列非空,就只给第一个队列中留一个元素,
//其他元素都倒到第二个队列中,取出第一个队列中的那个元素
if (!QueueEmpty(&s->q1))
{
while (QueueSize(&s->q1) > 1)
{
QueuePush(&s->q2, QueueFront(&s->q1));
QueuePop(&s->q1);
}
QueuePop(&s->q1);
}
//如果第一个队列为空,就就只给第二个队列中留一个元素,
//其他元素都倒到第一个队列中,取出第二个队列中的那个元素
else
{
while (QueueSize(&s->q2) > 1)
{
QueuePush(&s->q1, QueueFront(&s->q2));
QueuePop(&s->q2);
}
QueuePop(&s->q2);
}
}
//取栈顶元素
DataType StackBy2QueueTop(StackBy2Queue* s)
{
assert(s);
assert(!StackBy2QueueEmpty(s));
//如果第一个队列非空,就取第一个队列的队头,否则取第二个队列的队头
if (!QueueEmpty(&s->q1))
return QueueBack(&s->q1);
else
return QueueBack(&s->q2);
}
//栈的大小
int StackBy2QueueSize(StackBy2Queue* s)
{
assert(s);
return QueueSize(&s->q1) + QueueSize(&s->q2);
}
//是否为空
int StackBy2QueueEmpty(StackBy2Queue* s)
{
assert(s);
return QueueEmpty(&s->q1) && QueueEmpty(&s->q2);
}
4.元素出栈,入栈的合法性
int IsValidStack(int* In, int InSize, int* Out, int OutSize)
{
Stack s;
StackInit(&s);
int InIdex = 0;
int OutIdex = 0;
//如果两个数组的大小都不一致,一定不合法
if (InSize != OutSize)
return 0;
while (OutIdex < OutSize)
{
//当栈为空时或者栈顶元素不等于出栈队列时进行入栈
while (StackEmpty(&s) || StackTop(&s) != Out[OutIdex])
{
if (InIdex < InSize)
StackPush(&s, In[InIdex++]);
//当没有元素可以入栈时,而且栈顶元素不等于出栈顺序,证明出栈顺序错误
else
return 0;
}
//当栈顶元素等于出栈顺序时进行出栈
StackPop(&s);
OutIdex++;
}
return 1;
}
5.共享栈
头文件
#define MAXSIZE 10
//利用数组实现一个共享栈,第一个栈是从前往后入栈,第二栈的元素从后往前放
typedef struct SharedStack
{
int _array[MAXSIZE];
int _top1;
int _top2;
}SharedStack;
void SharedStackInit(SharedStack* s);
// 入栈
void SharedStackPush(SharedStack* s, int data, int which);
// 出栈
void SharedStackPop(SharedStack* s, int which);
// 获取栈顶元素
int SharedStackTop(SharedStack* s, int which);
// 有效元素的个数
int SharedStackSize(SharedStack* s, int which);
// 检测栈是否为空
int SharedStackEmpty(SharedStack* s, int which);
源文件:
void SharedStackInit(SharedStack* s)
{
s->_top1 = 0;
s->_top2 = MAXSIZE - 1;
}
// 入栈
void SharedStackPush(SharedStack* s, int data, int which)
{
if (s->_top2 < s->_top1)
return;
if (1 == which)
s->_array[s->_top1++] = data;
else
s->_array[s->_top2--] = data;
}
// 出栈
void SharedStackPop(SharedStack* s,int which)
{
if (SharedStackEmpty(s, which))
return;
if (1 == which)
s->_top1--;
else
s->_top2++;
}
// 获取栈顶元素
int SharedStackTop(SharedStack* s, int which)
{
assert(!SharedStackEmpty(s, which));
if (1 == which)
return s->_array[s->_top1 - 1];
else
return s->_array[s->_top2 + 1];
}
// 有效元素的个数
int SharedStackSize(SharedStack* s,int which)
{
if (1 == which)
return s->_top1;
else
return MAXSIZE-s->_top2-1;
}
// 检测栈是否为空
int SharedStackEmpty(SharedStack* s,int which)
{
if (1 == which)
return 0 == s->_top1;
else
return MAXSIZE-1 == s->_top2;
}