栈和队列初级题目(包含四个题)

news2024/9/29 23:24:13

目录

一、原题链接:

二、有效的括号:

​编辑代码实现:

 三、用队列实现栈:

四、用栈实现队列:

五、设计循环队列:

六、读书分享:


一、原题链接:

20. 有效的括号

225. 用队列实现栈

232. 用栈实现队列

622. 设计循环队列

二、有效的括号:

这种题大家应该在上数据结构课时应该就听过吧(括号匹配)。对于这个题,我们可以使用栈实现。

当栈顶元素与将要入栈的元素形成一个完整的括号时,就让栈顶元素出栈。直到把所有括号遍历完,栈里没有剩余元素时,就是有效的括号。


代码实现:

//手动实现一个栈
typedef char StackDataType;
typedef struct Stack
{
	StackDataType* _a;
	int _top;
	int _capacity;
}Stack;
void StackInit(Stack* pst);
void StackDestory(Stack* pst);
void StackPush(Stack* pst, StackDataType x);
void StackPop(Stack* pst);
int StackSize(Stack* pst);
bool StackEmpty(Stack* pst);
StackDataType StackTop(Stack* pst);
void StackInit(Stack* pst)
{
	assert(pst);
	pst->_a = (StackDataType*)malloc(sizeof(StackDataType) * 4);
	pst->_top = 0;
	pst->_capacity = 4;
}
void StackDestory(Stack* pst)
{
	assert(pst);
	free(pst->_a);
	pst->_a = NULL;
	pst->_top = 0;
	pst->_capacity = 0;
}
void StackPush(Stack* pst, StackDataType x)
{
	assert(pst);
	if (pst->_top == pst->_capacity)
	{
		pst->_capacity *= 2;
		StackDataType* tmp = (StackDataType*)realloc(pst->_a, sizeof(StackDataType) * pst->_capacity);
		if (tmp == NULL)
		{
			printf("内存不足\n");
			exit(-1);
		}
		else
		{
			pst->_a = tmp;
		}
	}
	pst->_a[pst->_top] = x;
	pst->_top++;
}
void StackPop(Stack* pst)
{
	assert(pst);
	assert(pst->_top > 0);
	--pst->_top;
}
int StackSize(Stack* pst)
{
	assert(pst);
	return pst->_top;
}
bool StackEmpty(Stack* pst)
{
	assert(pst);
	return pst->_top == 0 ? 1 : 0;
}
StackDataType StackTop(Stack* pst)
{
	assert(pst);
	assert(pst->_top > 0);
	return pst->_a[pst->_top - 1];
}


//有效的括号
bool isValid(char* s) {
    Stack st;
    StackInit(&st);
    bool ret=false;//用于返回最终结果
    while(*s!='\0')
    {
        if(*s=='('||*s=='['||*s=='{')//前括号入栈
        {
            StackPush(&st,*s);
            ++s;
        }
        if(*s==')'||*s==']'||*s=='}')//后括号出栈
        {
            if(StackEmpty(&st))//当栈为空,入栈的是后括号,无法匹配
                break;        //使用break不使用return是为了防止内存泄漏,因为中途返回不会调用销毁栈的函数

            StackDataType Top=StackTop(&st);//取栈顶元素出来匹配

            //匹配不成功
            if(Top=='('&&*s!=')')
                break;
            if(Top=='['&&*s!=']')
                break;
            if(Top=='{'&&*s!='}')
                break;

            //匹配成功
            StackPop(&st);
            ++s;
        }
    }

    if(*s=='\0')//字符串遍历完
    {
        ret=StackEmpty(&st);//查看栈内是否还存在元素
    }
    StackDestory(&st);
    return ret;
}

 三、用队列实现栈:

要用队列实现栈,我们要用两个队列来实现。

入栈时,把元素放入非空队列(最开始都为空时,随便放一个);

出栈时,把除队尾的所有元素都放入另一个队列里,然后让队尾元素出栈。

每次保证一个队列有数据,一个队列为空。

//手动实现一个队列
typedef int QueueDataType;
typedef struct QueueNode
{
	struct QueueNode* _next;
	QueueDataType _data;
}QueueNode;
typedef struct Queue
{
	QueueNode* _head;
	QueueNode* _tail;
}Queue;
void QueueInit(Queue* pq);
void QueueDestory(Queue* pq);
void QueuePush(Queue* pq,QueueDataType x);
void QueuePop(Queue* pq);
QueueDataType QueueFront(Queue* pq);
QueueDataType QueueBack(Queue* pq);
bool QueueEmpty(Queue* pq);
int QueueSize(Queue* pq);

