栈和队列的算法题目(C语言)

news2025/1/11 10:18:05

1. 括号匹配问题

20. 有效的括号 - 力扣(LeetCode)

利用栈后入先出的特性解题

1.判断字符串是否为空 为空返回

2.创建栈,遍历字符串

        第一个字符是左括号的情况:入栈->继续遍历下一个字符

        第一个字符是右括号的情况:从栈顶取元素,判断当前右括号是否匹配栈顶的左括号

3.遍历结束,判断栈是否为空,为空说明所有括号都已匹配,不为空说明有左括号没有匹配上

bool isValid(char* s) {
    Stack st;
    StackInit(&st);
    int count = 0;
    while(s[count])
    {
        if(s[count] == '(' 
        || s[count] == '['
        || s[count] == '{')
        {
            StackPush(&st,s[count]);
        }
        else
        {
            if(StackEmpty(&st))
            {
                StackDestory(&st);
                return false;
            }
            char top = StcakTop(&st);
            if(top == '(' && s[count] != ')'
            ||top == '{' && s[count] != '}'
            ||top == '[' && s[count] != ']')
            {
                StackDestory(&st);
                return false;
            }
            StackPop(&st);
        }
        count++;
    }
    int  result = StackEmpty(&st);
    StackDestory(&st);
    return result;
}

2. 用队列实现栈

225. 用队列实现栈 - 力扣(LeetCode)

队列的特性是先入先出 栈的特性是后入先出

创建两个队列

为空的情况:两个队列都为空

1.push插入:直接插入队列中

2.需要pop的时候,将队列的元素导到另一个队列,最后一个元素就是栈顶元素

3.当有元素需要插入,判断哪个队列不为空,就直接插入

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


MyStack* myStackCreate() {
    MyStack* newQueue = (MyStack*)malloc(sizeof(MyStack));
    newQueue->q1 =(Queue*)malloc(sizeof(Queue));
    newQueue->q2 =(Queue*)malloc(sizeof(Queue));
    QueueInit(newQueue->q1);
    QueueInit(newQueue->q2);
    return newQueue;
}

void myStackPush(MyStack* obj, int x) {
    Queue* empty = obj->q1;
    Queue* noempty = obj->q2;
    if(QueueEmpty(noempty))
    {
        empty = obj->q1;
        noempty = obj->q2;
    }
    QueuePush(noempty,x);
}

int myStackPop(MyStack* obj) {
    Queue* empty = obj->q1;
    Queue* noempty = obj->q2;
    int val = 0;
    if(QueueEmpty(noempty))
    {
        empty = obj->q2;
        noempty = obj->q1;
    }
    while(noempty->_size > 1)
    {
        int val = QueueFront(noempty);
        QueuePush(empty,val);
        QueuePop(noempty);
    }
    if(noempty->_size == 1)
    {
        val = QueueFront(noempty);
        QueuePop(noempty);
    }
    return val;
}

int myStackTop(MyStack* obj) {

    Queue* empty = obj->q1;
    Queue* noempty = obj->q2;
    int val = 0;
    if(QueueEmpty(noempty))
    {
        empty = obj->q2;
        noempty = obj->q1;
    }
    val = noempty->_rear->_data;
    return val;
}

bool myStackEmpty(MyStack* obj) {
    return QueueEmpty(obj->q1) && QueueEmpty(obj->q2);
}

void myStackFree(MyStack* obj) {
    Queue* empty = obj->q1;
    Queue* noempty = obj->q2;
    if(QueueEmpty(noempty))
    {
        empty = obj->q2;
        noempty = obj->q1;
    }
    QueueDestory(noempty);
    free(obj->q1);
    free(obj->q2);
    free(obj);
}

3. 用栈实现队列

stack1存放要进栈的元素

stack2存放要出栈的元素

当stack2为空时   将stack1的所有元素都导到stack2中

插入:

1.直接使用StackPush插入到stack1中

删除:

1.判断stack2是否为空,为空将stack1的数据导到stack2内

2.直接使用StackPop()取到栈顶元素返回

232. 用栈实现队列 - 力扣(LeetCode)

typedef struct {
    Stack* s1;
    Stack* s2;
} MyQueue;


MyQueue* myQueueCreate() {
    MyQueue* newQueue = (MyQueue*)malloc(sizeof(MyQueue));
    newQueue->s1 = (Stack*)malloc(sizeof(Stack));
    newQueue->s2 = (Stack*)malloc(sizeof(Stack));
    StackInit(newQueue->s1);
    StackInit(newQueue->s2);
    return newQueue;
}

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

int myQueuePop(MyQueue* obj) {
    if(StackEmpty(obj->s2))
    {
        while(!StackEmpty(obj->s1))
        {
            StackPush(obj->s2,StackPop(obj->s1));
        }
    }
    return StackPop(obj->s2);
}

