目录
一、栈
1.1栈的概念及结构
1.2栈的实现
二、队列
2.1队列的概念
2.2队列的实现
三、循环队列
3.1循环队列
3.2循环队列的实现
四、两栈实现队列+两队列实现栈
4.1两栈实现队232. 用栈实现队列 - 力扣(LeetCode)
4.1两队列实现栈225. 用队列实现栈 - 力扣(LeetCode)
五、栈和队列小题
//Stack.h
#pragma once
#include
#include
#include
#include
// 支持动态增长的栈
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);
//Stack.c
#define _CRT_SECURE_NO_WARNINGS
#include"Stack.h"
// 初始化栈
void StackInit(Stack* ps) {
assert(ps);
ps->_a = NULL;
ps->_capacity = 0;
ps->_top = 0; //可以直接插入,指向下一个
}
// 销毁栈
void StackDestroy(Stack* ps) {
assert(ps);
free(ps->_a);
ps->_a = NULL;
ps->_capacity = ps->_top = 0;
}
// 入栈
void StackPush(Stack* ps, STDataType data) {
assert(ps);
if (ps->_capacity == ps->_top) {
int newcapacity = ps->_capacity == 0 ? 4 : 2 * ps->_capacity;
Stack* temp = (Stack*)realloc(ps->_a, sizeof(Stack) * newcapacity);
if (!temp) {
perror("realloc fail or malloc fail");
exit(-1);
}
ps->_a = temp;
ps->_capacity = newcapacity;
}
ps->_a[ps->_top] = data;
ps->_top++;
}
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
int StackEmpty(Stack* ps) {
assert(ps);
return ps->_top == 0;
}
//检查栈是否已满
int StackFull(Stack* ps) {
assert(ps);
return ps->_capacity < ps->_top - 1 ? 0 : 1;
}
// 出栈
void StackPop(Stack* ps) {
assert(ps);
assert(!StackEmpty(ps));
ps->_top--;
}
// 获取栈顶元素
STDataType StackTop(Stack* ps) {
assert(ps);
assert(!StackEmpty(ps));
return ps->_a[ps->_top - 1];
}
// 获取栈中有效元素个数
int StackSize(Stack* ps) {
assert(ps);
return ps->_top;
}
//Queue.h
#pragma once
#include
#include
#include
#include
// 链式结构:表示队列
typedef int QDataType;
typedef struct QListNode
{
struct QListNode* _next;
QDataType _data;
}QNode;
// 队列的结构
typedef struct Queue
{
QNode* _front;
QNode* _rear;
}Queue;
// 初始化队列
void QueueInit(Queue* q);
// 队尾入队列
void QueuePush(Queue* q, QDataType data);
// 队头出队列
void QueuePop(Queue* q);
// 获取队列头部元素
QDataType QueueFront(Queue* q);
// 获取队列队尾元素
QDataType QueueBack(Queue* q);
// 获取队列中有效元素个数
int QueueSize(Queue* q);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Queue* q);
// 销毁队列
void QueueDestroy(Queue* q);
//Queue.c
#define _CRT_SECURE_NO_WARNINGS
#include"Queue.h"
// 初始化队列
void QueueInit(Queue* q) {
assert(q);
q->_front = NULL;
q->_rear = NULL;
}
// 队尾入队列
void QueuePush(Queue* q, QDataType data) {
assert(q);
QNode* newcode = (QNode*)malloc(sizeof(QNode));
if (newcode == NULL) {
perror("malloc fail");
exit(-1);
}
else {
newcode->_data = data;
newcode->_next = NULL;
}
if (q->_rear == NULL) {
q->_front = q->_rear = newcode;
}
else {
q->_rear->_next = newcode;
q->_rear = newcode;
}
/*if (q->_rear == NULL)
{
QNode* newcode = (QNode*)malloc(sizeof(QNode));
if (newcode == NULL) {
perror("malloc fail");
exit(-1);
}
q->_rear = q->_front = newcode;
newcode->_data = data;
newcode->_next = NULL;
}
else
{
QNode* newcode = (QNode*)malloc(sizeof(QNode));
if (newcode == NULL) {
perror("malloc fail");
exit(-1);
}
q->_rear->_next = newcode;
q->_rear = newcode;
newcode->_data = data;
newcode->_next = NULL;
}*/
}
// 队头出队列
void QueuePop(Queue* q) {
assert(q);
assert(!QueueEmpty(q));
if (q->_front->_next==NULL) {
q->_front = q->_rear = NULL;
}
else {
QNode* del = q->_front;
q->_front = q->_front->_next;
free(del);
del = NULL;
}
}
// 获取队列头部元素
QDataType QueueFront(Queue* q) {
assert(q);
assert(!QueueEmpty(q));
return q->_front->_data;
}
// 销毁队列
void QueueDestroy(Queue* q) {
assert(q);
QNode* cur = q->_front;
while (cur) {
QNode* del = cur;
cur = cur->_next;
free(del);
}
q->_front = q->_rear = NULL;
}
// 获取队列队尾元素
QDataType QueueBack(Queue* q) {
assert(q);
assert(!QueueEmpty(q));
return q->_rear->_data;
}
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Queue* q) {
assert(q);
return q->_rear == NULL && q->_front == NULL;
}
// 获取队列中有效元素个数
int QueueSize(Queue* q) {
assert(q);
QNode* cur = q->_front;
int sum = 0;
while (cur) {
sum++;
cur = cur->_next;
}
return sum;
}
实际中我们有时还会使用一种队列叫循环队列。如操作系统课程讲解生产者消费者模型
注意:Q.rear指的是最后一个元素的下一个
当我们判断循环队列是否为空或者是否满时,发现Q.rear和Q.front相等,而且不能区分,所以,我们可以多开一个空间!
如果Q.front和Q.rear相等,就是空。如果Q.rear的下一个是Q.front就是满
622. 设计循环队列 - 力扣(LeetCode)
#define _CRT_SECURE_NO_WARNINGS
typedef struct {
int* a;
int front;
int rear;
int N;
} MyCircularQueue;
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
obj->a = (int*)malloc(sizeof(int) * (k + 1));
obj->rear = obj->front = 0;
obj->N = k + 1;
return obj;
}
bool myCircularQueueIsFull(MyCircularQueue* obj) {
if ((obj->rear + 1) % obj->N == obj->front) {
return true;
}
return false;
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
if (obj->front == obj->rear) {
return true;
}
return false;
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
if (myCircularQueueIsFull(obj)) {
return false;
}
obj->a[obj->rear] = value;
obj->rear++;
obj->rear %= obj->N;
return true;
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
if (myCircularQueueIsEmpty(obj)) {
return false;
}
obj->front++;
obj->front %= obj->N;
return true;
}
int myCircularQueueFront(MyCircularQueue* obj) {
if (myCircularQueueIsEmpty(obj)) {
return -1;
}
return obj->a[obj->front];
}
int myCircularQueueRear(MyCircularQueue* obj) {
if (myCircularQueueIsEmpty(obj)) {
return -1;
}
if (obj->rear == 0) {
return obj->a[obj->N - 1];
}
return obj->a[obj->rear - 1];
}
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->a);
free(obj);
}
/**
* Your MyCircularQueue struct will be instantiated and called as such:
* MyCircularQueue* obj = myCircularQueueCreate(k);
* bool param_1 = myCircularQueueEnQueue(obj, value);
* bool param_2 = myCircularQueueDeQueue(obj);
* int param_3 = myCircularQueueFront(obj);
* int param_4 = myCircularQueueRear(obj);
* bool param_5 = myCircularQueueIsEmpty(obj);
* bool param_6 = myCircularQueueIsFull(obj);
* myCircularQueueFree(obj);
*/
思路分析:
先 push 1 2 3 4 再 pop
pop的时候,要将所有的pushST栈全部导入popST
如果再push时再存到pushST
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include
#include
// 支持动态增长的栈
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;
ps->_top = 0; //可以直接插入,指向下一个
}
// 销毁栈
void StackDestroy(Stack* ps) {
assert(ps);
free(ps->_a);
ps->_a = NULL;
ps->_capacity = ps->_top = 0;
}
// 入栈
void StackPush(Stack* ps, STDataType data) {
assert(ps);
if (ps->_capacity == ps->_top) {
int newcapacity = ps->_capacity == 0 ? 4 : 2 * ps->_capacity;
Stack* temp = (Stack*)realloc(ps->_a, sizeof(Stack) * newcapacity);
if (!temp) {
perror("realloc fail or malloc fail");
exit(-1);
}
ps->_a = temp;
ps->_capacity = newcapacity;
}
ps->_a[ps->_top] = data;
ps->_top++;
}
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
int StackEmpty(Stack* ps) {
assert(ps);
return ps->_top == 0;
}
//检查栈是否已满
int StackFull(Stack* ps) {
assert(ps);
return ps->_capacity < ps->_top - 1 ? 0 : 1;
}
// 出栈
void StackPop(Stack* ps) {
assert(ps);
assert(!StackEmpty(ps));
ps->_top--;
}
// 获取栈顶元素
STDataType StackTop(Stack* ps) {
assert(ps);
assert(!StackEmpty(ps));
return ps->_a[ps->_top - 1];
}
// 获取栈中有效元素个数
int StackSize(Stack* ps) {
assert(ps);
return ps->_top;
}
typedef struct {
Stack pushST;
Stack popST;
} MyQueue;
MyQueue* myQueueCreate() {
MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));
StackInit(&obj->pushST);
StackInit(&obj->popST);
return obj;
}
void myQueuePush(MyQueue* obj, int x) {
StackPush(&obj->pushST, x);
}
void pushSTtopopST(Stack* popST, Stack* pushST) {
while (StackSize(pushST)) {
StackPush(popST, StackTop(pushST));
StackPop(pushST);
}
}
int myQueuePop(MyQueue* obj) {
int top;
if (!StackEmpty(&obj->popST)) {
top = StackTop(&obj->popST);
StackPop(&obj->popST);
}
else {
pushSTtopopST(&obj->popST, &obj->pushST);
top = StackTop(&obj->popST);
StackPop(&obj->popST);
}
return top;
}
int myQueuePeek(MyQueue* obj) {
if (!StackEmpty(&obj->popST)) {
return StackTop(&obj->popST);
}
else {
pushSTtopopST(&obj->popST, &obj->pushST);
return StackTop(&obj->popST);
}
}
bool myQueueEmpty(MyQueue* obj) {
if (StackEmpty(&obj->popST) && StackEmpty(&obj->pushST)) {
return true;
}
return false;
}
void myQueueFree(MyQueue* obj) {
StackDestroy(&obj->popST);
StackDestroy(&obj->pushST);
free(obj);
}
/**
* Your MyQueue struct will be instantiated and called as such:
* MyQueue* obj = myQueueCreate();
* myQueuePush(obj, x);
* int param_2 = myQueuePop(obj);
* int param_3 = myQueuePeek(obj);
* bool param_4 = myQueueEmpty(obj);
* myQueueFree(obj);
*/
思路分析:
两个队列倒数据,当push时,push到有数据的队列,pop时,把有数据的队列倒入无数据的队列,只留下最后一个,这时候再pop一次就可以了。
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include
#include
// 链式结构:表示队列
typedef int QDataType;
typedef struct QListNode
{
struct QListNode* _next;
QDataType _data;
}QNode;
// 队列的结构
typedef struct Queue
{
QNode* _front;
QNode* _rear;
}Queue;
// 初始化队列
void QueueInit(Queue* q);
// 队尾入队列
void QueuePush(Queue* q, QDataType data);
// 队头出队列
void QueuePop(Queue* q);
// 获取队列头部元素
QDataType QueueFront(Queue* q);
// 获取队列队尾元素
QDataType QueueBack(Queue* q);
// 获取队列中有效元素个数
int QueueSize(Queue* q);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Queue* q);
// 销毁队列
void QueueDestroy(Queue* q);
// 初始化队列
void QueueInit(Queue* q) {
assert(q);
q->_front = NULL;
q->_rear = NULL;
}
// 队尾入队列
void QueuePush(Queue* q, QDataType data) {
assert(q);
QNode* newcode = (QNode*)malloc(sizeof(QNode));
if (newcode == NULL) {
perror("malloc fail");
exit(-1);
}
else {
newcode->_data = data;
newcode->_next = NULL;
}
if (q->_rear == NULL) {
q->_front = q->_rear = newcode;
}
else {
q->_rear->_next = newcode;
q->_rear = newcode;
}
}
// 队头出队列
void QueuePop(Queue* q) {
assert(q);
assert(!QueueEmpty(q));
if (q->_front->_next == NULL) {
q->_front = q->_rear = NULL;
}
else {
QNode* del = q->_front;
q->_front = q->_front->_next;
free(del);
del = NULL;
}
}
// 获取队列头部元素
QDataType QueueFront(Queue* q) {
assert(q);
assert(!QueueEmpty(q));
return q->_front->_data;
}
// 销毁队列
void QueueDestroy(Queue* q) {
assert(q);
QNode* cur = q->_front;
while (cur) {
QNode* del = cur;
cur = cur->_next;
free(del);
}
q->_front = q->_rear = NULL;
}
// 获取队列队尾元素
QDataType QueueBack(Queue* q) {
assert(q);
assert(!QueueEmpty(q));
return q->_rear->_data;
}
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Queue* q) {
assert(q);
return q->_rear == NULL && q->_front == NULL;
}
// 获取队列中有效元素个数
int QueueSize(Queue* q) {
assert(q);
QNode* cur = q->_front;
int sum = 0;
while (cur) {
sum++;
cur = cur->_next;
}
return sum;
}
typedef struct {
Queue p1;
Queue p2;
} MyStack;
MyStack* myStackCreate() {
MyStack* obj = (MyStack*)malloc(sizeof(MyStack));
QueueInit(&obj->p1);
QueueInit(&obj->p2);
return obj;
}
void myStackPush(MyStack* obj, int x) {
if (!QueueEmpty(&obj->p1))
{
QueuePush(&obj->p1, x);
}
else
{
QueuePush(&obj->p2, x);
}
}
int myStackPop(MyStack* obj) {
int top;
/*
Queue* empty = &obj->p1;
Queue* UNempty = &obj->p2;
if(!QueueEmpty(&obj->p1)){
empty = &obj->p2;
UNempty = &obj->p1;
}
while(QueueSize(UNempty)>1){
QueuePush(empty,QueueFront(UNempty));
QueuePop(UNempty);
}
top = QueueFront(UNempty);
QueuePop(UNempty);
*/
if (!QueueEmpty(&obj->p1)) {
while (QueueSize(&obj->p1) > 1)
{
QueuePush(&obj->p2, QueueFront(&obj->p1));
QueuePop(&obj->p1);
}
top = QueueFront(&obj->p1);
QueuePop(&obj->p1);
}
else {
while (QueueSize(&obj->p2) > 1)
{
QueuePush(&obj->p1, QueueFront(&obj->p2));
QueuePop(&obj->p2);
}
top = QueueFront(&obj->p2);
QueuePop(&obj->p2);
}
return top;
}
int myStackTop(MyStack* obj) {
if (!QueueEmpty(&obj->p1))
{
return QueueBack(&obj->p1);
}
else
{
return QueueBack(&obj->p2);
}
}
bool myStackEmpty(MyStack* obj) {
if (QueueEmpty(&obj->p1) && QueueEmpty(&obj->p2)) {
return true;
}
return false;
}
void myStackFree(MyStack* obj) {
QueueDestroy(&obj->p1);
QueueDestroy(&obj->p2);
free(obj);
}
/**
* Your MyStack struct will be instantiated and called as such:
* MyStack* obj = myStackCreate();
* myStackPush(obj, x);
* int param_2 = myStackPop(obj);
* int param_3 = myStackTop(obj);
* bool param_4 = myStackEmpty(obj);
* myStackFree(obj);
*/