void QueueInit(Queue* pq)
{
	assert(pq);
	pq->_head = NULL;
	pq->_tail = NULL;
}
void QueueDestory(Queue* pq)
{
	assert(pq);
	QueueDataType* tmp = NULL;
	while (pq->_head != NULL)
	{
		tmp = pq->_head;
		pq->_head = pq->_head->_next;
		free(tmp);
	}
	pq->_tail = NULL;
}
void QueuePush(Queue* pq, QueueDataType x)
{
	assert(pq);
	QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));
	if (newNode == NULL)
	{
		printf("内存不足\n");
		exit(-1);
	}
	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(pq->_head);
	QueueNode* next = pq->_head->_next;
	free(pq->_head);
	pq->_head = next;
	if (pq->_head == NULL)
	{
		pq->_tail = NULL;
	}
}
QueueDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->_head);
	return pq->_head->_data;
}
QueueDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->_tail);
	return pq->_tail->_data;
}
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->_head == NULL ? 1 : 0;
}
int QueueSize(Queue* pq)
{
	assert(pq);
	QueueNode* cur = pq->_head;
	int size = 0;
	while (cur != NULL)
	{
		size++;
		cur = cur->_next;
	}
	return size;
}



//用两个队列实现栈
typedef struct {
    Queue _q1;
    Queue _q2;
} MyStack;

MyStack* myStackCreate() {
    MyStack* st=(MyStack*)malloc(sizeof(MyStack));//为结构体分配内存
    QueueInit(&st->_q1);
    QueueInit(&st->_q2);
    return st;//后续可以通过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* nonEmpty=&obj->_q2;
    if(!QueueEmpty(&obj->_q1))
    {
        empty=&obj->_q2;
        nonEmpty=&obj->_q1;
    }
    int ret=QueueBack(nonEmpty);//获取非空队列的队尾作为栈顶元素

    while(QueueSize(nonEmpty)>1)//将非栈顶元素放入空队列,将非空队列的元素依次出栈,除栈顶元素
    {    
        QueuePush(empty,QueueFront(nonEmpty));
        QueuePop(nonEmpty);
    }
    QueuePop(nonEmpty);//栈顶元素出栈
    return ret;
}

int myStackTop(MyStack* obj) {
    //非空队列的最后一个元素就是栈顶元素
    //题目说了:每次调用 pop 和 top 都保证栈不为空
    if(!QueueEmpty(&obj->_q1))
    {
        return QueueBack(&obj->_q1);
    }
    else //if(!QueueEmpty(obj->_q2))
    {
        return QueueBack(&obj->_q2);
    }
}

bool myStackEmpty(MyStack* obj) {
    if(QueueEmpty(&obj->_q1)&&QueueEmpty(&obj->_q2))
    {
        return true;
    }
    return false;
}

void myStackFree(MyStack* obj) {
    QueueDestory(&obj->_q1);
    QueueDestory(&obj->_q1);
    free(obj);
}

 栈的相关函数的外部调用:

int main()
{
	MyStack* obj = myStackCreate();
	myStackPush(obj, 1);
	myStackPush(obj, 2);
	return 0;
}

四、用栈实现队列:

类比于用队列实现栈,这个题也可以用两个栈实现队列。

我们创建一个插入栈(_pushSt),一个删除栈(_PopSt),入队列就将元素放入_pushSt,出队列就将 _pushSt 里的所有元素都放入 _popSt 后再出栈。

//手动实现一个栈
typedef int StackDataType;
typedef struct Stack
{
	StackDataType* _a;
	int _top;
	int _capacity;
}Stack;
void StackInit(Stack* pst);
void StackDestory(Stack* pst);
void StackPush(Stack* pst, StackDataType x);
void StackPop(Stack* pst);
int StackSize(Stack* pst);
bool StackEmpty(Stack* pst);
StackDataType StackTop(Stack* pst);

