文章目录
前言
leetcode栈和队列的相关题、有效的括号、用队列实现栈、用栈实现队列、设计循环队列等介绍
一、有效的括号
c
// 动态增长的栈
typedef char STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;
// 初始化栈
void STInit(ST* ps);
// 销毁栈
void STDestroy(ST* ps);
// 插入
void STPush(ST* ps, STDataType x);
// 出栈
void STPop(ST* ps);
// 检查是否为空
bool STEmpty(ST* ps);
// 获取栈顶元素
STDataType STTop(ST* ps);
//获取有效元素的个数
int STSize(ST* ps);
// 初始化栈
void STInit(ST* ps)
{
assert(ps);
ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);
if (ps->a == NULL)
{
perror("STInit malloc");
return;
}
ps->top = 0; // top指的是栈顶元素的下一个位置
//ps->top = -1; // top 指的是栈顶元素
ps->capacity = 4;
}
// 销毁栈
void STDestroy(ST* ps)
{
assert(ps);
free(ps->a);
ps->a == NULL;
ps->top = 0;
ps->capacity = 0;
}
// 入栈
void STPush(ST* ps, STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)
{
STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * ps->capacity * 2);
if (tmp == NULL)
{
perror("STPush relloc");
return;
}
ps->a = tmp;
ps->capacity *= 2;
}
ps->a[ps->top] = x;
ps->top++;
}
// 出栈
void STPop(ST* ps)
{
assert(ps);
assert(!STEmpty(ps));
ps->top--;
}
// 检查是否为空
bool STEmpty(ST* ps)
{
assert(ps);
return ps->top == 0;
}
// 获取栈顶元素
STDataType STTop(ST* ps)
{
assert(ps);
assert(!STEmpty(ps));
return ps->a[ps->top - 1];
}
// 获取有效元素的个数
int STSize(ST* ps)
{
assert(ps);
return ps->top;
}
bool isValid(char* s) {
ST st;
STInit(&st);
while(*s)
{
if(*s == '(' || *s == '[' || *s == '{')
{
STPush(&st, *s);
}
else
{
if(STEmpty(&st))
{
STDestroy(&st);
return false;
}
char top = STTop(&st);
STPop(&st);
if((*s == ')' && top != '(')
|| (*s == ']' && top != '[')
|| (*s == '}' && top != '{'))
{
STDestroy(&st);
return false;
}
}
s++;
}
bool ret = STEmpty(&st);
STDestroy(&st);
return ret;
}
二、用队列实现栈
c
typedef int QDataType;
typedef struct QueueNode
{
struct QueueNode* next;
QDataType data;
}QNode;
typedef struct Queue
{
QNode* head;
QNode* tail;
int size;
} Queue;
// 初始化队列
void QInit(Queue* pq)
{
assert(pq);
pq->head = pq->tail = NULL;
pq->size = 0;
}
// 销毁队列
void QDestroy(Queue* pq)
{
assert(pq);
QNode* cur = pq->head;
while (cur)
{
QNode* next = cur->next;
free(cur);
cur = next;
}
pq->head = pq->tail = NULL;
pq->size = 0;
}
// 入队列
void QPush(Queue* pq, QDataType x)
{
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
perror("QPush()::malloc()");
return;
}
newnode->next = NULL;
newnode->data = x;
if (pq->head == NULL)
{
assert(pq->tail == NULL);
pq->head = pq->tail = newnode;
}
else
{
pq->tail->next = newnode;
pq->tail = pq->tail->next;
}
pq->size++;
}
// 出队列
void QPop(Queue* pq)
{
assert(pq);
assert(pq->head != NULL);
if (pq->head->next == NULL)
{
free(pq->head);
pq->head = pq->tail = NULL;
}
else
{
QNode* cur = pq->head;
pq->head = cur->next;
free(cur);
cur = NULL;
}
pq->size--;
}
// 获取队列元素个数
int QSize(Queue* pq)
{
assert(pq);
return pq->size;
}
// 判断队列是否为空
bool QEmpty(Queue* pq)
{
assert(pq);
return (pq->head == NULL && pq->tail == NULL);
}
// 找到队列的头元素
QDataType QFront(Queue* pq)
{
assert(pq);
assert(!QEmpty(pq));
return (pq->head->data);
}
// 找到队列的尾元素
QDataType QBack(Queue* pq)
{
assert(pq);
assert(!QEmpty(pq));
return (pq->tail->data);
}
typedef struct {
Queue q1;
Queue q2;
} MyStack;
MyStack* myStackCreate() {
MyStack* pst = (MyStack*)malloc(sizeof(MyStack));
if(pst == NULL)
{
perror("myStackCreate malloc");
return NULL;
}
QInit(&pst->q1);
QInit(&pst->q2);
return pst;
}
void myStackPush(MyStack* obj, int x) {
if(!QEmpty(&obj->q1))
{
QPush(&obj->q1, x);
}
else
{
QPush(&obj->q2, x);
}
}
int myStackPop(MyStack* obj) {
Queue* empty = &obj->q1;
Queue* nonempty = &obj->q2;
if(!QEmpty(&obj->q1))
{
empty = &obj->q2;
nonempty = &obj->q1;
}
while(QSize(nonempty) > 1)
{
QPush(empty, QFront(nonempty));
QPop(nonempty);
}
int top = QFront(nonempty);
QPop(nonempty);
return top;
}
int myStackTop(MyStack* obj) {
if(!QEmpty(&obj->q1))
{
return QBack(&obj->q1);
}
else
{
return QBack(&obj->q2);
}
}
bool myStackEmpty(MyStack* obj) {
return (QEmpty(&obj->q1) && QEmpty(&obj->q2));
}
void myStackFree(MyStack* obj) {
QDestroy(&obj->q1);
QDestroy(&obj->q2);
obj = NULL;
}
/**
* 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);
*/
三、 用栈实现队列
c
// 动态增长的栈
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;
// 初始化栈
void STInit(ST* ps);
// 销毁栈
void STDestroy(ST* ps);
// 插入
void STPush(ST* ps, STDataType x);
// 出栈
void STPop(ST* ps);
// 检查是否为空
bool STEmpty(ST* ps);
// 获取栈顶元素
STDataType STTop(ST* ps);
//获取有效元素的个数
int STSize(ST* ps);
// 初始化栈
void STInit(ST* ps)
{
assert(ps);
ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);
if (ps->a == NULL)
{
perror("STInit malloc");
return;
}
ps->top = 0; // top指的是栈顶元素的下一个位置
//ps->top = -1; // top 指的是栈顶元素
ps->capacity = 4;
}
// 销毁栈
void STDestroy(ST* ps)
{
assert(ps);
free(ps->a);
ps->a == NULL;
ps->top = 0;
ps->capacity = 0;
}
// 入栈
void STPush(ST* ps, STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)
{
STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * ps->capacity * 2);
if (tmp == NULL)
{
perror("STPush relloc");
return;
}
ps->a = tmp;
ps->capacity *= 2;
}
ps->a[ps->top] = x;
ps->top++;
}
// 出栈
void STPop(ST* ps)
{
assert(ps);
assert(!STEmpty(ps));
ps->top--;
}
// 检查是否为空
bool STEmpty(ST* ps)
{
assert(ps);
return (ps->top == 0);
}
// 获取栈顶元素
STDataType STTop(ST* ps)
{
assert(ps);
assert(!STEmpty(ps));
return ps->a[ps->top - 1];
}
// 获取有效元素的个数
int STSize(ST* ps)
{
assert(ps);
return ps->top;
}
typedef struct {
ST pushst;
ST popst;
} MyQueue;
MyQueue* myQueueCreate() {
MyQueue* tmp = (MyQueue*)malloc(sizeof(MyQueue));
if(tmp == NULL)
{
perror("myQueueCreate malloc");
return NULL;
}
STInit(&tmp->pushst);
STInit(&tmp->popst);
return tmp;
}
void myQueuePush(MyQueue* obj, int x) {
STPush(&obj->pushst, x);
}
int myQueuePop(MyQueue* obj) {
if(STEmpty(&obj->popst))
{
while(!STEmpty(&obj->pushst))
{
STPush(&obj->popst, STTop(&obj->pushst));
STPop(&obj->pushst);
}
}
int front = STTop(&obj->popst);
STPop(&obj->popst);
return front;
}
int myQueuePeek(MyQueue* obj) {
if(STEmpty(&obj->popst))
{
while(!STEmpty(&obj->pushst))
{
STPush(&obj->popst, STTop(&obj->pushst));
STPop(&obj->pushst);
}
}
int front = STTop(&obj->popst);
return front;
}
bool myQueueEmpty(MyQueue* obj) {
return (STEmpty(&obj->pushst) && STEmpty(&obj->popst));
}
void myQueueFree(MyQueue* obj) {
STDestroy(&obj->pushst);
STDestroy(&obj->popst);
free(obj);
obj = NULL;
}
/**
* 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);
*/
四、设计循环队列
c
typedef struct {
int* a;
int Front;
int Rear;
int k;
} MyCircularQueue;
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* tmp = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
tmp->a = (int*)malloc(sizeof(int) * (k+1));
tmp->Front = tmp->Rear = 0;
tmp->k = k;
return tmp;
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
return (obj->Front == obj->Rear);
}
bool myCircularQueueIsFull(MyCircularQueue* obj) {
return (obj->Front == (obj->Rear + 1) % (obj->k + 1));
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
// 判断是否满了
if(myCircularQueueIsFull(obj))
{
return false;
}
// 没满
obj->a[obj->Rear] = value;
obj->Rear++;
obj->Rear = obj->Rear % (obj->k + 1);
return true;
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
// 判断你是否为空
if(myCircularQueueIsEmpty(obj))
{
return false;
}
obj->Front = obj->Front % (obj->k + 1);
obj->Front++;
return true;
}
int myCircularQueueFront(MyCircularQueue* obj) {
// 判断队列为空 返回 -1
if(myCircularQueueIsEmpty(obj))
{
return - 1;
}
return obj->a[obj->Front];
}
int myCircularQueueRear(MyCircularQueue* obj) {
// 判断队列为空 返回 -1
if(myCircularQueueIsEmpty(obj))
{
return -1;
}
return obj->a[(obj->Rear-1 + (obj->k + 1)) % (obj->k + 1)];
}
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->a);
obj->a = NULL;
obj->Front = obj->Rear = 0;
obj->k = 0;
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);
*/
总结
leetcode栈和队列的相关题、有效的括号、用队列实现栈、用栈实现队列、设计循环队列等介绍