0
点赞
收藏
分享

微信扫一扫

LeetCode —— 栈和队列相关的oj题(含循环队列)

_LEON_ 2022-04-14 阅读 85

目录

一、用队列实现栈

1.题干分析

2.动图解析 

3.代码实现

二、有效的括号

1.题干分析 

2.动图解析 

3.代码实现 

三、用栈实现队列 

1.题干分析 

2.动图解析 

3.代码实现 

四、设计循环队列 

1.题干分析 

2.代码实现

①数组实现

②链表实现


一、用队列实现栈

1.题干分析

2.动图解析 

3.代码实现

typedef int QDataType;

typedef struct QueueNode
{
struct QueueNode* next;
QDataType data;
}QueueNode;

typedef struct Queue
{
QueueNode* head;
QueueNode* tail;
}Queue;

//队列的初始化
void QueueInit(Queue* pq);

//队列的销毁
void QueueDestroy(Queue* pq);

//队尾入队列
void QueuePush(Queue* pq, QDataType x);

// 队头出队列
void QueuePop(Queue* pq);

//取队头的数据
QDataType QueueFront(Queue* pq);

//取队尾的数据
QDataType QueueBack(Queue* pq);

//计算有多少个数据
int QueueSize(Queue* pq);

//判断队列是否为空
bool QueueEmpty(Queue* pq);

//队列的初始化
void QueueInit(Queue* pq)
{
assert(pq);
pq->head = NULL;
pq->tail = NULL;
}

//队列的销毁
void QueueDestroy(Queue* pq)
{
assert(pq);
QueueNode* cur = pq->head;
while (cur != NULL)
{
QueueNode* next = cur->next;
free(cur);
cur = next;
}
pq->head = pq->tail = NULL;
}

//队尾入队列(尾插)
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
newnode->data = x;
newnode->next = NULL;
if (pq->head == NULL)
{
pq->head = pq->tail = newnode;
}
else
{
pq->tail->next = newnode;
pq->tail = newnode;
}
}

// 队头出队列(删除数据)
void QueuePop(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
QueueNode* next = pq->head->next;
free(pq->head);
pq->head = next;

//此时head和tail同时指向最后一个空间,释放head后,要注意也要把tail释放了
if (pq->head == NULL)
{
pq->tail = NULL;
}
}

//取队头的数据
QDataType QueueFront(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->head->data;
}

//取队尾的数据
QDataType QueueBack(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->tail->data;
}

//计算有多少个数据
int QueueSize(Queue* pq)
{
assert(pq);
int n = 0;
QueueNode* cur = pq->head;
while (cur)
{
++n;
cur = cur->next;
}
return n;
}

//判断队列是否为空
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->head == NULL;
}

typedef struct {
Queue q1;
Queue q2;
} MyStack;

