C语言数据结构-----栈和队列练习题(分析+代码)

前言

前面的博客写了如何实现栈和队列,下来我们来看一下队列和栈的相关习题。

链接: 栈和队列的实现

文章目录

  • 前言
  • 1.用栈实现括号匹配
  • 2.用队列实现栈
  • 3.用栈实现队列
  • 4.设计循环队列


1.用栈实现括号匹配

在这里插入图片描述

此题最重要的就是数量匹配和顺序匹配。
用栈可以完美的做到:
1.左括号入栈
2.有右括号,取栈顶左括号匹配

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
typedef char STDataType;typedef struct Stack
{STDataType* a;int top;		// 标识栈顶位置的int capacity;
}ST;void STInit(ST* pst);
void STDestroy(ST* pst);// 栈顶插入删除
void STPush(ST* pst, STDataType x);
void STPop(ST* pst);
STDataType STTop(ST* pst);bool STEmpty(ST* pst);
int STSize(ST* pst);void STInit(ST* pst)
{assert(pst);pst->a = NULL;pst->capacity = 0;// 表示top指向栈顶元素的下一个位置pst->top = 0;// 表示top指向栈顶元素
//pst->top = -1;
}void STDestroy(ST* pst)
{assert(pst);free(pst->a);pst->a = NULL;pst->top = pst->capacity = 0;
}// 栈顶插入删除
void STPush(ST* pst, STDataType x)
{assert(pst);if (pst->top == pst->capacity){int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;STDataType* tmp = (STDataType*)realloc(pst->a, sizeof(STDataType) * newcapacity);if (tmp == NULL){perror("realloc fail");return;}pst->a = tmp;pst->capacity = newcapacity;}pst->a[pst->top] = x;pst->top++;
}void STPop(ST* pst)
{assert(pst);// 不为空assert(pst->top > 0);pst->top--;
}STDataType STTop(ST* pst)
{assert(pst);// 不为空assert(pst->top > 0);return pst->a[pst->top - 1];
}bool STEmpty(ST* pst)
{assert(pst);/*if (pst->top == 0){return true;}else{return false;}*/return pst->top == 0;
}int STSize(ST* pst)
{assert(pst);return pst->top;
}
//这里以上都是栈的代码
bool isValid(char* s)
{ST st;STInit(&st);while (*s){if (*s == '[' || *s == '(' || *s == '{'){STPush(&st, *s);}else{if (STEmpty(&st)!=NULL)//右括号比左括号多{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;
}

2.用队列实现栈

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
这样感觉没什么用,很低效,但是这题考的就是我们对于队列和栈性质的理解!

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
typedef int QDataType;
typedef struct QueueNode
{QDataType val;struct QueueNode* next;
}QNode;typedef struct Queue
{QNode* phead;QNode* ptail;int size;
}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);
bool QueueEmpty(Queue* pq);
int QueueSize(Queue* pq);void QueueInit(Queue* pq)
{assert(pq);pq->phead = pq->ptail = NULL;pq->size = 0;
}void QueueDestroy(Queue* pq)
{assert(pq);QNode* cur = pq->phead;while (cur){QNode* next = cur->next;free(cur);cur = next;}pq->phead = pq->ptail = NULL;pq->size = 0;
}void QueuePush(Queue* pq, QDataType x)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");return;}newnode->val = x;newnode->next = NULL;if (pq->ptail == NULL){pq->ptail = pq->phead = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}void QueuePop(Queue* pq)
{assert(pq);// assert(pq->phead);QNode* del = pq->phead;pq->phead = pq->phead->next;free(del);del = NULL;if (pq->phead == NULL)pq->ptail = NULL;pq->size--;
}QDataType QueueFront(Queue* pq)
{assert(pq);// assert(pq->phead);return pq->phead->val;
}QDataType QueueBack(Queue* pq)
{assert(pq);// assert(pq->ptail);return pq->ptail->val;
}bool QueueEmpty(Queue* pq)
{assert(pq);return pq->phead == NULL;
}int QueueSize(Queue* pq)
{assert(pq);return pq->size;
}
//这里之前都是队列的代码
typedef struct //匿名结构体
{Queue q1;Queue q2;
} MyStack;MyStack* myStackCreate() 
{MyStack* pst = (MyStack*)malloc(sizeof(MyStack));QueueInit(&pst->q1);QueueInit(&pst->q2);return pst;
}void myStackPush(MyStack* obj, int x) //插入,哪个不为空就往哪里插,都为空随便进一个都行
{if (!QueueEmpty(&obj->q1))QueuePush(&obj->q1, x);elseQueuePush(&obj->q2, x);
}int myStackPop(MyStack* obj) 
{//假设q1为空,q2不为空Queue* emptyq=&obj->q1;Queue* nonemptyq=&obj->q2;if (!QueueEmpty(&obj->q1))//如果假设错了,就交换{emptyq = &obj->q2;nonemptyq = &obj->q1;   }//非空队列钱N-1个元素导入空队列,最后一个就是栈顶元素while (QueueSize(nonemptyq)>1){QueuePush(emptyq, QueueFront(nonemptyq));//将非空队列插入空队列QueuePop(nonemptyq);//删掉}//并返回栈顶元素int top=QueueFront(nonemptyq);QueuePop(nonemptyq);return top;
}int myStackTop(MyStack* obj) 
{//谁不为空就返回谁的队尾数据,队尾数据就是导数据之后栈顶的数据if (!QueueEmpty(&obj->q1))return QueueBack(&obj->q1);elsereturn 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);
}

3.用栈实现队列

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

和队列实现栈的思路一样,主要考察栈和队列的性质

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>typedef int STDataType;typedef struct Stack
{STDataType* a;int top;		// 标识栈顶位置的int capacity;
}ST;void STInit(ST* pst);
void STDestroy(ST* pst);// 栈顶插入删除
void STPush(ST* pst, STDataType x);
void STPop(ST* pst);
STDataType STTop(ST* pst);bool STEmpty(ST* pst);
int STSize(ST* pst);void STInit(ST* pst)
{assert(pst);pst->a = NULL;pst->capacity = 0;// 表示top指向栈顶元素的下一个位置pst->top = 0;// 表示top指向栈顶元素//pst->top = -1;
}void STDestroy(ST* pst)
{assert(pst);free(pst->a);pst->a = NULL;pst->top = pst->capacity = 0;
}// 栈顶插入删除
void STPush(ST* pst, STDataType x)
{assert(pst);if (pst->top == pst->capacity){int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;STDataType* tmp = (STDataType*)realloc(pst->a, sizeof(STDataType) * newcapacity);if (tmp == NULL){perror("realloc fail");return;}pst->a = tmp;pst->capacity = newcapacity;}pst->a[pst->top] = x;pst->top++;
}void STPop(ST* pst)
{assert(pst);// 不为空assert(pst->top > 0);pst->top--;
}STDataType STTop(ST* pst)
{assert(pst);// 不为空assert(pst->top > 0);return pst->a[pst->top - 1];
}bool STEmpty(ST* pst)
{assert(pst);/*if (pst->top == 0){return true;}else{return false;}*/return pst->top == 0;
}int STSize(ST* pst)
{assert(pst);return pst->top;
}
//以上为栈的代码
typedef struct 
{ST pushst;//入数据栈ST popst;//出数据栈
} MyQueue;MyQueue* myQueueCreate() 
{MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));STInit(&obj->popst);STInit(&obj->pushst);return obj;
}void myQueuePush(MyQueue* obj, int x) 
{STPush(&obj->pushst, x);
}int myQueuePop(MyQueue* obj)
{int front = myQueuePeek(obj);//有数据不动,没数据导数据STPop(&obj->popst);return front;
}int myQueuePeek(MyQueue* obj) //返回队列开头的元素
{if (STEmpty(&obj->popst))//如果popst不为空,跳到最后返回栈顶元素{                        while (!STEmpty(&obj->pushst)){//popst为空,那就导数据,把pushst的数据导入popst,再返回栈顶元素STPush(&obj->popst, STTop(&obj->pushst));STPop(&obj->pushst);}}return STTop(&obj->popst);//返回栈顶元素
}bool myQueueEmpty(MyQueue* obj) 
{return STEmpty(&obj->popst) && STEmpty(&obj->pushst);
}void myQueueFree(MyQueue* obj) 
{STDestroy(&obj->popst);STDestroy(&obj->pushst);free(obj);
}