void StackInit(Stack* pst)
{
	assert(pst);
	pst->_a = (StackDataType*)malloc(sizeof(StackDataType) * 4);
	pst->_top = 0;
	pst->_capacity = 4;
}
void StackDestory(Stack* pst)
{
	assert(pst);
	free(pst->_a);
	pst->_a = NULL;
	pst->_top = 0;
	pst->_capacity = 0;
}
void StackPush(Stack* pst, StackDataType x)
{
	assert(pst);
	if (pst->_top == pst->_capacity)
	{
		pst->_capacity *= 2;
		StackDataType* tmp = (StackDataType*)realloc(pst->_a, sizeof(StackDataType) * pst->_capacity);
		if (tmp == NULL)
		{
			printf("内存不足\n");
			exit(-1);
		}
		else
		{
			pst->_a = tmp;
		}
	}
	pst->_a[pst->_top] = x;
	pst->_top++;
}
void StackPop(Stack* pst)
{
	assert(pst);
	assert(pst->_top > 0);
	--pst->_top;
}
int StackSize(Stack* pst)
{
	assert(pst);
	return pst->_top;
}
bool StackEmpty(Stack* pst)
{
	assert(pst);
	return pst->_top == 0 ? 1 : 0;
}
StackDataType StackTop(Stack* pst)
{
	assert(pst);
	assert(pst->_top > 0);
	return pst->_a[pst->_top - 1];
}



//用两个栈实现队列
typedef struct {
    Stack _pushSt;
    Stack _popSt;
} MyQueue;


MyQueue* myQueueCreate() {
    MyQueue* q=(MyQueue*)malloc(sizeof(MyQueue));//为队列分配空间
    StackInit(&q->_pushSt);
    StackInit(&q->_popSt);
    return q;
}

void myQueuePush(MyQueue* obj, int x) {
    StackPush(&obj->_pushSt,x);//直接将元素压入_pshSt
}

int myQueuePop(MyQueue* obj) {
    int ret=myQueuePeek(obj);//由于该操作和获取队头元素操作类似,所以直接调用获取队头元素
    StackPop(&obj->_popSt);
    return ret;
}
//获取队头元素
int myQueuePeek(MyQueue* obj) {
    //直接在_popSt里面拿
    if(StackEmpty(&obj->_popSt))//当_popSt里面没有元素
    {
        while(!StackEmpty(&obj->_pushSt))//当_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) {
    StackDestory(&obj->_pushSt);
    StackDestory(&obj->_popSt);
    free(obj);
}

五、设计循环队列:

对于静态循环链表的设计,由于会存在队空与队满情况的冲突(队空与队满时,头指针与尾指针都指向一个位置)

如果没有多余空间:

当多余一个空间: 

队满情况: 

执行出队操作时的特殊情况:

 

返回队尾元素,且_rear指向数组头时的情况 :

//静态循环队列
typedef struct {
    int* _a;
    int _front;
    int _rear;
    int _k;
} MyCircularQueue;


MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue* q=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    q->_a=(int*)malloc(sizeof(int)*(k+1));//多分配一个空间,方便区别空与满
    q->_front=0;
    q->_rear=0;
    q->_k=k;//记录循环链表的容量
    return q;
}
//先声明,方便函数调用
bool myCircularQueueIsEmpty(MyCircularQueue* obj);
bool myCircularQueueIsFull(MyCircularQueue* obj);

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    if(myCircularQueueIsFull(obj))
    {
        return false;
    }
    else
    {
        obj->_a[obj->_rear]=value; 
        if(obj->_rear==obj->_k)
        {
            obj->_rear%=obj->_k;//_rear在最后一个位置需要向后移动时,回到数组头部
        }   
        else
        {
           obj->_rear++; 
        }
    }
    return true;
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    {
        return false;
    }
    else
    {
        obj->_front++;
        if(obj->_front==obj->_k+1)//如果_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->_rear==0)//队尾指针指向在数组的第0号位置,队尾元素应该在数组的最后
        return obj->_a[obj->_k];
 
    return obj->_a[obj->_rear-1];   
}

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    return obj->_front==obj->_rear;
}

bool myCircularQueueIsFull(MyCircularQueue* obj) {
    return (obj->_rear+1)%(obj->_k+1) == obj->_front;
}

void myCircularQueueFree(MyCircularQueue* obj) {
    free(obj->_a);
    free(obj);
}

六、读书分享:

道德经·第五十章》:

出生入死。生之徒,十有三;死之徒”,十有三;人之生,动之于死地”,亦十有三。夫何故?以其生生之厚。
盖闻善摄生者", 陆行不遇兕虎,人军不被甲兵"。兕无所投其角”,虎无所用其爪”,兵无所容其刃。夫何故?以其无死地。

解释:

人出世为生,入地为死。属于长寿的,占十分之三;属于短命的,占十分之三;人的过分地奉养生命,妄为而走向死路的,也占了十分之三。为什么呢?因为奉养太过度了。
听说善于养护生命的人,在陆地上行走不会遇到犀牛和老虎,在战争中不会受到杀伤。犀牛用不上它的角,老虎用不上它的爪,兵器用不上它的刃。为什么呢?因为他没有进入死亡的范围。
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1662649.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux 进程信号【信号产生】

💓博主CSDN主页:麻辣韭菜💓   ⏩专栏分类:Linux知识分享⏪   🚚代码仓库:Linux代码练习🚚   🌹关注我🫵带你学习更多Linux知识   🔝 目录 前言 信号概念 1. 生活角度的信号 2…

线性代数的一些理解(更新中)

以前学的时候都是囫囵吞枣,能搞过就得了。现在有了点时间可以静下来看看。。 还是分成点来看吧。 1 小车运行 一个车匀速在一维坐标前行,速度是2米每秒,起始点是0。如何描述 设 𝑥(𝑡) 表示车辆在时间 &#x1d461…

为什么要进行金融类软件测试

金融类软件测试是确保金融软件质量、安全性和稳定性的关键步骤。随着金融行业信息化和数字化的深入发展,金融软件的应用范围日益广泛,涉及资金交易、客户信息管理、风险控制等多个方面。 因此,进行金融类软件测试显得尤为重要,以…

力扣HOT100 - 155. 最小栈

解题思路&#xff1a; 辅助栈 class MinStack {private Stack<Integer> stack;private Stack<Integer> min_stack;public MinStack() {stack new Stack<>();min_stack new Stack<>();}public void push(int val) {stack.push(val);if (min_stack.i…

24数维杯ABC题思路已更新!!!!

24数维杯A题保姆级思路&#xff0b;配套代码&#xff0b;后续参考论文 简单麦麦https://www.jdmm.cc/file/2710639/ 24数维杯B题保姆级思路&#xff0b;可执行代码&#xff0b;后续参考论文 简单麦麦https://www.jdmm.cc/file/2710640/ 24数维杯C题保姆级思路&#xff0b;可执…

[AutoSar]BSW_Com021单帧 首帧 流控帧 连续帧 详解

目录 关键词平台说明一、N_PDU和N_PCI二、单帧三、首帧四、流控帧五、连续帧六、case 关键词 嵌入式、C语言、autosar、OS、BSW、UDS、diagnostic 平台说明 项目ValueOSautosar OSautosar厂商vector &#xff0c; EB芯片厂商TI 英飞凌编程语言C&#xff0c;C编译器HighTec (…

2024全新小狐狸AI免授权源码

源码安装说明&#xff1a; 下 载 地 址 &#xff1a; runruncode.com/php/19757.html 1. 在宝塔新建一个站点&#xff0c;选择 PHP 版本为 7.2、7.3 或 7.4。将压缩包上传到站点的根目录&#xff0c;并设置运行目录为 /public。 2. 导入数据库文件&#xff0c;该文件位于 …

【JVM】从三种认知角度重识JVM

目录 JVM概述 JVM主要功能 虚拟机是Java平台无关的保障 JVM概述 JVM&#xff1a;Java Virtual Machine,也就是Java虚拟机。 虚拟机&#xff1a;通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的计算机系统&#xff08;物理上不存在&#xff09;。 JVM通…

求一个B站屏蔽竖屏视频的脚本

求一个B站屏蔽竖屏视频的脚本 现在B站竖屏竖屏越来越多了&#xff0c;手机还好点给我一个按钮&#xff0c;选择不喜欢&#xff0c;但是我一般都用网页版看视屏&#xff0c;网页版不给我选择不喜欢的按钮&#xff0c;目测大概1/4到1/3的视频都是竖屏视频。 目前网页版唯一的进…

【数据库】数据库指令

