03-数据结构-栈与队列

1.栈

77a8072800534dd1b6072ce98752205d.png

栈和队列是两种操作受限的线性表。如上图所示显示栈的结构

栈:先进后出,入栈(数据进入) 和出栈(数据出去)均在栈顶操作。

常见栈的应用场景包括括号问题的求解,表达式的转换和求值,函数调用和递归实现

1.1 栈的代码实现

#include<iostream>
#include<stdio.h>
#include<malloc.h>
#include<assert.h>typedef int STDataType;
typedef struct node
{STDataType x;struct node* next;
}node;
typedef struct Stack
{node* head;int nums;		// 长度
}Stack;// 初始化栈 
void StackInit(Stack* ps)
{assert(ps);ps->head = NULL;ps->nums = 0;
}// 入栈 
void StackPush(Stack* ps, STDataType data)
{assert(ps);node* new_node = (node*)malloc(sizeof(node));new_node->x = data;new_node->next = ps->head;ps->head = new_node;ps->nums++;
}// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
int StackEmpty(Stack* ps)
{assert(ps);return ps->nums == 0;
}// 出栈 
STDataType StackPop(Stack* ps)
{assert(ps);assert(!StackEmpty(ps));STDataType ret = ps->head->x;node* del = ps->head;ps->head = ps->head->next;free(del);ps->nums--;return ret;
}// 获取栈中有效元素个数 
int StackSize(Stack* ps)
{assert(ps);return ps->nums;
}// 销毁栈 
void StackDestroy(Stack* ps)
{assert(ps);node* tmp = ps->head;while (tmp){ps->head = ps->head->next;free(tmp);tmp = ps->head;}ps->head = NULL;ps->nums = 0;
}int main()
{Stack sta;StackInit(&sta);StackPush(&sta, 1);StackPush(&sta, 2);StackPush(&sta, 3);StackPush(&sta, 4);StackPush(&sta, 5);std::cout << StackSize(&sta) << std::endl;while (!StackEmpty(&sta)){printf("%d\n", StackPop(&sta));}
}

1.2 进制转化

#include <iostream>
#include <malloc.h>using namespace std;/**** 结 构 体 声 明 ****/
typedef struct scStack{struct scStack *next;int elem;
}scStack;/*余数入栈
*/
scStack *push(scStack *stack,int elem){scStack *newStack = (scStack *)malloc(sizeof(scStack));newStack->elem = elem;newStack->next = stack;stack = newStack;return stack;
}/*进制转换
*/
scStack *sysConvert(int num,int system,scStack *sys){while(num > 0){sys = push(sys,num % system);num /= system;}return sys;   //返回栈顶
}/*余数出栈
*/
void pop(scStack *stack){while(stack){scStack *top = stack;top->elem >= 10 ? printf("%c",top->elem + 'a' - 10) : printf("%d",top->elem);stack = stack->next;free(top);}cout<<endl<<"转换完毕!"<<endl;
}/*主函数
*/
int main(){scStack *stack = NULL; //初始化栈int num,system;cout<<"请输入一个10进制数:";cin>>num;cout<<"请输入想要转换为多少进制:";cin>>system;stack = sysConvert(num,system,stack);pop(stack);return 0;
}

1.3 括号匹配

#include<stdio.h>#define MaxSize 10typedef struct {    // 定义顺序栈int data[MaxSize];  // 静态数组存放栈中元素int top;    // 栈顶指针:指向目前栈顶元素的位置
} SeqStack;void InitStack(SeqStack &S) {S.top = -1;
}bool StackEmpty(SeqStack S) {if(S.top == -1) {return true;} else {return false;}
}bool Push(SeqStack &S, char x) {if(S.top == MaxSize - 1) {return false;}S.top = S.top + 1;S.data[S.top] = x;return true;
}bool Pop(SeqStack &S, char &x) {if(S.top == -1) {return false;}x = S.data[S.top];S.top = S.top - 1;return true;
}bool bracketCheck(char str[], int length) {SeqStack S;InitStack(S);for(int i = 0;i < length;i++) {if(str[i] == '(' || str[i] == '[' || str[i] == '{') {Push(S, str[i]);} else {if(StackEmpty(S)) {return false;}char topElem;Pop(S, topElem);if(str[i] == ')' && topElem != '(') {return false;}if(str[i] == ']' && topElem != '[') {return false;}if(str[i] == '}' && topElem != '{') {return false;}}}return StackEmpty(S);
}int main() {char A[] = "[([][])]";if(bracketCheck(A, 8)) {printf("A The match is successful\n");}else{printf("A The match is faild\n");}char B[] = "[([][]]";if(bracketCheck(B, 8)) {printf("B The match is successful\n");}else{printf("B The match is faild\n");}
}