int myQueuePeek(MyQueue* obj) {
    if(StackEmpty(obj->s2))
    {
        while(!StackEmpty(obj->s1))
        {
            StackPush(obj->s2,StackPop(obj->s1));
        }
    }
    return StcakTop(obj->s2);
}

bool myQueueEmpty(MyQueue* obj) {
    return StackEmpty(obj->s1) && StackEmpty(obj->s2);
}

void myQueueFree(MyQueue* obj) {
    StackDestory(obj->s1);
    StackDestory(obj->s2);
    free(obj->s1);
    free(obj->s2);
    free(obj);
}

4. 设计循环队列

622. 设计循环队列 - 力扣(LeetCode)

使用数组来设计循环队列,当head走到最后一个元素就使用%来使数组循环

head就是队头,tail就是队尾

从队头出数据,队尾入数据

题目要求队列长度为k,我们申请k+1个空间用来区分队列满和不满的情况

当head==tail就是队列为空
当tail的下一个位置的元素==head就表示队列为满




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


MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue* newQueue = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    newQueue->tail = newQueue->head = 0;
    newQueue->k = k + 1; 
    newQueue->Queue = (int*)malloc(sizeof(int)*(k+1));
    return newQueue;
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    return obj->head == obj->tail;
}

bool myCircularQueueIsFull(MyCircularQueue* obj) {
    return (obj->tail+1)%(obj->k) == obj->head;
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    if(myCircularQueueIsFull(obj))
    {
        return false;
    }
    obj->Queue[obj->tail] = value;
    obj->tail = (obj->tail+1)%(obj->k);
    return true;
}

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    {
        return false;
    }
    obj->head = (obj->head+1)%(obj->k);
    return true;
}

int myCircularQueueFront(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    return obj->Queue[obj->head];
}

int myCircularQueueRear(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    return obj->Queue[(obj->tail-1+obj->k) % obj->k];
}



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

栈的C语言代码:

typedef char StackDataType;
	
typedef struct StackNode
{
	StackDataType* _stack;
	int _capacity;
	int _top;
}Stack;

void StackInit(Stack* st);
void StackPush(Stack* st, StackDataType data);
void StackPop(Stack* st);
StackDataType StcakTop(Stack* st);
int StackSize(Stack* st);
int StackEmpty(Stack* st);
void StackDestory(Stack* st);
void StackInit(Stack* st)
{
	st->_stack = NULL;
	st->_capacity = 0;
	st->_top = 0;
}
void StackPush(Stack* st, StackDataType data)
{
	assert(st);
	if (st->_capacity == st->_top)
	{
        int newCapacity = st->_capacity == 0?4:st->_capacity*2;
		st->_stack = (StackDataType*)realloc(st->_stack, newCapacity * sizeof(StackDataType));
        st->_capacity = newCapacity;
	}
	st->_stack[st->_top] = data;
	st->_top++;
}
void StackPop(Stack* st)
{
	assert(st);
	assert(st->_top);
	st->_top--;
}
StackDataType StcakTop(Stack* st)
{
	assert(st);
	return st->_stack[st->_top-1];
}
int StackSize(Stack* st)
{
	assert(st);
	return st->_top;
}
int StackEmpty(Stack* st)
{
	assert(st);
	if (st->_top == 0)
	{
		return true;
	}
	else
	{
		return false;
	}
}
void StackDestory(Stack* st)
{
	assert(st);
	free(st->_stack);
    st->_stack = NULL;
	st->_capacity = st->_top = 0;

}

队列的C语言代码:

typedef int QueueNodeDataType;
typedef struct QListNode
{
	struct QListNode* _pNext;
	QueueNodeDataType _data;
}QNode;

typedef struct Queue
{
	QNode* _front;
	QNode* _rear;
	int _size;
}Queue;