一。数据库打开 1.命令行 2.进入mysql mysql -uroot -p密码 3.退出 exit&#xff1b; 二。针对数据库的操作 1.创建数据库&#xff08;有分号&#xff09; create database student; 2.使用数据库 use student 3.删除数据库&#xff08;有分号&#xff09; drop database…

回归预测 | Matlab实现SMA-GPR黏菌算法优化高斯过程回归多变量回归预测

回归预测 | Matlab实现SMA-GPR黏菌算法优化高斯过程回归多变量回归预测 目录 回归预测 | Matlab实现SMA-GPR黏菌算法优化高斯过程回归多变量回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab实现SMA-GPR黏菌算法优化高斯过程回归多变量回归预测 1.Matlab实现…

【Redis】用户登录校验

对于用 redis 对用户进行登录校验&#xff0c;大致可分为以下六步&#xff1a; 首先通过查询数据库来查找具有提供的用户名、密码和delFlag值为0的用户。如果未找到用户&#xff0c;则抛出一个带有消息"用户不存在"的ClientException&#xff08;用户不存在&#xf…

能远程一起观看电影和直播的SyncTV

什么是 SyncTV &#xff1f; SyncTV 是一个允许您远程一起观看电影和直播的程序。它提供了同步观看、剧院和代理功能。使用 SyncTV&#xff0c;您可以与朋友和家人一起观看视频和直播&#xff0c;无论他们在哪里。SyncTV 的同步观看功能确保所有观看视频的人都在同一点上。这意…

Java刷题-基础篇

目录 题目1&#xff1a;打印1~100内奇数和、偶数和 题目2&#xff1a;计算5的阶乘 题目3&#xff1a;计算 1!2!3!4!5! 的和 题目4&#xff1a;找1~100之间即能被3整除&#xff0c;又能被5整除的数字&#xff0c;要求必须使用break/continue 题目5&#xff1a;实现猜数字小…

陪玩系统APP小程序H5音视频社交系统陪玩系统源码,陪玩app源码,陪玩源码搭建陪玩社交系统开发(现成,可定制)线下陪玩系统项目开发搭建

线下陪玩系统项目的设计 在需求分析完成后&#xff0c;接下来进行系统设计。系统设计主要包括以下几个部分&#xff1a; 1. 数据库设计&#xff1a;根据需求分析的结果&#xff0c;设计数据库结构&#xff0c;包括用户信息表、服务信息表、订单信息表等。 2. 界面设计&#…

Java设计模式 _行为型模式_命令模式

一、命令模式 1、命令模式 命令模式&#xff08;Command Pattern&#xff09;是一种行为型模式&#xff0c;一种数据驱动的设计模式。命令模式中请求以命令的形式包裹在对象中&#xff0c;即将命令封装为类&#xff0c;从而可以使用不同的请求&#xff0c;队列等操作具体的对象…

汇昌联信科技:拼多多可以做无货源吗?

在探讨电商平台的经营模式时&#xff0c;"无货源"这一概念经常被提及。它指的是卖家在不需要事先囤积大量商品的情况下&#xff0c;通过与供应商的合作&#xff0c;直接将订单信息传递给他们&#xff0c;由供应商完成发货的过程。针对“拼多多可以做无货源吗?”这一…

力扣HOT100 - 84. 柱状图中最大的矩形

解题思路&#xff1a; 单调栈 对于一个高度height[ i ]&#xff0c;找左右两边均严格小于它的值。 class Solution {public int largestRectangleArea(int[] heights) {int n heights.length;int[] left new int[n];int[] right new int[n];Deque<Integer> mono_st…

部署达梦数据库主从配置详细操作DM8

服务器配置 主库 192.168.81.128 实例名 dm-1 从库 192.168.81.129 实例名 dm-2 以下安装部署主从服务器都操作 关闭防火墙 systemctl stop firewalld && systemctl disable firewalld 注意安装前必须创建 dmdba 用户&#xff0c;禁止使用 root 用户安装数据库。…

[笔试训练](十八)

目录 052:字符串压缩 053:chika和蜜柑 054:01背包 052:字符串压缩 压缩字符串(一)_牛客题霸_牛客网 (nowcoder.com) 题目&#xff1a; 题解&#xff1a; 双指针模拟 class Solution { public:string compressString(string param) {int nparam.size();string ret;int num…