1.4 递归

//X有n个盘子,从上到下有从小到大的顺序,有三个柱子X,Y, Z,把n个盘子从X移到Z,
//Y为辅助,并在移动过程中有一个约束条件就是大盘永远不能在小盘上面。
//
#include <stdio.h>
#include <stdlib.h>#define MAXSIZE 100typedef int ElemType;//盘子的结构
typedef struct//柱子(栈)的结构
{char name;ElemType* base;ElemType* top;
}StackType;int initstack(StackType* s,char name)
{s->name=name;s->base=(ElemType*)malloc(MAXSIZE*sizeof(ElemType));if(s->base==NULL)exit(0);s->top=s->base;return 1;}int push(StackType* s,ElemType e)
{if(s->top-s->base>=MAXSIZE)exit(0);*(s->top)=e;s->top++;return 1;
}ElemType pop(StackType* s)
{if(s->top==s->base)exit(0);s->top--;return *(s->top);
}int main()
{int all;int i;StackType X;StackType Y;StackType Z;initstack(&X,'X');initstack(&Y,'Y');initstack(&Z,'Z');while(1){printf("请输入X柱子开始有多少个盘子\n");scanf("%d",&all);for(i=all;i>0;i--){push(&X,i);}hannota(all,&X,&Y,&Z);}return 1;
}int hannota(int n,StackType* x,StackType* y,StackType* z)
{if(1==n){move(x,z);printf("from %c to %c\n",x->name,z->name);return 1;}hannota(n-1,x,z,y);//先解决n-1个盘子移到辅助柱子Y的汉洛塔问题move(x,z);//最后一个从x移到Zprintf("from %c to %c\n",x->name,z->name);hannota(n-1,y,x,z);//解决n-1个盘子移到柱子z的汉洛塔问题return 1;
}int move(StackType* s1,StackType* s2)
{ElemType temp;temp=pop(s1);push(s2,temp);return 1;
}

2.队列

队列的应用场景包括计算机系统中各种资源的管理,消息缓冲器的管理和广度优先搜索遍历等。

队列是先进先出,如上图所示,队列从队尾入队,从队头出队。队列有顺序队列,链队列和循环队列

2.1 链队列的代码实现

#include <stdio.h>
#include <malloc.h>
typedef char ElemType;
typedef struct DataNode
{	ElemType data;struct DataNode *next;
} DataNode;				//链队数据结点类型
typedef struct
{	DataNode *front;DataNode *rear;
} LinkQuNode;			//链队类型
void InitQueue(LinkQuNode *&q)
{	q=(LinkQuNode *)malloc(sizeof(LinkQuNode));q->front=q->rear=NULL;
}
void DestroyQueue(LinkQuNode *&q)
{DataNode *p=q->front,*r;//p指向队头数据结点if (p!=NULL)			//释放数据结点占用空间{	r=p->next;while (r!=NULL){	free(p);p=r;r=p->next;}}free(p);free(q);				//释放链队结点占用空间
}
bool QueueEmpty(LinkQuNode *q)
{return(q->rear==NULL);
}
void enQueue(LinkQuNode *&q,ElemType e)
{	DataNode *p;p=(DataNode *)malloc(sizeof(DataNode));p->data=e;p->next=NULL;if (q->rear==NULL)		//若链队为空,则新结点是队首结点又是队尾结点q->front=q->rear=p;else{	q->rear->next=p;	//将p结点链到队尾,并将rear指向它q->rear=p;}
}
bool deQueue(LinkQuNode *&q,ElemType &e)
{	DataNode *t;if (q->rear==NULL)		//队列为空return false;t=q->front;				//t指向第一个数据结点if (q->front==q->rear)  //队列中只有一个结点时q->front=q->rear=NULL;else					//队列中有多个结点时q->front=q->front->next;e=t->data;free(t);return true;
}
int main()
{LinkQuNode *q;     //创建队列q  ElemType e;InitQueue(q);   //初始化队enQueue(q,'a');enQueue(q,'b');enQueue(q,'c'); //依次进队a,b,cdeQueue(q,e);printf("%c\n",e);   //出队元素a deQueue(q,e);printf("%c\n",e);  //出队元素b deQueue(q,e);printf("%c\n",e);  //出队元素cDestroyQueue(q);  //销毁队 return 0; 
} 

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

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

相关文章

实验4.2 默认路由和浮动静态路由的配置