void QueueInit(Queue* q);
void QueuePush(Queue* q, QueueNodeDataType val);
void QueuePop(Queue* q);
bool QueueEmpty(Queue* q);
int QueueSize(Queue* q);
QueueNodeDataType QueueFront(Queue* q);
QueueNodeDataType Queuerear(Queue* q);
void QueueDestory(Queue* q);
void QueueInit(Queue* q)
{
	assert(q);
	q->_front = NULL;
	q->_rear = NULL;
	q->_size = 0;
}
void QueuePush(Queue* q, QueueNodeDataType val)
{
	assert(q);
	QNode* newNode = (QNode*)malloc(sizeof(QNode));
	assert(newNode);
	newNode->_data = val;
	newNode->_pNext = NULL;
	if (q->_front == NULL)//队列没有结点
	{
		q->_front = q->_rear = newNode;
	}
	else
	{
		q->_rear->_pNext = newNode;
		q->_rear = newNode;
	}
	q->_size++;
}
void QueuePop(Queue* q)
{
	assert(q);
	if (q->_front == NULL)
	{
		return;
	}
	else
	{
		if (q->_front == q->_rear)//说明只有一个结点
		{
			free(q->_front);
			q->_front = q->_rear = NULL;
		}
		else
		{
			QNode* cur = q->_front->_pNext;
			free(q->_front);
			q->_front = cur;
		}
	}
	q->_size--;
}
bool QueueEmpty(Queue* q)
{
	assert(q);
	return q->_front == NULL;
}
int QueueSize(Queue* q)
{
	assert(q);
	return q->_size;
}
QueueNodeDataType QueueFront(Queue* q)
{
	assert(q);
	assert(q->_front);
	return q->_front->_data;
}
QueueNodeDataType Queuerear(Queue* q)
{
	assert(q);
	assert(q->_rear);
	return q->_rear->_data;
}
void QueueDestory(Queue* q)
{
	assert(q);
	QNode* cur = q->_front;
	while (cur)
	{
		QNode* tmp = cur;
		cur = cur->_pNext;
		free(tmp);
	}
	q->_front = q->_rear = NULL;

}

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

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

相关文章

Caffenie配合Redis做两级缓存,Redis发布订阅实现缓存一致更新

一、什么是两级缓存 在项目中。一级缓存用Caffeine,二级缓存用Redis,查询数据时首先查本地的Caffeine缓存,没有命中再通过网络去访问Redis缓存,还是没有命中再查数据库。具体流程如下 二、简单的二级缓存实现-v1 目录结构 2…

手写排班日历

手写排班日历&#xff1a; 效果图&#xff1a; vue代码如下&#xff1a; <template><div class"YSPB"><div class"title">排班日历</div><div class"banner"><span classiconfont icon-youjiantou click&qu…

【机器学习】分类与回归——掌握两大核心算法的区别与应用

【机器学习】分类与回归——掌握两大核心算法的区别与应用 1. 引言 在机器学习中&#xff0c;分类和回归是两大核心算法。它们广泛应用于不同类型的预测问题。分类用于离散的输出&#xff0c;如预测图像中的对象类型&#xff0c;而回归则用于连续输出&#xff0c;如预测房价。…

.net core 通过Sqlsugar生成实体

通过替换字符串的方式生成代码&#xff0c;其他代码也可以通这种方式生成 直接上代码 设置模板 将这几个模板文件设置为&#xff1a;嵌入资源 模板内容&#xff1a; using SqlSugar;namespace {Namespace}.Domain.Admin.{ModelName}; /// <summary> /// {TableDisplay…

浪潮光纤交换机FS8500、FS8600、FS8900端口数量授权扩容方法

浪潮光纤交换机FS8500、FS8600、FS8900系列是OEM博通G610、G620、G630光纤交换机&#xff0c;激活方法也是和博通一样的 获取设备License id 登录光纤交换机&#xff0c;可以使用Console线&#xff0c;也可以使用网线ssh登录默认ip&#xff1a;10.77.77.77&#xff0c;这里推…

【北京迅为】《STM32MP157开发板使用手册》- 第二十六章Cortex-M4 GPIO_蜂鸣器实验

iTOP-STM32MP157开发板采用ST推出的双核cortex-A7单核cortex-M4异构处理器&#xff0c;既可用Linux、又可以用于STM32单片机开发。开发板采用核心板底板结构&#xff0c;主频650M、1G内存、8G存储&#xff0c;核心板采用工业级板对板连接器&#xff0c;高可靠&#xff0c;牢固耐…

浅谈电动汽车公共充电桩布局设计及解决方案

摘要&#xff1a;随着社会现代化的深入推进&#xff0c;环境保护和资源利用可持续化发展的重要性愈发显著。电动汽车因其在节能、效率、环保等方面的突出优势&#xff0c;开始越来越多的进入城市交通系统。然而目前充电桩等相关配套设施缺乏合理的设置依据&#xff0c;不利于电…

【区块链通用服务平台及组件】中金数据云链平台 | FISCO BCOS应用案例

近年来&#xff0c;湖北省、武汉市区块链产业加快发展&#xff0c;在供应链管理、产品溯源等诸多领域逐步落地&#xff0c;形成了良好创新 创业氛围。2022 年 8 月&#xff0c;武汉市正式获批建设国家区块链发展先导区。中金数据&#xff08;武汉&#xff09;超算技术有限公司以…

组织数据能力评估模型一览

组织数据能力的成熟度等评估模型主要包括&#xff1a;DCMM、DSMM、DCAM、DAMA等。最新版《DMBOK2.1》 中&#xff0c;对于数据成熟度评估模型的选择给出了应考虑的标准&#xff1a; 可访问性&#xff1a;实践以非技术术语陈述&#xff0c;传达活动的功能要义。全面性&#xff…

