1.用队列实现栈(225. 用队列实现栈 - 力扣(LeetCode))
<1>. 我们由图可以看出,如果插入一些元素之后,我们获取栈顶元素就是最后队列的最后一个元素,那我们是不是就可以把队列一的内容一个一个移动,这样直到队列只剩下一个元素之时,我们此时获得的队列元素就是栈顶的元素,如果我们再次插入5 6,那我们是插入队列一还是队列二呢,如果我们插入队列二,如何获得栈顶元素六呢?那刚才的4如果不是删除操作,那就需要把4先进队列二,再把再把5 6 接着插入队列二。那么我们这样就获得了一个规律。
我们需要两个队列,每次放入数据的时候,就把数据插入在不为空的队列,如果我们要获取栈顶数据时候,那么把这个不为空的队列放入这个空的队列,直到不为空的队列只剩下一个元素的时候,就是我们要获得的元素,如果我们要删除此时的元素,那么直接用队列的删除则可以直接删除掉。
所以我们可以开始实现操作,先实现两个队列的建立
typedef struct {
que n1;
que n2;
} MyStack;
MyStack* myStackCreate()
{
MyStack* ps=(MyStack*)malloc(sizeof(MyStack));
init(&ps->n1);
init(&ps->n2);
return ps;
}
我们建立的结构体里面包含了两个队列,队列n1,n2,
在我们最开始往进插入的时候,随便插入,一直插入那个不为空的队列,只要保证一个空,一个不为空就可以了。
void myStackPush(MyStack* ps, int x)
{
if(!empty(&ps->n1))
{
push(&ps->n1,x);
}
else{
push(&ps->n2,x);
}
}
删除的话,我们就要先进行导入操作,直至最开始不为空的那个队列只剩下一个元素。
int myStackPop(MyStack* ps)
{
que* yesem=&ps->n1;
que* noem=&ps->n2;
if(!empty(&ps->n1))
{
yesem=&ps->n2;
noem=&ps->n1;
}
while(sz(noem)>1)
{
int front=quefront(noem);
push(yesem,front);
pop(noem);
}
int front=quefront(noem);
pop(noem);
return front;
}
返回栈顶元素和刚才操作一样,只不过不用删除掉元素。当然我们也可以实现一个队列的访问队尾的函数,直接用这个函数也可以
int myStackTop(MyStack* ps)
{
if(!empty(&ps->n1))
{
return queback(&ps->n1);
}
else
{
return queback(&ps->n2);
}
}
我们想想该如何查此时的栈还有没元素,两个队列全是空的肯定是空,只有一个队列有元素,那栈就不为空。
bool myStackEmpty(MyStack* ps)
{
return empty(&ps->n1)&&empty(&ps->n2);
}
好了,奉上全部代码
typedef int innt;
typedef struct list
{
innt data;
struct list* next;
}list;
typedef struct que
{
list* head;
list* tail;
int sz;
}que;
void init(que* ps);
void push(que* ps, innt x);
void print(que* ps);
void pop(que* ps);
int quefront(que* ps);
int queback(que* ps);
bool empty(que* ps);
int sz(que* ps);
void destory(que* ps);
void init(que* ps)
{
assert(ps);
ps->head = ps->tail = NULL;
ps->sz = 0;
}
void push(que* ps, innt x)
{
assert(ps);
list* ret = (list*)malloc(sizeof(list));
if (ret == NULL)
{
perror("malloc NULL");
exit(1);
}
ret->next = NULL;
if (ps->sz == 0)
{
ret->data = x;
ps->head = ps->tail = ret;
}
else
{
ret->data = x;
ps->tail->next = ret;
ps->tail = ret;
}
ps->sz++;
}
void print(que* ps)
{
assert(ps);
//assert(!empty(ps));
list* ret = ps->head;
while (ret)
{
printf("%d->", ret->data);
ret = ret->next;
}
printf("\n");
}
void pop(que* ps)
{
assert(ps);
assert(!empty(ps));
if (ps->head == ps->tail)
{
free(ps->head);
ps->head =ps->tail= NULL;
}
else{
list* ret = ps->head->next;
free(ps->head);
ps->head = ret;
}
ps->sz--;
}
int quefront(que* ps)
{
assert(ps);
assert(ps->head!=NULL);
return ps->head->data;
}
int queback(que* ps)
{
assert(ps);
assert(ps->head!=NULL);
return ps->tail->data;
}
bool empty(que* ps)
{
assert(ps);
return (ps->sz == 0);
}
int sz(que* ps)
{
assert(ps);
return ps->sz;
}
void destory(que* ps)
{
assert(ps);
list* ret = ps->head;
while (ret)
{
list* wln = ret->next;
free(ret);
ret = wln;
}
ps->head = ps->tail = NULL;
ps->sz = 0;
}
typedef struct {
que n1;
que n2;
} MyStack;
MyStack* myStackCreate()
{
MyStack* ps=(MyStack*)malloc(sizeof(MyStack));
init(&ps->n1);
init(&ps->n2);
return ps;
}
void myStackPush(MyStack* ps, int x)
{
if(!empty(&ps->n1))
{
push(&ps->n1,x);
}
else{
push(&ps->n2,x);
}
}
int myStackPop(MyStack* ps)
{
que* yesem=&ps->n1;
que* noem=&ps->n2;
if(!empty(&ps->n1))
{
yesem=&ps->n2;
noem=&ps->n1;
}
while(sz(noem)>1)
{
int front=quefront(noem);
push(yesem,front);
pop(noem);
}
int front=quefront(noem);
pop(noem);
return front;
}
int myStackTop(MyStack* ps)
{
if(!empty(&ps->n1))
{
return queback(&ps->n1);
}
else
{
return queback(&ps->n2);
}
}
bool myStackEmpty(MyStack* ps)
{
return empty(&ps->n1)&&empty(&ps->n2);
}
void myStackFree(MyStack* ps)
{
destory(&ps->n1);
destory(&ps->n2);
free(ps);
}