栈的基础操作
https://blog.csdn.net/hansionz/article/details/81636557
队列的基础操作
https://blog.csdn.net/hansionz/article/details/81636644
栈和队列面试题(c语言实现)
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).
思路:
/**************************************************************/
//1.获取最小值(O(1))
typedef struct GetMinStack
{
Stack _mst;//存放正常入栈序列
Stack _msmin;//存放最小值
}GetMinStack;
//入栈操作
void Stack_O1Push(GetMinStack* ps, DataType x);
//出栈操作
void Stack_O1Pop(GetMinStack* ps);
//获取最小值
DataType GetMinValue(GetMinStack* ps);
//取栈顶元素
DataType GetStack_O1Top(GetMinStack* ps);
void Stack_O1Push(GetMinStack* ps, DataType x)
{
assert(ps);
//存放数据的栈无论如何必须压栈
StackPush(&ps->_mst, x);
//如果存放最小值那个栈栈顶元素大于x或者是那个栈还为空,必须压栈
if ((StackTop(&ps->_msmin) > x) || (StackEmpty(&ps->_msmin) == 0))
{
StackPush(&ps->_msmin, x);
}
}
void Stack_O1Pop(GetMinStack* ps)
{
assert(ps);
//比较两个栈顶元素是否相同,如果相同都出栈,如果不相同,只出数据栈
if (StackTop(&ps->_mst) == StackTop(&ps->_msmin))
{
StackPop(&ps->_msmin);
}
StackPop(&ps->_mst);
}
DataType GetMinValue(GetMinStack* ps)
{
assert(ps);
return StackTop(&ps->_msmin);
}
DataType GetStack_O1Top(GetMinStack* ps)
{
assert(ps);
return StackTop(&ps->_mst);
}
2.使用两个栈实现一个队列
思路:
typedef struct QueueBy2Stack
{
Stack input;//实现入队的栈
Stack output;//实现出队的栈
}QueueBy2Stack;
//初始化函数
void QueueInit(QueueBy2Stack* pq);
//销毁函数
void QueueDestroy(QueueBy2Stack* pq);
//入队函数
void QueuePush(QueueBy2Stack* pq, DataType x);
//出队函数
void QueuePop(QueueBy2Stack* pq);
//取队头元素函数
DataType QueueFront(QueueBy2Stack*pq);
//求队列大小
int QueueSize(QueueBy2Stack* pq);
//判断队列是否为空,空返回0,非空返回1
int QueueEmpty(QueueBy2Stack* pq);
/****************************************************************/
/*两个栈实现一个队列*/
void QueueInit(QueueBy2Stack* pq)
{
assert(pq);
StackInit(&pq->input);
StackInit(&pq->output);
}
void QueueDestroy(QueueBy2Stack* pq)
{
assert(pq);
StackDestroy(&pq->input);
StackDestroy(&pq->output);
}
void QueuePush(QueueBy2Stack* pq, DataType x)
{
assert(pq);
//把output栈所有元素拿到input栈
while (StackEmpty(&pq->output))
{
DataType tmp;
tmp = StackTop(&pq->output);
StackPop(&pq->output);
StackPush(&pq->input, tmp);
}
//然后入栈既入队
StackPush(&pq->input, x);
}
void QueuePop(QueueBy2Stack* pq)
{
assert(pq);
//把input栈所有元素拿到output栈
while (StackEmpty(&pq->input))
{
DataType tmp;
tmp = StackTop(&pq->input);
StackPop(&pq->input);
StackPush(&pq->output, tmp);
}
//然后出栈相当于出队
StackPop(&pq->output);
}
DataType QueueFront(QueueBy2Stack*pq)
{
assert(pq);
while (StackEmpty(&pq->input))
{
DataType tmp;
tmp = StackTop(&pq->input);
StackPop(&pq->input);
StackPush(&pq->output, tmp);
}
//和pop一样只不过这里变成取栈顶
return StackTop(&pq->output);
}
int QueueSize(QueueBy2Stack* pq)
{
assert(pq);
return StackSize(&pq->input) + StackSize(&pq->output);
}
//空返回0,非空返回1
int QueueEmpty(QueueBy2Stack* pq)
{
assert(pq);
return StackEmpty(&pq->input) | StackEmpty(&pq->output);
}
3.使用两个队列实现一个栈
思路:
typedef struct StackBy2Queue
{
Queue queue1;
Queue queue2;
int size;//有效元素的个数
}StackBy2Queue;
//初始化函数
void StackInit(StackBy2Queue* ps);
//销毁函数
void StackDestroy(StackBy2Queue* ps);
//入栈操作函数
void StackPush(StackBy2Queue* ps, DataType x);
//出栈操作函数
void StackPop(StackBy2Queue* ps);
//取栈顶元素函数
DataType StackGetTop(StackBy2Queue* ps);
//求栈的大小
int StackSize(StackBy2Queue* ps)
//判断栈是否为空,空返回0,非空返回1
int StackEmpty(StackBy2Queue* ps)
/***************************************************************/
/*两个队列实现一个栈*/
//初始化栈
void StackInit(StackBy2Queue* ps)
{
assert(ps);
QueueInit(&ps->queue1);
QueueInit(&ps->queue2);
ps->size = 0;
}
//销毁栈
void StackDestroy(StackBy2Queue* ps)
{
assert(ps);
QueueDestroy(&ps->queue1);
QueueDestroy(&ps->queue2);
ps->size = 0;
}
//入栈操作
void StackPush(StackBy2Queue* ps, DataType x)
{
assert(ps);
//两个队列都为空,插入哪一个都行,有一个队列不为空,就插入那个队列
if (QueueSize(&ps->queue1) != 0)
{
QueuePush(&ps->queue1, x);
}
else
{
QueuePush(&ps->queue2, x);
}
ps->size++;
}
//出栈操作
void StackPop(StackBy2Queue* ps)
{
assert(ps);
//空栈
if (ps->size == 0)
{
return;
}
//确定那个队列为空,那个不为空
Queue* _Have = &ps->queue1;//有元素
Queue* _NoHave = &ps->queue2;//没有元素
if (QueueSize(&ps->queue1) == 0)
{
_Have = &ps->queue2;
_NoHave = &ps->queue1;
}
//不为空的队列保留一个元素,最后出队既是出栈
while (QueueSize(_Have)!=1)
{
DataType tmp;
tmp = QueueFront(_Have);
QueuePop(_Have);
QueuePush(_NoHave, tmp);
}
QueuePop(_Have);
ps->size--;
}
//取栈顶元素
DataType StackGetTop(StackBy2Queue* ps)
{
assert(ps);
//空栈
if (ps->size == 0)
{
return;
}
Queue* _Have = &ps->queue1;//有元素
Queue* _NoHave = &ps->queue2;//没有元素
if (QueueSize(&ps->queue1) == 0)
{
_Have = &ps->queue2;
_NoHave = &ps->queue1;
}
//直接返回队尾元素或者是下面的做法(移到另一个队列,取队头)
return QueueBack(_Have);
#if 0
while (QueueSize(_Have) != 1)
{
DataType tmp;
tmp = QueueFront(_Have);
QueuePop(_Have);
QueuePush(_NoHave, tmp);
}
DataType cur = QueueFront(_Have);
QueuePop(_Have);
QueuePush(_NoHave, cur);
return cur;
#endif
}
int StackSize(StackBy2Queue* ps)
{
assert(ps);
return QueueSize(&ps->queue1) + QueueSize(&ps->queue2);
}
//空 返回0,非空返回1
int StackEmpty(StackBy2Queue* ps)
{
assert(ps);
return QueueEmpty(&ps->queue1) | QueueEmpty(&ps->queue2);
}
4.元素出栈、入栈的合法性。如入栈的序列(1,2,3,4,5),出栈序列为(4,5,3,2,1)
思路:
/*************************************************************/
/*检查出入栈的合法性,合法返回1,不合法返回0*/
int CheckLegal(int* num_in, int* num_out,int len_in,int len_out)
{
Stack s;
StackInit(&s);
//如果两个出入栈序列长度不相同必然不合法
if (len_in != len_out)
{
return 0;
}
assert(num_in);
assert(num_out);
int j = 0;
for (int i = 0; i < len_in; i++)
{
StackPush(&s, num_in[i]);
//栈顶元素和出栈序列相同则出栈一次,出栈序列向后移动一位
//不相同则继续入栈入栈序列
while ((StackEmpty(&s) != 0) && (StackTop(&s) == num_out[j]))
{
StackPop(&s);
j++;
}
}
return StackEmpty(&s) == 0 ? 1 : 0;
}
5.一个数组实现两个共享栈
思路:
第一种用于有缺陷,这里就不实现了。只实现第二种和第三种方式。
第二种实现方式:
#define MAXSIZE 10
typedef struct StackShare
{
DataType* _a;
int top_low;//左栈栈顶
int top_high;//右栈栈顶
}StackShare;
//初始化栈
void StackShareInit(StackShare* ps);
//销毁栈
void StackShareDestroy(StackShare* ps);
//检查栈是否满
int StackIsFull(StackShare* ps);
//检查共享栈是否为空
int StackShareEmpty(StackShare* ps, char c);
//求栈的大小
int StackShareSize(StackShare* ps, char c);
//入栈操作
void StackSharePush(StackShare* ps, DataType x, char c);
//出栈操作
void StackSharePop(StackShare* ps, char c);
//取栈顶元素
DataType StackShareTop(StackShare* ps, char c);
/***************************************************************/
/*共享栈,‘L’代表左栈,‘R’代表右栈(静态实现)*/
//初始化栈
void StackShareInit(StackShare* ps)
{
assert(ps);
memset(ps->_a, sizeof(DataType)*MAXSIZE, 0);
ps->top_high = MAXSIZE - 1;
ps->top_low = 0;
}
//销毁栈
void StackShareDestroy(StackShare* ps, char c)
{
assert(ps);
assert((c == 'R' || (c == 'L')));
if (c == 'L')
{
ps->top_low = 0;
}
else
{
ps->top_high = 0;
}
}
//判断栈是否为空,空返回0,非空返回1
int StackShareEmpty(StackShare* ps, char c)
{
assert(ps);
assert((c == 'R' || (c == 'L')));
//左栈
if (c == 'L')
{
return ps->top_low == 0 ? 0 : 1;
}
//右栈
else
{
return ps->top_high == MAXSIZE - 1 ? 0 : 1;
}
}
//栈的大小
int StackShareSize(StackShare* ps, char c)
{
assert(ps);
assert((c == 'R' || (c == 'L')));
if (c == 'L')
{
return ps->top_low;
}
else
{
return MAXSIZE - 1 - ps->top_high;
}
}
//入栈
void StackSharePush(StackShare* ps, DataType x, char c)
{
assert(ps);
assert((c == 'R' || (c == 'L')));
if (StackIsFull(ps))
{
printf("StackFull\n");
return;
}
if (c == 'L')
{
ps->_a[ps->top_low] = x;
ps->top_low++;
}
else
{
ps->_a[ps->top_high] = x;
ps->top_high--;
}
}
//出栈
void StackSharePop(StackShare* ps, char c)
{
assert(ps);
assert((c == 'R' || (c == 'L')));
if (c == 'L')
{
if (StackShareEmpty(ps, c))
{
ps->top_low--;
}
else
{
printf("StackEmpty\n");
}
}
else
{
if (StackShareEmpty(ps, c))
{
ps->top_high++;
}
else
{
printf("StackEmpty\n");
}
}
}
//取栈顶元素
DataType StackShareTop(StackShare* ps, char c)
{
assert(ps);
assert((c == 'R' || (c == 'L')));
if (c == 'L')
{
return ps->_a[ps->top_low - 1];
}
else
{
return ps->_a[ps->top_high + 1];
}
}
//判断栈是否满,满返回1,不满返回0
int StackIsFull(StackShare* ps)
{
assert(ps);
if (ps->top_low <= ps->top_high)
{
return 0;
}
else
{
return 1;
}
}
第二种实现方式(奇偶栈):
/******************************************************/
/*5.一个数组实现一个共享栈(奇偶栈)*/
//初始化共享栈(动态实现)
void ShareStackInit(ShareStack* ps)
{
assert(ps);
ps->_a = (DataType*)malloc(sizeof(DataType)* 3);
ps->_top_l = 0;
ps->_top_r = 1;
ps->capacity = 3;
}
//销毁共享栈
void ShareStackDestroy(ShareStack* ps, char c)
{
assert(ps);
assert(c == 'L' || c == 'R');
if (c == 'L')
{
ps->_top_l = 0;
if (ps->_top_r == 1)
{
free(ps->_a);
ps->_a = NULL;
ps->capacity = 0;
}
}
else
{
ps->_top_r = 1;
if (ps->_top_l == 0)
{
free(ps->_a);
ps->_a = NULL;
ps->capacity = 0;
}
}
}
//入栈
void ShareStackPush(ShareStack* ps, DataType x, char c)
{
assert(ps);
assert(c == 'L' || c == 'R');
if (c == 'L')
{
if (ps->_top_l >= ps->capacity)
{
DataType* tmp = realloc(ps->_a, (sizeof(DataType)* (2 * ps->capacity)));
if (tmp != NULL)
{
ps->_a = tmp;
}
ps->capacity *= 2;
}
ps->_a[ps->_top_l] = x;
ps->_top_l += 2;
}
else
{
if (ps->_top_r >= ps->capacity)
{
DataType* tmp = realloc(ps->_a, 2 * (ps->capacity));
if (tmp != NULL)
{
ps->_a = tmp;
}
ps->capacity *= 2;
}
ps->_a[ps->_top_r] = x;
ps->_top_r += 2;
}
}
//出栈
void ShareStackPop(ShareStack* ps, char c)
{
assert(ps);
assert(c == 'L' || c == 'R');
if (c == 'L')
{
if (ps->_top_l == 0)
{
printf("StackEmpty\n");
return;
}
ps->_top_l -= 2;
}
else
{
if (ps->_top_r == 0)
{
printf("StackEmpty\n");
return;
}
ps->_top_r -= 2;
}
}
取栈顶元素
DataType ShareStackTop(ShareStack* ps, char c)
{
assert(ps);
assert(c == 'L' || c == 'R');
if (c == 'L')
{
return ps->_a[ps->_top_l - 2];
}
else
{
return ps->_a[ps->_top_r - 2];
}
}
//为空返回0,非空返回1
int ShareStackEmpty(ShareStack* ps, char c)
{
assert(ps);
assert(c == 'L' || c == 'R');
if (c == 'L')
{
return ps->_top_l == 0 ? 0 : 1;
}
else
{
return ps->_top_r == 1 ? 0 : 1;
}
}
//求栈的大小
int ShareStackSize(ShareStack* ps, char c)
{
assert(ps);
assert(c == 'L' || c == 'R');
if (c == 'L')
{
return ps->_top_l / 2;
}
else
{
return ps->_top_r / 2;//向下取整
}
}