实验4.2 默认路由和浮动静态路由的配置 一、任务描述二、任务分析三、具体要求四、实验拓扑五、任务实施1.路由器的基本配置。2.配置默认路由&#xff0c;实现全网互通。3.配置浮动静态路由&#xff0c;实现链路备份。 六、任务验收七、任务小结八、知识链接1&#xff0e;默认路…

【Linux】Linux基础命令

本文使用工具为xshell7 同时借助阿里云服务器来完成演示 常用快捷键 &#xff1a;ctrlL 清屏 ctrlinsert 复制 shiftinsert 粘贴 登录成功界面 ls&#xff08;list&#xff09;命令 列出目录中的内容 列出当前/指定目录中都有哪些内容&#xff08;包含的文件和目录&#x…

常用的Webstrom插件

Active Tab Highlighter 高亮选中的tab Atom Material Icons 图标&#xff0c;个人觉得还是挺好看&#xff0c;各类分拣也能区分的很明显 Code Remark 代码标记 Gitmoji Plus git提交时候的小图标 GitToolBox git工具&#xff0c;免费版本就支持鼠标在哪一行就显示提交的信…

CSS自适应分辨率 amfe-flexible 和 postcss-pxtorem:大屏高宽自适应问题

前言 继上篇《CSS自适应分辨率 amfe-flexible 和 postcss-pxtorem》。 发现一个有趣的问题&#xff0c;文件 rem.js 中按照宽度设置自适应&#xff0c;适用于大多数页面&#xff0c;但当遇到大屏就不那么合适了。 问题 使用宽度&#xff0c;注意代码第2 和 4 行&#xff1a;…

安捷伦DSOX2012A示波器100 MHz

简  述&#xff1a;100 MHz、2 通道&#xff0c;超大的显示屏&#xff1a;8.5 英寸 WVGA 显示屏&#xff0c;高达 50,000 个波形/秒的更新速率&#xff0c;存储器存储深度&#xff1a;100 kpts &#xff0c;内置 20 MHz 函数发生器 Keysight(原Agilent) InfiniiVision DSOX2…

Sync and Refresh Project to update the path.

报错截图&#xff1a; 解决方案&#xff1a;卸载idea&#xff0c;重新安装idea、sdk、nodejs、ohpm&#xff08;主要原因就是版本不兼容的问题&#xff0c;我这里是nodejs版本问题&#xff0c;按照推荐重装后&#xff09;&#xff0c;问题解决&#xff01;&#xff01;&#xf…

Android Studio设置android:background 属性背景颜色

除了默认的颜色之外都要自己添加。 添加颜色的操作步骤&#xff1a; 打开res文件夹&#xff0c;找values&#xff0c;里面有个colors.xml的文件。然后在里面定义一些颜色。 完成

三相异步电机动态数学模型推导及矢量控制仿真

文章目录 **原文链接&#xff0c;点击跳转**三相异步电机动态数学模型及矢量控制仿真1、异步电机三相方程2、坐标变换3、磁链3/2变换推导4、两相静止坐标系下的方程5、两相旋转坐标系下的方程6、以 ω-is-Ψr 为状态变量的状态方程7、矢量控制及 matlab 仿真 原文链接&#xff…

adam优化器和动量

原始的SGD 加上动量&#xff08;惯性&#xff0c;每一次更新根据前面所有结果&#xff0c;使结果更快收敛&#xff09; AdaGrad 与SGD的核心区别在于计算更新步长时&#xff0c;增加了分母&#xff1a;梯度平方累积和的平方根。此项能够累积各个参数 的历史梯度平方&#xf…

边缘计算有哪些常用场景?TSINGSEE边缘AI视频分析技术行业解决方案

随着ChatGPT生成式人工智能的爆发&#xff0c;AI技术在业界又掀起一波新浪潮。值得关注的是&#xff0c;边缘AI智能也在AI人工智能技术进步的基础上得到了快速发展。IDC跟踪报告数据显示&#xff0c;2021年我国的边缘计算服务器整体市场规模达到33.1亿美元&#xff0c;预计2020…

KylinV10 安装 MySQL 教程(可防踩雷)

KylinV10 安装 MySQL 教程&#xff08;可防踩雷&#xff09; 1、直接用 apt 快捷安装 MySQL $ sudo apt-get update #更新软件源 $ sudo apt-get install mysql-server #安装mysql然后你会发现&#xff0c;KylinV10 安装畅通无阻&#xff0c;并没有设置密码的场景&#xff0c…

window之pycharm配置shell

cmd.exe "/K" e:\ProgramData\anaconda3\Scripts\activate.bat e:\ProgramData\anaconda3