前两天实现了栈和队列,现在做两道经典的例题来巩固所学的知识。
题目链接:
目录
思路:
①构建两个栈实现队列。一个栈为input栈,只存入数据;一个栈为output栈,只负责出数据。
②当出数据时,先判断output栈是否为空(StackEmpty(&output)),如果为空,要把input栈中的数据全部导入到output栈中,然后再出output栈顶元素,再删除一个output栈中的数据。
这时我们来分析为什么要让output为空时才倒数据。

注意了!栈是先进后出哦!只有当output为空的时候才能倒数据,要不然后插入的数据会将出栈的顺序打乱。

因为我们是使用C语言做这道题,我们要自己创建栈,这点是比较麻烦的,好在是前两天我们实现了一个栈,直接拿来使用即可。
源码较长,我放在最后,可以通过目录跳转。
思路:
①一个队列存放输入的数据,一个队列专门为空,在出数据时用于保存数据。这两个队列每出一次数据时会进行功能的倒换。
②出数据时,要将存数据的队列中数据导入到空队列中,直到只留下一个数据。然后将此数据输出,如果是Pop型,输出后则将数据删除,如果是Top型,则将数据输出后再插入到倒数据队列。
步骤:
一、插入数据
如果q1为空,则q1是用于倒数据的队列,所以放入q2,反之亦然,q2为空放数据插入q1。
二、取数据
1.将除了最后一个数据之外的剩下数据全部导入到倒数据队列,然后将剩下这最后一个数据输出。
2.如果要求是Pop型,输出后则将该数据删除;如果是Top型,则将数据输出后再插入到倒数据队列。

