一、题目链接:. - 力扣(LeetCode)
二、题解代码
//支持动态增长的栈
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top; // 栈顶
int capacity; // 容量
}Stack;
// 初始化栈
void StackInit(Stack* ps);
//入栈
void StackPush(Stack* ps, STDataType data);
// 出栈
void StackPop(Stack* ps);
// 获取栈顶元素
STDataType StackTop(Stack* ps);
// 获取栈中有效元素个数
int StackSize(Stack* ps);
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
int StackEmpty(Stack* ps);
// 销毁栈
void StackDestroy(Stack* ps);
//初始化栈
void StackInit(Stack* ps)
{
assert(ps);
ps->a = NULL;
ps->capacity =0; //将容量初始化为0
ps->top =0; //栈顶位置初始化为0
}
//入栈
void StackPush(Stack* ps, STDataType data)
{
assert(ps);
if (ps->capacity == ps->top) //当容量等于栈顶的的标识,说明要进行扩容增加容量
{
int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
STDataType* p = (STDataType*)realloc(ps->a, sizeof(STDataType) * newcapacity);
if (p == NULL)
{
perror("realloc fail");
return;
}
ps->a = p;
ps->capacity = newcapacity;
}
ps->a[ps->top] = data;
ps->top++; //入栈一次,栈顶位置加1
}
//出栈
void StackPop(Stack* ps)
{
assert(ps);
int ret= StackEmpty(ps);
if (ret != 0)
{
return;
}
ps->top--; //出栈一次,栈顶位置减1
}
//获取栈顶元素
STDataType StackTop(Stack* ps)
{
assert(ps);
int ret = StackEmpty(ps);
if (ret != 0)
{
return -1;
}
int n = ps->top-1; //取栈顶元素,它所在的是第top个,数组下标是top-1
return ps->a[n];
}
//获取栈中有效元素个数
int StackSize(Stack* ps)
{
assert(ps);
return ps->top;
}
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
int StackEmpty(Stack* ps)
{
assert(ps);
return ps->top == 0;//top是0,就会返回1.不是0,就会返回0
}
// 销毁栈
void StackDestroy(Stack* ps)
{
assert(ps);
ps->top = ps->capacity = 0;
free(ps->a);
ps->a = NULL;
}
typedef struct
{
Stack A;
Stack B;
} MyQueue;
//初始化
MyQueue* myQueueCreate();
//入队
void myQueuePush(MyQueue* obj, int x);//入队在有元素的地方
//出队
int myQueuePop(MyQueue* obj);
//取队头元素
int myQueuePeek(MyQueue* obj);
//判断是否为空
bool myQueueEmpty(MyQueue* obj);
//销毁队列
void myQueueFree(MyQueue* obj);
//初始化
MyQueue* myQueueCreate()
{
MyQueue* myQueue = (MyQueue*)malloc(sizeof(MyQueue));
if (myQueue == NULL)
{
perror("malloc fail");
return NULL;
}
StackInit(&myQueue->A);//初始化A栈
StackInit(&myQueue->B);//初始化B栈
return myQueue;
}
//入队
void myQueuePush(MyQueue * obj, int x)//入队在有元素的地方
{
if (!StackEmpty(&obj->A))//如果A栈不为空
{
StackPush(&obj->A, x);//元素入A栈
}
else //如果A栈为空,元素入B栈
{
StackPush(&obj->B, x);//元素入B栈
}
}
//出队
int myQueuePop(MyQueue * obj)
{
//假设法
Stack *Empty = &obj->A; //先假设A为空,B为非空
Stack *NoEmpty =&obj->B;
if (!StackEmpty(&obj->A))//如果A栈不为空,交换Empty 和NoEmpty
{
Empty = &obj->B; //先假设A为空,B为非空
NoEmpty =& obj->A;
}
while (!StackEmpty(NoEmpty))//将非空的栈(NoEmpty)里的元素依次出栈,并入栈到空栈(Empty)里面
{
STDataType temp = StackTop(NoEmpty);//取栈顶元素
StackPop(NoEmpty);//栈顶元素出栈
StackPush(Empty, temp);//将出栈的元素,入栈到空栈中
}
//将(NoEmpty)栈中的元素依次转到(Empty)栈中,这时的状态变了((Empty)栈有元素,(NoEmpty)栈无元素)
STDataType fist = StackTop(Empty);//取这时(Empty)栈(现在有元素了)的栈顶元素,
StackPop(Empty);//栈顶元素出栈,也就是队列的队头元素
//将(Empty)栈中的元素依次还给(NoEmpty)栈,回到之前的状态((Empty)栈无元素,(NoEmpty)栈有元素)
while (!StackEmpty(Empty))//将非空的栈里的元素依次出栈,并入栈到空栈里面
{
STDataType temp = StackTop(Empty);//取栈顶元素
StackPop(Empty);//栈顶元素出栈
StackPush(NoEmpty, temp);//将出栈的元素,入栈到(NoEmpty)中
}
return fist;//将队列的队头元素返回
}
//取队头元素
int myQueuePeek(MyQueue * obj)
{
//假设法
Stack NoEmpty;//先假设B为非空,
if (!StackEmpty(&obj->A))//如果A栈不为空,交换Empty 和NoEmpty
{
NoEmpty = obj->A; //先假设A为空,B为非空
}
else
NoEmpty = obj->B;
while (StackSize(&NoEmpty) > 1)//将非空的栈(NoEmpty)里的元素依次出栈,并入栈到空栈(Empty)里面,
//留下最后一个
{
STDataType temp = StackTop(&NoEmpty);//取栈顶元素
StackPop(&NoEmpty);//栈顶元素出栈
}
STDataType fist = StackTop(&NoEmpty);//取这时(NoEmpty)栈
StackPop(&NoEmpty);//栈顶元素出栈
return fist;//将队列的队头元素返回
}
//判断是否为空
bool myQueueEmpty(MyQueue * obj)
{
if (obj->A.top == 0 && obj->B.top == 0)//两个栈都是空,说明队列为空了
return true;
else
return false;
}
//销毁队列
void myQueueFree(MyQueue * obj)
{
StackDestroy(&obj->A);//销毁A栈
StackDestroy(&obj->B);//销毁B栈
free(obj);//释放申请的myQueue
}
三、思路方法
1.有两个队列,每次 元素进栈的时候 插入数据在已经有数据的队列之中
假设有数据的是A队列,没有元素的是B队列
2.元素出栈时,就是将有将存储了数据的队列(A队列)里面的元素依次出队列,
并依次入队列到另一个开始没存储数据的队列(B队列)中,
但是要留下最后一个元素在A队列,这时候就将A队列的那个最后的数据出队返回,这就是我们要的栈顶元素
这时A队列为空,B队列有数据。
循环执行以上的操作