数据结构之栈和队列算法题

news/2024/12/18 15:43:24/

一:有效括号数

学了栈之后这一题就比较简单了。

思路:1、左括号进栈 2、右括号出栈匹配。

完整代码:

因为使用C语言写的,所以里面包含了栈的实现

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int STDataType;
typedef struct Stack
{STDataType* a;int top;int capacity;
}ST;void StackInit(ST* st);void StackPush(ST* st, STDataType x);void StackPop(ST* st);STDataType StackTop(ST* st);bool StackEmpty(ST* st);void StackDestroy(ST* st);int StackSize(ST* st);void StackInit(ST* st)
{st->a = NULL;//top 表示栈顶元素的下一个st->capacity = st->top = 0;
}void StackPush(ST* st, STDataType x)
{assert(st);if (st->top == st->capacity){int newcapacity = st->capacity == 0 ? 4 : st->capacity * 2;STDataType* tmp = (STDataType*)realloc(st->a, newcapacity*sizeof(STDataType));if (tmp == NULL){perror("malloc fail!!");exit(1);}st->a = tmp;st->capacity = newcapacity;}st->a[st->top++] = x;
}void StackPop(ST* st)
{assert(st);assert(!StackEmpty(st));st->top--;
}STDataType StackTop(ST* st)
{assert(st);assert(!StackEmpty(st));return st->a[st->top - 1];
}bool StackEmpty(ST* st)
{assert(st);return st->top == 0;
}void StackDestroy(ST* st)
{assert(st);free(st->a);st->a == NULL;st->capacity = st->top = 0;
}int StackSize(ST* st)
{assert(st);return st->top;
}bool isValid(char* s) {ST st;StackInit(&st);while(*s){if(*s=='{'|| *s=='('|| *s=='['){StackPush(&st,*s);}else{if(StackEmpty(&st)){StackDestroy(&st);return false;}char c = StackTop(&st);StackPop(&st);if((c == '{' && *s != '}')|| (c == '(' && *s != ')') || (c == '[' && *s != ']')){StackDestroy(&st);return false;}}s++;}bool ret = StackEmpty(&st);StackDestroy(&st);return ret;
}

二:用队列实现栈

首先说明一点,这只是对栈和队列熟练度的考察,并不是栈的更好地实现方式。

思路:两个队列,保证有一个队列为空,然后其余操作基于空队列实现。

画图分析:

完整代码:

typedef int QDatatype;typedef struct QueueNode {QDatatype data;struct QueueNode* next;
}QueueNode;typedef struct Queue {struct QueueNode* head;struct 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){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));if (newnode == NULL){perror("malloc fail!!");exit(1);}else{newnode->next = NULL;newnode->data = x;}if (pq->head == NULL){pq->head = pq->tail = newnode;}else{pq->tail->next = newnode;pq->tail = newnode;}
}
void QueuePop(Queue* pq)
{assert(pq);assert(pq->head != NULL);QueueNode* del = pq->head;pq->head = del->next;free(del);del = NULL;if (pq->head == NULL){pq->tail = NULL;}
}
QDatatype QueueFront(Queue* pq)
{assert(pq);assert(pq->head != NULL);return pq->head->data;
}
QDatatype Queueback(Queue* pq)
{assert(pq);assert(pq->head != NULL);return pq->tail->data;
}
int QueueSize(Queue* pq)
{assert(pq);int cnt = 0;QueueNode* cur = pq->head;while (cur){cnt++;cur = cur->next;}return cnt;
}
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(&st->q1);QueueInit(&st->q2);return st;
}void myStackPush(MyStack* obj, int x) {if(!QueueEmpty(&obj->q1)){QueuePush(&obj->q1,x);}else{QueuePush(&obj->q2,x);}
}int myStackPop(MyStack* obj) {//判空Queue *Empty = &obj->q1;Queue *NonoEmpty = &obj->q2;if (!QueueEmpty(Empty)){Empty = &obj->q2;NonoEmpty = &obj->q1;}//出队列,入另外一个队列while (QueueSize(NonoEmpty) > 1){QDatatype data = QueueFront(NonoEmpty);QueuePush(Empty, data);QueuePop(NonoEmpty);}//剩余一个元素QDatatype data = QueueFront(NonoEmpty);QueuePop(NonoEmpty);return data;
}int myStackTop(MyStack* obj) {if(!QueueEmpty(&obj->q1)){return Queueback(&obj->q1);}else{return Queueback(&obj->q2);}
}bool myStackEmpty(MyStack* obj) {return (QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2));
}void myStackFree(MyStack* obj) {QueueDestroy(&obj->q1);QueueDestroy(&obj->q2);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);
*/

三:用栈实现队列

这一题就是反过来用栈实现队列,要实现后进先出。

思路:两个栈pushst popst 然后往pushst里面push ,每当要出队列或者要去队头数据时,就返回popst的栈顶数据,如果popst为空,就一口气把pushst里面的数据全塞进去。

就不画图了

完整代码:

栈的实现在上面有,不重复拷贝了。