HBase在大数据实时处理中的角色

HBase是一个分布式的、面向列的开源NoSQL数据库&#xff0c;它建立在Hadoop的HDFS之上&#xff0c;被设计用于处理大规模数据集。HBase非常适合于需要随机实时读写访问的应用程序&#xff0c;例如大数据分析、数据仓库和实时数据处理等场景。本文将探讨HBase是如何进行大数据实…

SpinalHDL之数据类型(六)

本文作为SpinalHDL学习笔记第五十九篇,介绍SpinalHDL的Vec数据类型。 目录: 1.描述(Description) 2.声明(Declaration) 3.操作符(Operators) ⼀、描述(Description) Vec是定义了⼀组带有标号的信号的复合信号(基于SpinalHDL基础类别)。 ⼆、声明(Declaration) 声明向量的…

最新消息,OpenAI o 1 一种新的大型语言模型正在被引入

据最新消息。 我们正在引入OpenAI o 1&#xff0c;这是一种新的大型语言模型&#xff0c;经过强化学习训练&#xff0c;可以执行复杂的推理。O 1在回答之前思考--它可以在对用户做出响应之前产生一个很长的内部思考链。 OpenAI o 1在竞争性编程问题&#xff08;Codeforces&am…

GaN挑战Si价格底线?英飞凌推出全球首个12英寸GaN晶圆技术

昨日&#xff0c;英飞凌宣布已成功开发出全球首个12英寸功率氮化镓GaN晶圆技术&#xff0c;并计划在今年的德国慕尼黑展上向公众展示首批12英寸GaN晶圆。 据英飞凌介绍&#xff0c;12英寸晶圆上的芯片生产在技术上更先进&#xff0c;效率也有显著提高&#xff0c;相较于8英寸晶…

Serverless 安全新杀器:云安全中心护航容器安全

作者&#xff1a;胡志广(独鳌) 云安全中心对于 Serverless 容器用户的价值 从云计算发展之初&#xff0c;各大云厂商及传统安全厂商就开始围绕云计算的形态来做安全解决方案。传统安全与云计算安全的形态与做法开始发生变化&#xff0c;同时随着这 10 多年的发展&#xff0c;…

JavaWeb开发中为什么Controller里面的方法是@RequestMapping?

在Java Web开发中&#xff0c;尤其是在使用Spring MVC框架时&#xff0c;RequestMapping注解被广泛应用于Controller层的方法上&#xff0c;这是因为RequestMapping是Spring MVC提供的一个核心注解&#xff0c;用于将HTTP请求映射到相应的处理器类或处理器方法上。通过这种方式…

安全隔离上网的有效途径:沙盒

在数字化浪潮日益汹涌的今天&#xff0c;网络安全成为了不可忽视的重要议题。沙箱技术作为一种高效的隔离机制&#xff0c;为企业和个人提供了一种在享受网络便利的同时&#xff0c;保障系统安全的解决方案。本文旨在深入探讨沙箱技术如何做到隔离上网&#xff0c;从而为用户提…

什么开放式耳机好用?2024五款宝藏品牌推荐!

在移动互联网时代&#xff0c;耳机已成为许多人生活中不可或缺的一部分&#xff0c;无论是在通勤路上还是运动时&#xff0c;它们都能提供音乐享受&#xff0c;同时减轻压力。然而&#xff0c;长时间佩戴入耳式耳机可能会引起耳道不适甚至炎症。因此&#xff0c;开放式耳机因其…

STM32 如何生成随机数

目录 一、引言 二、STM32 随机数发生器概述 三、工作原理 1.噪声源 2.线性反馈移位寄存器&#xff08;LFSR&#xff09; 3.数据寄存器&#xff08;RNG_DR&#xff09; 4.监控和检测电路&#xff1a; 5.控制和状态寄存器 6.生成流程 四、使用方法 1.使能随机数发生器 …

洛谷 P3065 [USACO12DEC] First! G

原题点这里​​​​​​ 题目来源于&#xff1a;洛谷 题目本质&#xff1a;字符串&#xff0c;Hash&#xff0c;字典树Trie 题目思路&#xff1a; 因为涉及到字典序的问题&#xff0c;那么应该能想到字典树。很显然字符串s1如果比字符串s2的字典序小的话&#xff0c;只有两种…

sms4j 发送短信

一、使用介绍 技术介绍&#xff1a; SMS4J: 短信 支持 阿里云 腾讯云 云片 等等各式各样的短信服务商 项目地址&#xff1a; SMS4J: 让简单的事情回归简单的本质。 SMS4J为短信聚合框架&#xff0c;帮您轻松集成多家短信服务&#xff0c;解决接入多个短信SDK的繁琐流程。 目前已…