栈与队列经典问题合集(c语言版)
栈与队列作为数据结构中顺序类型的热门类型,近年来一直是各大公司笔试面试的常考题目类型,本次合集收录了较为常见的栈与队列问题,偏基础。
1.
实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值)的时间
复杂度为O(1)。
我们定义栈的结构体时除了栈存储的数据data外可以额外存储一个min,这个数据代表当前栈的最小数据,当插入数据时我们将当前栈顶的min与插入数据做对比,小值存入新栈顶数据的min中,这样同时可以保证删除数据时以及可以读出当前栈的最小数据。
以下为实现代码。
定义一个含有min的栈
typedef struct DataType
{
int data;
int min;
}DataType;
typedef struct stack
{
DataType* _a;
int _size;
}Stack;
初始化
oid StackInit(Stack* st )
{
st->_a = (DataType*)malloc(1000*sizeof(DataType));
st->_size = 0;
}
打印栈
void StackPrint(Stack st)
{
int i;
if (st._size == 0)
{
printf("该栈为空!\n");
}
else
{
for (i = 0;i < st._size;i++)
{
printf("%d ",st._a[i].data);
}
}
}
插入数据
void StackPush(Stack* st, int x)
{
if (st->_size == 0)
{
st->_a[st->_size].data = x;
st->_a[st->_size].min = x;
st->_size++;
return;
}
else
{
if (x < st->_a[st->_size - 1].min)
{
x = st->_a[st->_size].min;
}
else
{
st->_a[st->_size].min = st->_a[st->_size - 1].min;
}
}
st->_a[st->_size].data=x;
st->_size++;
}
删除数据
void StackPop(Stack* st)
{
if (st->_size == 0)
{
printf("该栈为空!\n");
}
else
{
st->_size--;
}
}
以上只实现部分基础接口,更多接口同理不在赘述。
2. 使用两个栈实现一个队列
2. 使用两个栈实现一个队列
一个栈只用于插入数据(以下称进入栈),一个栈只用于出数据(以下称释放栈)。插入数据时将数据插入进入栈,释放数据时,如果释放栈没有数据了,将进入栈的数全部压入释放栈即可。读取数据时先读取进入栈在读取释放栈即可。
以下为代码实现
以下为代码实现
typedef struct StoQ
{
Stack* st1;
Stack* st2;
} StoQ;
模拟队列初始化
void StoQinit(StoQ* p)
{
StackInit(p->st1);
StackInit(p->st2);
}
模拟队列插入数据
void StoQinit(StoQ* p)
{
StackInit(p->st1);
StackInit(p->st2);
}
模拟队列删除数据
void Stackpop(StoQ* p)
{
DataType x = 0;
if (p->st2->_top==0)
{
while (p->st1->_top != 0)
{
x = p->st1->_array[(p->st1->_top) - 1];
StackPush(p->st2,x);
StackPop(p->st1);
}
}
StackPop(p->st2);
}
以上只提供部分基础接口
3.
使用两个队列实现一个栈
一个队列只增加数据,一个队列只删除数据,当需要删除数据时,将进入队列的数据全部放入释放队列,将释放队列的数据除了最后一个数据剩余全部返回进入队列,再删除释放队列的数据即可,遍历时只遍历进入队列即可。
typedef struct QtoS { Queue *q1; Queue *q2; } QtoS;
初始化
void QtoSinit(QtoS* p)
{
QueueInit(p->q1);
QueueInit(p->q2);
}
插入数据
void QtoSpush(QtoS* p, DataType x)
{
QueuePush(p->q1, x);
}
删除数据
void QtoSpop(QtoS* p)
{
if (p->q1->_head->_next == NULL)
{
return;
}
else
{
while (p->q1->_head->_next->_next != NULL)
{
QueuePush(p->q2,p->q1->_head->_data);
QueuePop(p->q1);
}
QueuePop(p->q1);
while (p->q2->_head != NULL)
{
QueuePush(p->q1, p->q2->_head->_data);
QueuePop(p->q2);
}
}
}