因为C语言没有这些结构的库,我们只能手搓出栈和队列,好在前两天我们实现过栈和队列,这时我们直接将其拷贝过来然后套用既可,所以代码有点多。
- #include <stdio.h>
- #include <assert.h>
- #include <stdbool.h>
- #include <stdlib.h>
-
- typedef int STDateType;
- typedef struct Stack
- {
- STDateType* a;
- int top; //标识栈顶的数据
- int capacity; //动态性的 可以扩容
- }ST;
-
- void StackInit(ST* ps);
- void StackDestory(ST* ps);
- void StackPush(ST* ps, STDateType x);
- void StackPop(ST* ps);
- STDateType StackTop(ST* ps); //取栈顶的元素
- bool StackEmpty(ST* ps); //判断栈是否为空
- int StackSize(ST* ps); //得知栈的大小
-
-
-
- void StackInit(ST* ps)
- {
- assert(ps);
- ps->a = NULL;
- ps->top = 0;
- ps->capacity = 0;
- }
- void StackDestory(ST* ps)
- {
- assert(ps);
- free(ps->a);
- ps->a = NULL;
- ps->top = ps->capacity = 0;
- }
- void StackPush(ST* ps, STDateType x)
- {
- assert(ps);
- if (ps->capacity == ps->top)
- {
- int NewCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
- STDateType* temp = (STDateType * )realloc(ps->a, sizeof(STDateType) * NewCapacity);
- if (temp == NULL)
- {
- printf("realloc fail");
- exit(-1);
- }
- ps->a = temp;
- ps->capacity = NewCapacity;
- }
- ps->a[ps->top] = x;
- ps->top++;
- }
- void StackPop(ST* ps)
- {
- assert(ps);
- assert(!StackEmpty(ps));
- ps->top--;
- }
- STDateType StackTop(ST* ps)
- {
- assert(ps);
- assert(!StackEmpty(ps));
- return ps->a[ps->top - 1];
- }
- bool StackEmpty(ST* ps)
- {
- assert(ps);
- return ps->top == 0;
- }
- int StackSize(ST* ps)
- {
- assert(ps);
- return ps->top;
- }
-
-
- typedef struct {
- ST input; //input栈
- ST output; //output栈
- } MyQueue;
-
- //将队列创建好 并返回
- MyQueue* myQueueCreate() {
- //开辟一个结构体变量的空间
- //表示我们自己创建的结构体 MyQueue
- MyQueue* obj =(MyQueue*)malloc(sizeof(MyQueue));
- //注意,在创建一个MyQueue中,我们是创建了一个栈,如果我们调用了栈的函数,是需要将该栈的地址传入函数才能符合其类型
- StackInit(&obj->input);
- StackInit(&obj->output);
- return obj;
- }
-
- void myQueuePush(MyQueue* obj, int x) {
- //将数据放入input栈
- StackPush(&obj->input,x);
- }
-
- int myQueuePop(MyQueue* obj) {
- //将数据弹出
- //如果output空,则表示出数据栈为空,则要导数据
- if(StackEmpty(&obj->output))
- {
- //直到input为空
- while(!StackEmpty(&obj->input))
- {
- //将input的数据放入output
- //插入一个 Pop一个
- StackPush(&obj->output,StackTop(&obj->input));
- StackPop(&obj->input);
- }
- }
- int ret=StackTop(&obj->output);
- StackPop(&obj->output);
- return ret;
- }
-
- bool myQueueEmpty(MyQueue* obj) {
- //两个栈为空,即队列为空
- return (StackEmpty(&obj->input)&& StackEmpty(&obj->output));
- }
-
- int myQueuePeek(MyQueue* obj) {
- //如果队列为空
- if (myQueueEmpty(obj))
- {
- return -1;
- }
- if(StackEmpty(&obj->output))
- {
- while(!StackEmpty(&obj->input))
- {
- //将input的数据放入output
- StackPush(&obj->output,StackTop(&obj->input));
- StackPop(&obj->input);
- }
- }
- return StackTop(&obj->output);
- }
-
-
-
- void myQueueFree(MyQueue* obj) {
- StackDestory(&obj->input);
- StackDestory(&obj->output);
- free(obj);
- }
- #include <stdio.h>
- #include <stdbool.h>
- #include <stdlib.h>
- #include <assert.h>
-
-
- typedef int QDataType;
- typedef struct QueueNode
- {
- struct QueueNode* next;
- QDataType data;
- }QNode;
-
- typedef struct Queue
- {
- QNode* head;
- QNode* tail;
- }Queue;
- void QueueInit(Queue* pq)
- {
- assert(pq);
- pq->head = pq->tail = NULL;
- }
- void QueueDestroy(Queue* pq)
- {
- assert(pq);
-
- QNode* Dest = pq->head;
- while (Dest)
- {
- QNode* temp = Dest->next;
- free(Dest);
- Dest = temp;
- }
- pq->head = pq->tail = NULL;
- }
- void QueuePush(Queue* pq, QDataType x)
- {
- assert(pq);
- //创建一个节点
- QNode* newnode = (QNode*)malloc(sizeof(QNode));
- if (newnode == NULL)
- {
- printf("malloc fail\n");
- exit(-1);
- }
- newnode->data = x;
- newnode->next = NULL;
- //判断pq是不是一个空结点
- //如果是 则将newnode置为当前队列的第一个结点
- //如果不是 则将newnode链接到pq的下一个位置
- if (pq->tail == NULL)
- { //两个节点都指向newnode 表示此时队列中就一个元素
- pq->head = pq->tail = newnode;
- }
- else
- {
- //1.将newnode链接到tail的后面
- pq->tail->next = newnode;
- //2.将newnode置换为新的tail
- pq->tail = newnode;
- }
- }
-
- bool QueueEmpty(Queue* pq)
- {
- assert(pq);
- return pq->head == NULL;
- }
- void QueuePop(Queue* pq)
- {
- assert(pq);
- assert(!QueueEmpty(pq));
- //额外判断一下,解决如果仅剩一个结点了,pop的话导致tail为野指针
- if (pq->head->next == NULL)
- {
- free(pq->head);
- pq->head = pq->tail = NULL;
- }
- else
- {
- QNode* next = pq->head->next;
- free(pq->head);
- pq->head = next;
- }
- }
- QDataType QueueFront(Queue* pq)
- {
- assert(pq);
- assert(!QueueEmpty(pq));
- return pq->head->data;
- }
- QDataType QueueBck(Queue* pq)
- {
- assert(pq);
- assert(!QueueEmpty(pq));
- return pq->tail ->data;
- }
-
- int QueueSize(Queue *pq)
- {
- assert(pq);
- int count = 0;
- QNode* cur = pq->head;
- while (cur)
- {
- cur = cur->next;
- count++;
- }
- return count;
- }
-
-
- typedef struct {
- Queue q1; //队列1
- Queue q2; //队列2
- } MyStack;
-
-
- MyStack* myStackCreate() {
- MyStack* obj = (MyStack*)malloc(sizeof(MyStack));
- if (obj == NULL)
- {
- return 0;
- }
- //初始化这两个队列
- QueueInit(&obj->q1);
- QueueInit(&obj->q2);
- return obj;
- }
-
- bool myStackEmpty(MyStack* obj) {
- return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
- }
-
-
- void myStackPush(MyStack* obj, int x) {
- //如果q1为空,则往q2里放数据
- if (QueueEmpty(&obj->q1))
- {
- QueuePush(&obj->q2, x);
- }
- else
- {
- QueuePush(&obj->q1, x);
- }
- }
-
- int myStackPop(MyStack* obj) {
- //如果q1为空,就要从q2往q1里导数据
- if (QueueEmpty(&obj->q1))
- {
- while (!((&obj->q2)->head->next == NULL))
- {
- QueuePush(&obj->q1, QueueFront(&obj->q2));
- QueuePop(&obj->q2);
- }
- int ret = QueueFront(&obj->q2);
- QueuePop(&obj->q2);
- return ret;
- }
- else
- {
- while (!((&obj->q1)->head->next == NULL))
- {
- QueuePush(&obj->q2, QueueFront(&obj->q1));
- QueuePop(&obj->q1);
- }
- int ret = QueueFront(&obj->q1);
- QueuePop(&obj->q1);
- return ret;
- }
- }
-
- int myStackTop(MyStack* obj) {
- //如果q1为空,则是存放除栈顶数据的位置
- if (QueueEmpty(&obj->q1))
- {
- while (!((&obj->q2)->head->next == NULL))
- {
- QueuePush(&obj->q1, QueueFront(&obj->q2));
- QueuePop(&obj->q2);
- }
- int ret = QueueFront(&obj->q2);
- QueuePush(&obj->q1,ret);
- QueuePop(&obj->q2);
- return ret;
- }
- else
- {
- while (!((&obj->q1)->head->next == NULL))
- {
- QueuePush(&obj->q2, QueueFront(&obj->q1));
- QueuePop(&obj->q1);
- }
- int ret = QueueFront(&obj->q1);
- QueuePush(&obj->q2,ret);
- QueuePop(&obj->q1);
- return ret;
- }
- }
-
- void myStackFree(MyStack* obj) {
- QueueDestroy(&obj->q1);
- QueueDestroy(&obj->q2);
- free(obj);
- }