方法与用双栈实现队列相同,此处用双队列实现栈,除了尾节点外,把队列1的元素都放到队列2,然后队列1就只剩最后进的元素了,就可以进行各种操作了,操作后,在把队列2的元素放回队列1中。此处最麻烦的以就是链表的操作。我这里还出了一个问题,就是当free掉尾节点后,没有及时头结点的next指向NULL,这样的头结点的next就是野指针,在后面再调用头结点的next时就出现问题了。在力扣上显示这个错误:AddressSanitizer: heap-use-after-free on address 0x602000000f78 at pc 0x000000402f27 bp 0x7ffe73d07cd0 sp 0x7ffe73d07cc8
另外,从栈实现队列和队列实现栈的两个问题的解法中,学习到了一种方法,就是例如,在用队列实现栈的问题中,除了有队列的结构体外,还有一个栈的的结构体,里面放的是指向队列的指针,还有栈内元素的个数,有了这个个数,就方便判断栈空。
代码如下:
typedef struct myqueue{
int data;
struct myqueue*next;
}MyQueue;
typedef struct{
MyQueuefront;
MyQueuerear;
}LinkQueue;
typedef struct {
LinkQueue*s;
int cnt;
} MyStack;
/** Initialize your data structure here. */
MyStack* myStackCreate() {
MyStackobj=(MyStack)malloc(sizeof(MyStack));
LinkQueueQ1=(LinkQueue)malloc(sizeof(LinkQueue));
Q1->front=Q1->rear=(MyQueue*)malloc(sizeof(MyQueue));
Q1->front->next=NULL;
obj->s=Q1;
obj->cnt=0;
return obj;
}
/** Push element x onto stack. /
void myStackPush(MyStack obj, int x) {
MyQueuen=(MyQueue)malloc(sizeof(MyQueue));
n->data=x;
obj->s->rear->next=n;
obj->s->rear=n;
n->next=NULL;
obj->cnt++;
}
void QueuePush(MyStackobj,MyQueuet){
obj->s->rear->next=t;
t->next=NULL;
obj->s->rear=t;
}
/** Removes the element on top of the stack and returns that element. /
int myStackPop(MyStack obj) {
MyStackobj2=(MyStack)malloc(sizeof(MyStack));
LinkQueueQ2=(LinkQueue)malloc(sizeof(LinkQueue));
Q2->front=Q2->rear=(MyQueue*)malloc(sizeof(MyQueue));
obj2->s=Q2;
obj2->cnt=0;
Q2->front->next=NULL;
MyQueue*t=NULL,*temp=NULL;
int num;
while(obj->cnt>1)
{
t=obj->s->front->next;
obj->s->front->next=t->next;
obj->cnt–;
QueuePush(obj2,t);
obj2->cnt++;
}
temp=obj->s->front->next;
obj->s->front->next=NULL; //此处没注意到
num=temp->data;
free(temp);
obj->s->rear=obj->s->front;
obj->cnt–;
while(obj2->cnt)
{
t=obj2->s->front->next;
obj2->s->front->next=t->next;
obj2->cnt–;
QueuePush(obj,t);
obj->cnt++;
}
return num;
}
/** Get the top element. /
int myStackTop(MyStack obj) {
MyStackobj2=(MyStack)malloc(sizeof(MyStack));
LinkQueueQ2=(LinkQueue)malloc(sizeof(LinkQueue));
Q2->front=Q2->rear=(MyQueue*)malloc(sizeof(MyQueue));
obj2->s=Q2;
obj2->cnt=0;
Q2->front->next=NULL;
MyQueue*t=NULL,*temp=NULL;
int num;
while(obj->cnt>1)
{
t=obj->s->front->next;
obj->s->front->next=t->next;
obj->cnt–;
QueuePush(obj2,t);
obj2->cnt++;
}
//把队列obj剩下的那个放入obj2里
t=obj->s->front->next;
num=t->data;
obj->s->front->next=t->next;
obj->cnt–;
QueuePush(obj2,t);
obj2->cnt++;
obj->s->rear=obj->s->front;
while(obj2->cnt)
{
t=obj2->s->front->next;
obj2->s->front->next=t->next;
obj2->cnt–;
QueuePush(obj,t);
obj->cnt++;
}
return num;
}
/** Returns whether the stack is empty. /
bool myStackEmpty(MyStack obj) {
return !obj->cnt;
}
void myStackFree(MyStack* obj) {
MyQueue*temp1=obj->s->front,temp2=NULL;
while(temp1)
{
temp2=temp1;
temp1=temp1->next;
free(temp2);
}
LinkQueueQ=obj->s;
free(Q);
free(obj);
}