部分函数的结构如下:
在这里插入图片描述

4.设计循环队列

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdbool.h>typedef struct
{int* a;//数组指针(一开始开的空间)int front;//头int back;//尾int k;//数据个数
} MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k)
{MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));obj->a = (int*)malloc(sizeof(int) * (k + 1));obj->front = 0;obj->back = 0;obj->k = k;return obj;
}bool myCircularQueueIsEmpty(MyCircularQueue* obj)
{return obj->front == obj->back;//头等于尾是空
}bool myCircularQueueIsFull(MyCircularQueue* obj)
{return (obj->back + 1) % (obj->k + 1) == obj->front;//上述图片分析出的公式
}bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) //插入
{if (myCircularQueueIsFull(obj))return false;              //如果满了就返回错obj->a[obj->back] = value;obj->back++;obj->back %= (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) //从队首获取元素。如果队列为空,返回 -1 。
{if (myCircularQueueIsEmpty(obj))return -1;return obj->a[obj->front];
}int myCircularQueueRear(MyCircularQueue* obj) //获取队尾元素。如果队列为空,返回 -1 。
{if (myCircularQueueIsEmpty(obj))return -1;if (obj->back == 0)return obj->a[obj->k];elsereturn obj->a[obj->back - 1];
}void myCircularQueueFree(MyCircularQueue* obj)
{free(obj->a);free(obj);
}

部分代码结构如下:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习:全面了解深度学习-从理论到实践

深度学习&#xff1a;全面了解深度学习-从理论到实践 摘要&#xff1a;本文旨在为读者提供一份全面的深度学习指南&#xff0c;从基本概念到实际应用&#xff0c;从理论数学到实践技术&#xff0c;带领读者逐步深入了解这一领域。我们将一起探讨深度学习的历史、发展现状&#…

【挑战业余一周拿证】二、在云中计算 - 第 1 节 - 模块2 简介

第 1 节 - 模块2 简介 无论你的企业是属于像医疗、保健、制造、保险等等行业 , 再或者 , 您的服务是向全世界的数百万用户提供视频、、图片或者文字服务,你也需要服务器来为您的业务和应用程序提供支持,服务器的作用是帮助您托管应用程序并提供满足您业务需求的计算能力. 当你使…

三种常见的哈希结构

1.数组 2.set 使用序引用set头文件 unordered_set需引用unordered_set 3.map unordered_map需引用unordered_map头文件

三维gis中用纹理限定多边形地理区域

在三维 gis 中经常需要在指定的多边形地理范围内做一些操作&#xff0c;比如地形的多边形裁剪、压平多边形区域内的倾斜摄影模型、在指定地理范围内绘制等间距的点等。这都涉及到限定多边形区域的问题。 所谓的限定多边形地理区域&#xff0c;核心问题在于判断某个片元是否处于…

java学习part12多态

99-面向对象(进阶)-面向对象的特征三&#xff1a;多态性_哔哩哔哩_bilibili 1.多态&#xff08;仅限方法&#xff09; 父类引用指向子类对象。 调用重写的方法&#xff0c;就会执行子类重写的方法。 编译看引用表面类型&#xff0c;执行看实际变量类型。 2.父子同名属性是否…

同旺科技 USB 转 RS-485 适配器 -- 隔离型

内附链接 1、USB 转 RS-485 适配器 隔离版主要特性有&#xff1a; ● 支持USB 2.0/3.0接口&#xff0c;并兼容USB 1.1接口&#xff1b; ● 支持USB总线供电&#xff1b; ● 支持Windows系统驱动&#xff0c;包含WIN10 / WIN11 系统32 / 64位&#xff1b; ● 支持Windows …

Vue3-基于husky的代码检查工作流

husky是一个git hooks工具&#xff08;git的钩子工具&#xff0c;可以在特定时机执行特定的命令&#xff09; 代码检查 背景&#xff1a;想要使代码上传到git仓库前进行代码检查&#xff0c;所以提前下载好git 打开项目终端&#xff0c;点击右上角选择进入Git Bash控制 1.如…

AWVS 使用方法归纳

1.首先确认扫描的网站&#xff0c;以本地的dvwa为例 2.在awvs中添加目标 输入的地址可以是域名也可以是ip&#xff0c;只要本机可以在浏览器访问的域名或ip即可 添加地址及描述之后&#xff0c;点击保存&#xff0c;就会展现出目标设置选项 business criticality译为业务关键…

Ubuntu 20.0 + mysql 8.0 用户和密码修改

第一步 下载&#xff08;简单,注意联网&#xff09;Ubuntu 终端输入以下两行命令 (1) 数据库的服务端及客户端数据库的开发软件包 sudo apt-get install mysql-server mysql-client (2) 数据库的开发软件包 sudo apt-get install libmysqlclient-dev 第二步 查看是否安装成功 …

ELK日志系统

&#xff08;一&#xff09;ELK 1、elk&#xff1a;是一套完整的日志集中处理方案&#xff0c;由三个开源的软件简称组成 2、E&#xff1a;ElasticSearch&#xff08;ES&#xff09;&#xff0c;是一个开源的&#xff0c;分布式的存储检索引擎&#xff08;索引型的非关系型数…

MX6ULL学习笔记 (一)交叉工具链的安装

前言&#xff1a; ARM 裸机、Uboot 移植、Linux 移植这些都需要在 Ubuntu 下进行编译&#xff0c;编译就需要编译 器&#xff0c;Ubuntu 自带的 gcc 编译器是针对 X86 架构的&#xff01;而我们现在要编译的是 ARM 架构的代码&#xff0c;因为我们编译的代码是需要烧写到ARM板子…

字符串逆序问题

写一个函数&#xff0c;可以将任意输入的字符串逆序&#xff08;要可以满足多组输入&#xff09; 这个题有三个点 1.要读入键盘输入的字符串&#xff0c;所以要用到字符串输入函数 2.可以进行多组输入 3.把输入的n组字符串都逆序 #define _CRT_SECURE_NO_WARNINGS 1 #incl…