栈与队列经典问题合集(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); } } }