typedef struct {ST pushst;ST popst;
} MyQueue;MyQueue* myQueueCreate() {MyQueue* pq = (MyQueue*)malloc(sizeof(MyQueue));StackInit(&pq->pushst);StackInit(&pq->popst);return pq;
}void myQueuePush(MyQueue* obj, int x) {StackPush(&obj->pushst,x);
}int myQueuePop(MyQueue* obj) {if(StackEmpty(&obj->popst)){while(!StackEmpty(&obj->pushst)){StackPush(&obj->popst,StackTop(&obj->pushst));StackPop(&obj->pushst);}}int frontstack = StackTop(&obj->popst);StackPop(&obj->popst);return frontstack;
}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->popst) && StackEmpty(&obj->pushst);
}void myQueueFree(MyQueue* obj) {StackDestroy(&obj->popst);StackDestroy(&obj->pushst);free(obj);
}

四:环形队列(环形缓冲器)

这里给大家贴一张图:

(数组实现)思路:创建K(存有效数据的大小)+1的长度,两个指针(严格来讲应该是下标)指向头和尾。然后用%操作实现循环。

具体请看下面画图分析

画图分析:

完整代码:


typedef struct {int* a;int tail;int head;int k;
} MyCircularQueue;bool myCircularQueueIsEmpty(MyCircularQueue* obj);
bool myCircularQueueIsFull(MyCircularQueue* obj);
MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue* cp =(MyCircularQueue*)malloc(sizeof(MyCircularQueue));cp->a =(int*)malloc(sizeof(int)*(k+1));cp->tail = 0;cp->head = 0;cp->k = k;return cp;
}bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {if(myCircularQueueIsFull(obj))return false;else{obj->a[obj->tail] = value;++obj->tail;obj->tail %= (obj->k+1);return true;}
}bool myCircularQueueDeQueue(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj))return false;else{obj->head++;obj->head %= (obj->k+1);return true;}
}int myCircularQueueFront(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj))return -1;return obj->a[obj->head];
}int myCircularQueueRear(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj))return -1;return obj->a[(obj->tail+obj->k)%(obj->k+1)];
}bool myCircularQueueIsEmpty(MyCircularQueue* obj) {return obj->head == obj->tail;
}bool myCircularQueueIsFull(MyCircularQueue* obj) {return (obj->tail+1)%(obj->k+1) == obj->head;
}void myCircularQueueFree(MyCircularQueue* obj) {free(obj->a);free(obj);
}

  完


http://www.ppmy.cn/news/1556150.html

相关文章

C语言基础-字符数组与字符串

字符数组 概念 元素类型为char字符型的数组&#xff0c;字符数组往往是用来存储字符串数据的。C语言中&#xff0c;字符是字节字符。 字节字符&#xff1a;一个字符占一个字节&#xff0c;在C语言中&#xff0c;使用char表示字节 char a A; char b 1; char c 65; //以上…

【AI知识】有监督学习分类任务之支持向量机

1.支持向量机概念 支持向量机&#xff08;Support Vector Machine, SVM&#xff09; 是一种有监督学习算法&#xff0c;主要用于分类任务&#xff08;也可用于回归任务&#xff0c;即支持向量回归&#xff0c;SVR&#xff09;。SVM的核心思想是找到一个最优的超平面&#xff0…

/bin/bash^M: 解释器错误:没有那个文件或目录(bad interpreter: No such file or directiry)

/bin/bash^M: 解释器错误&#xff1a;没有那个文件或目录&#xff08;bad interpreter: No such file or directiry&#xff09; 问题描述 运行脚本时报错如下&#xff1a; /bin/bash^M: 解释器错误&#xff1a;没有那个文件或目录&#xff08;bad interpreter: No such file…

【ubuntu18.04】ubuntu18.04挂在硬盘出现 Wrong diagnostic page; asked for 1 got 8解决方案

错误日志 [ 8754.700227] usb 2-3: new full-speed USB device number 3 using xhci_hcd [ 8754.867389] usb 2-3: New USB device found, idVendor0e0f, idProduct0002, bcdDevice 1.00 [ 8754.867421] usb 2-3: New USB device strings: Mfr1, Product2, SerialNumber0 [ 87…

yarn修改缓存位置

查看缓存位置 以下三个命令分别为&#xff1a;bin是yarn存储命令的二进制文件&#xff0c;global存储全局node_modules &#xff0c;cache存储用下下载缓存&#xff0c;查看本机目前的目录&#xff1a; 查看bin目录命令&#xff1a;yarn global bin 查看global目录命令&…

GCNet的简述

其中了解self-attention知道他的计算量是 Global Context Attention计算量变少从变成 NL&#xff1a; (a)首先resize成CHW然后通过11的卷积生成q&#xff0c;k&#xff0c;v&#xff0c;然后q乘 变成HWHW&#xff0c;然后通过softmax进行归一化然后和v进行乘&#xff0c;再通…

AI来了,云原生更稳了

不了解AI的时候&#xff0c;往往会将其视为洪水猛兽&#xff0c;因为AI确实具有颠覆一切的巨大能量&#xff1b;但是当你慢慢接近它、拥抱它甚至尝试驾驭它&#xff0c;你会发现AI如同其他许多新技术一样&#xff0c;都需要扎根的土壤、生长的养分和成熟过程中适宜的环境等。 “…

酒蒙子骰子小程序系统

酒蒙子流量变现小程序小游戏 后端tp8 前端uniapp 会员变现 分销推广 流量主 …