//栈的创建
MyStack* myStackCreate() {
MyStack* st = (MyStack*)malloc(sizeof(MyStack));
QueueInit(
QueueInit(
return st;
}

//数据入栈
void myStackPush(MyStack* obj, int x) {
if(!QueueEmpty(&obj->q1))
{
QueuePush(
}
else
{
QueuePush(
}
}

//数据出栈
int myStackPop(MyStack* obj) {
Queue* emptyQ =
Queue* noneemptyQ =
if(!QueueEmpty(&obj->q1))
{
emptyQ =
noneemptyQ =
}
while(QueueSize(noneemptyQ) > 1)
{
QueuePush(emptyQ,QueueFront(noneemptyQ));
QueuePop(noneemptyQ);
}
int top = QueueFront(noneemptyQ);
QueuePop(noneemptyQ);
return top;
}

//栈顶元素
int myStackTop(MyStack* obj) {
//队列的尾就是栈的顶
if(!QueueEmpty(&obj->q1))
{
return QueueBack(
}
else
{
return QueueBack(
}
}

//判断栈是否为空
bool myStackEmpty(MyStack* obj) {
return QueueEmpty(&obj->q1) && QueueEmpty(
}

//栈的销毁
void myStackFree(MyStack* obj) {
QueueDestroy(
QueueDestroy(
free(obj);
}

二、有效的括号

1.题干分析 

2.动图解析 

3.代码实现 

typedef char STDataType;

typedef struct Stack
{
STDataType* a;
int top;//栈顶
int capacity;
}ST;

//栈的初始化
void StackInit(ST* ps);

//栈的销毁
void StackDestroy(ST* ps);

//栈的栈顶插入
void StackPush(ST* ps, STDataType x);

//栈的删除
void StackPop(ST* ps);

//取栈顶的数据
STDataType StackTop(ST* ps);

//栈的元素个数
int StackSize(ST* ps);

//判断栈是不是空
bool StackEmpty(ST* ps);

//栈的初始化
void StackInit(ST* ps)
{
assert(ps);
ps->a = NULL;
ps->top = 0;
ps->capacity = 0;
}


//栈的销毁
void StackDestroy(ST* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capacity = ps->top = 0;
}

//栈的栈顶插入
void StackPush(ST* ps, STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)
{
int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newCapacity);
if (tmp == NULL)
{
printf("realloc fail\n");
exit(-1);
}
ps->a = tmp;
ps->capacity = newCapacity;
}
ps->a[ps->top] = x;
ps->top++;
}

//栈的删除
void StackPop(ST* ps)
{
assert(ps);
assert(!StackEmpty(ps));
ps->top--;
}

//取栈顶的数据
STDataType StackTop(ST* ps)
{
assert(ps);
assert(!StackEmpty(ps));
return ps->a[ps->top - 1];
}

//栈的元素个数
int StackSize(ST* ps)
{
assert(ps);
return ps->top;
}

//判断栈是不是空
bool StackEmpty(ST* ps)
{
assert(ps);
return ps->top == 0;
}

bool isValid(char * s){
ST st;
StackInit(
while(*s)
{
//入左括号
if(*s == '(' || *s== '{' || *s== '[')
{
StackPush(
++s;
}
else
{
//遇到右括号,但是栈里面没有数据,说明前面没有左括号,不匹配
if(StackEmpty(&st))
{
StackDestroy(
return false;
}
//取栈顶的数据,进行比对
STDataType top = StackTop(
StackPop(

if((*s == ')' & '(')
||(*s == '}' & '{')
||(*s == ']' & '['))
{
StackDestroy(
return false;
}
else
{
s++;
}
}
}
//如果不是空,说明还有左括号未出;
//没有匹配返回的是false
bool ret = StackEmpty(
StackDestroy(
return ret;
}

三、用栈实现队列 

1.题干分析 

2.动图解析 

3.代码实现 

typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top;//栈顶
int capacity;
}ST;

//栈的初始化
void StackInit(ST* ps);

//栈的销毁
void StackDestroy(ST* ps);

//栈的栈顶插入
void StackPush(ST* ps, STDataType x);

//栈的删除
void StackPop(ST* ps);

//取栈顶的数据
STDataType StackTop(ST* ps);

//栈的元素个数
int StackSize(ST* ps);

//判断栈是不是空
bool StackEmpty(ST* ps);

//栈的初始化
void StackInit(ST* ps)
{
assert(ps);
ps->a = NULL;
ps->top = 0;
ps->capacity = 0;
}


//栈的销毁
void StackDestroy(ST* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capacity = ps->top = 0;
}

//栈的栈顶插入
void StackPush(ST* ps, STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)
{
int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newCapacity);
if (tmp == NULL)
{
printf("realloc fail\n");
exit(-1);
}
ps->a = tmp;
ps->capacity = newCapacity;
}
ps->a[ps->top] = x;
ps->top++;
}

//栈的删除
void StackPop(ST* ps)
{
assert(ps);
assert(!StackEmpty(ps));
ps->top--;
}

//取栈顶的数据
STDataType StackTop(ST* ps)
{
assert(ps);
assert(!StackEmpty(ps));
return ps->a[ps->top - 1];
}

//栈的元素个数
int StackSize(ST* ps)
{
assert(ps);
return ps->top;
}

//判断栈是不是空
bool StackEmpty(ST* ps)
{
assert(ps);
return ps->top == 0;
}

typedef struct {
ST pushST;
ST popST;
} MyQueue;

//队列的创建
MyQueue* myQueueCreate() {
MyQueue* q = (MyQueue*)malloc(sizeof(MyQueue));
StackInit(
StackInit(
return q;
}

void myQueuePush(MyQueue* obj, int x) {
StackPush(&obj->pushST,x);
}

//取队头数据
int myQueuePop(MyQueue* obj) {
//如果popST中没有数据,将pushST中的数据导过去
//popST中的数据就符合先进先出的顺序了
if(StackEmpty(&obj->popST))
{
while(!StackEmpty(&obj->pushST))
{
StackPush(&obj->popST,StackTop(&obj->pushST));
StackPop(&obj->pushST);
}
}
int front = StackTop(&obj->popST);
StackPop(&obj->popST);
return front;
}

//返回队列开头的元素
int myQueuePeek(MyQueue* obj) {
if(StackEmpty(&obj->popST))
{
while(!StackEmpty(&obj->pushST))
{
StackPush(&obj->popST,StackTop(&obj->pushST));
StackPop(&obj->pushST);
}
}
return StackTop(&obj->popST);
}

//判断队列是否为空
bool myQueueEmpty(MyQueue* obj) {
return StackEmpty(&obj->pushST) && StackEmpty(&obj->popST);
}

//队列销毁
void myQueueFree(MyQueue* obj) {
StackDestroy(&obj->pushST);
StackDestroy(&obj->popST);
free(obj);
}

四、设计循环队列 

1.题干分析 

2. 代码实现

①数组实现

typedef struct {
int* a;
int k;
int front;
int tail;
} MyCircularQueue;
bool myCircularQueueIsEmpty(MyCircularQueue* obj);
bool myCircularQueueIsFull(MyCircularQueue* obj);

MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* cq = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
cq->a = (int*)malloc(sizeof(int)*(k+1));//开辟k+1个空间
cq->front = cq->tail = 0;
cq->k = k;
return cq;
}
//入数据
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
if(myCircularQueueIsFull(obj))
return false;
obj->a[obj->tail] = value;
++obj->tail;
obj->tail %= (obj->k+1);
return true;
}
//出数据
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
return false;
++obj->front;
obj->front%=(obj->k+1);
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->tail ==0)
return obj->a[obj->k];
else
return obj->a[obj->tail-1];
/*
int i = (obj->tail + obj->k) % (obj->k+1);
return obj->a[i];
*/

}
//判空
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
return obj->front == obj->tail;
}
//判满
bool myCircularQueueIsFull(MyCircularQueue* obj) {
return (obj->tail+1) % (obj->k+1) == obj->front;
}
//销毁
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->a);
free(obj);
}

 

② 链表实现

typedef int CirQDataType;

typedef struct CirQNode
{
CirQDataType Data;
struct CirQNode* next;
}CirQNode;

typedef struct {
int k;
CirQNode* head;
CirQNode* tail;
} MyCircularQueue;

bool myCircularQueueIsEmpty(MyCircularQueue* obj);
bool myCircularQueueIsFull(MyCircularQueue* obj);

//循环队列的初始化
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* cq = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
CirQNode* cur = (CirQNode*)malloc(sizeof(CirQNode));
cq->k = k;
cq->head = cq->tail = cur;
//创建好一个结点后,在后面循环创建k个结点
while(k--)
{
CirQNode* newnode = (CirQNode*)malloc(sizeof(CirQNode));
CirQNode* NewTail = cq->tail;//记录新的尾
NewTail->next = newnode;//把申请的结点链到新的尾上
newnode->next = cq->head;//新结点链到头结点
cq->tail=newnode;//自己成为新的尾
}
cq->tail=cq->tail->next;//让tail回到原来的位置,也可不加,因为循环,只是个人看着不舒服
cq->head = cq->tail;
return cq;
}

//循环队列的入数据
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
if(myCircularQueueIsFull(obj))
return false;
//依次入数据,tail向后走
obj->tail->Data = value;
obj->tail = obj->tail->next;
return true;
}

//循环队列的出数据
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
return false;
obj->head = obj->head->next;
return true;
}

//循环队列取队头数据
int myCircularQueueFront(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
return -1;
return obj->head->Data;

}

//循环队列取队尾数据
int myCircularQueueRear(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
return -1;
//tail的前有个位置的结点就是队尾的数据
CirQNode* prev = obj->head;
while(prev->next != obj->tail)
{
prev = prev->next;
}
return prev->Data;
}

//循环队列判空
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
return obj->head == obj->tail;
}

//循环队列判满
bool myCircularQueueIsFull(MyCircularQueue* obj) {
return obj->tail->next == obj->head;
}

//循环队列销毁
void myCircularQueueFree(MyCircularQueue* obj) {
while(obj->head != obj->tail)
{
CirQNode* cur = obj->head->next;
free(obj->head);
obj->head = cur;
}
free(obj->head);
free(obj);
}

 

举报

相关推荐

0 条评论