顺序栈(数据结构括号匹配)
数据结构--栈和队列基础知识
数据结构--栈和队列基础知识⼀概述栈和队列,严格意义上来说,也属于线性表,因为它们也都⽤于存储逻辑关系为 "⼀对⼀" 的数据,但由于它们⽐较特殊,因此将其单独作为⼀篇⽂章,做重点讲解。
既然栈和队列都属于线性表,根据线性表分为顺序表和链表的特点,栈也可分为顺序栈和链表,队列也分为顺序队列和链队列,这些内容都会在本章做详细讲解。
使⽤栈结构存储数据,讲究“先进后出”,即最先进栈的数据,最后出栈;使⽤队列存储数据,讲究 "先进先出",即最先进队列的数据,也最先出队列。
⼆栈2.1 栈的基本概念同顺序表和链表⼀样,栈也是⽤来存储逻辑关系为 "⼀对⼀" 数据的线性存储结构,如下图所⽰。
从上图我们看到,栈存储结构与之前所了解的线性存储结构有所差异,这缘于栈对数据 "存" 和 "取" 的过程有特殊的要求:1. 栈只能从表的⼀端存取数据,另⼀端是封闭的;2. 在栈中,⽆论是存数据还是取数据,都必须遵循"先进后出"的原则,即最先进栈的元素最后出栈。
拿图 1 的栈来说,从图中数据的存储状态可判断出,元素 1 是最先进的栈。
因此,当需要从栈中取出元素 1 时,根据"先进后出"的原则,需提前将元素 3 和元素 2 从栈中取出,然后才能成功取出元素 1。
因此,我们可以给栈下⼀个定义,即栈是⼀种只能从表的⼀端存取数据且遵循 "先进后出" 原则的线性存储结构。
通常,栈的开⼝端被称为栈顶;相应地,封⼝端被称为栈底。
因此,栈顶元素指的就是距离栈顶最近的元素,拿下图中的栈顶元素为元素 4;同理,栈底元素指的是位于栈最底部的元素,下中的栈底元素为元素 1。
2.2 进栈和出栈基于栈结构的特点,在实际应⽤中,通常只会对栈执⾏以下两种操作:向栈中添加元素,此过程被称为"进栈"(⼊栈或压栈);从栈中提取出指定元素,此过程被称为"出栈"(或弹栈);2.3 栈的具体实现栈是⼀种 "特殊" 的线性存储结构,因此栈的具体实现有以下两种⽅式:1. 顺序栈:采⽤顺序存储结构可以模拟栈存储数据的特点,从⽽实现栈存储结构。
利用顺序栈解决括号匹配问题(c++)--数据结构
利⽤顺序栈解决括号匹配问题(c++)--数据结构题⽬:7-1 括号匹配(30 分)给定⼀串字符,不超过100个字符,可能包括括号、数字、字母、标点符号、空格,编程检查这⼀串字符中的( ) ,[ ],{ }是否匹配。
输⼊格式:输⼊在⼀⾏中给出⼀⾏字符串,不超过100个字符,可能包括括号、数字、字母、标点符号、空格。
输出格式:如果括号配对,输出yes,否则输出no。
输⼊样例1:sin(10+20)输出样例1:yes输⼊样例2:{[}]输出样例2:no分析:通过详读题⽬以及例题我们可以知道:程序会读⼊随机输⼊的⼀串字符串,⽽当只有 '('和')' 、'['和']' 、 '{'和'}'相匹配的时候输出“yes”,其他情况都会输出“no”。
这时候我们可以采⽤顺序栈的结构来解决这⼀个问题:将所有的左括号(即" ( 、[ 、{ ")存⼊栈中,遇到右括号(即" )、]、}")时出栈,再判断两者是否匹配。
代码:#include<iostream>#include<string.h>using namespace std;//定义栈#define max_size 200//栈的最⼤容量typedef char datatype;typedef struct{datatype zhan[max_size];int top;//栈顶}stack;//栈的初始化void initial(stack &st){st.top = 0;}//类型为datatype的x⼊栈void push(stack &st, datatype x){//当栈顶和max_size相等时,栈满if(st.top == max_size){// cout<<"This stack has already full!";cout<<"no";exit(0);}else{st.zhan[st.top] = x;st.top++;}}//出栈char pop(stack &st){if(st.top == 0){// cout<<"This stack is empty!";cout<<"no";exit(0);}else{st.top--;return st.zhan[st.top];}}int main(){stack s;initial(s);/*输⼊字符串,并将字符串放到字符数组中,实现能够逐个扫描字符串中的字符,并且不跳过空格符*/string str;getline(cin, str);char ch[200]={'\0'};strcpy(ch,str.c_str());//flag标志状态 1为括号匹配,0为不匹配int flag=1;int i;for(i=0; ch[i]!='\0'; i++){//元素若为{,(,[则⼊栈if((ch[i] == '{' )|| (ch[i] =='[') || (ch[i] =='(')){push(s, ch[i]);}//元素若为},),]则出栈赋值给aelse if((ch[i] == '}') || (ch[i] ==']') || (ch[i] ==')')){char a;a = pop(s);//若a与ch[i]匹配,进⾏下⼀个字符扫描if((a == '{' && ch[i] == '}') || (a == '(' && ch[i] == ')') || (a == '[' && ch[i] == ']')){ continue;}else flag = 0;}}if(s.top != 0){ //当左括号多出没有与右括号匹配的时候(如:" {() ")flag = 0}if(flag == 0){cout<<"no";}else cout<<"yes";return0;}编程过程中遇到的问题:1. 在对字符串进⾏⼊栈操作时s.top(栈顶)的数值不增加,总为1错误代码如下:运⾏结果如下:这段代码对于初学者来说看上去逻辑和操作过程似乎都没有问题,同时也困扰了我许久,在参考了《数据结构(c语⾔版)》李云清等编著的教程后,我发现我犯了⼀个致命的低级错误:编程push函数的时候,传⼊的参数为 stack st ,是不具有返回的功能,也就意味着在 push 函数中对于 st.top++ 这个操作没有更改主函数中st.top的数值。
数据结构括号匹配算法
括号匹配算法主要用于检查一个字符串中的括号是否匹配。
这个算法利用栈的后进先出(LIFO)性质,对输入的字符串进行检查。
以下是括号匹配算法的基本步骤:
1. 初始化一个空栈。
2. 遍历输入的字符串,对于每个字符:
* 如果字符是左括号('('、'{'、'['),将其压入栈中。
* 如果字符是右括号(')'、'}'、']'),检查栈顶的元素是否与之匹配。
如果匹配,则将栈顶元素弹出;否则,表示括号不匹配,返回错误。
3. 检查栈是否为空。
如果栈为空,表示所有括号都已匹配,返回成功;否则,表示还有未匹配的括号,返回错误。
在实现这个算法时,需要使用一个栈来存储左括号。
在遍历字符串的过程中,每遇到一个左括号,就将其压入栈中。
每遇到一个右括号,就检查栈顶的元素是否与之匹配。
如果匹配,则将栈顶元素弹出;否则,表示括号不匹配。
以上是括号匹配算法的基本思想。
具体的实现方式可能会因编程语
言和数据结构的不同而有所差异。
栈和队列先进先出和后进先出的数据结构
栈和队列先进先出和后进先出的数据结构栈和队列是常用的数据结构,它们分别以先进先出(FIFO)和后进先出(LIFO)的方式来组织和管理数据。
在许多编程语言中,栈和队列被广泛应用于解决各种问题。
本文将从定义、特点、应用和实现这几个方面来介绍栈和队列。
一、定义栈(Stack)是一种只允许在固定一端进行插入和删除操作的线性数据结构。
这一端被称为栈顶,而另一端被称为栈底。
栈的特点是先进后出。
队列(Queue)是一种先进先出的线性数据结构,允许在一端进行插入操作,而在另一端进行删除操作。
插入操作在队列的尾部进行,删除操作则在队列的头部进行。
二、特点2.1 栈的特点(1)插入和删除操作只能在栈顶进行,保证数据的顺序。
(2)栈是一种后进先出(LIFO)的数据结构,也就是最后插入的元素最先被删除。
(3)栈只能在栈顶进行插入和删除操作,不允许在中间或者底部进行操作。
2.2 队列的特点(1)插入操作只能在队列的尾部进行,保证数据的顺序。
(2)删除操作只能在队列的头部进行,始终删除最先插入的元素。
(3)队列是一种先进先出(FIFO)的数据结构,也就是最先插入的元素最早被删除。
三、应用3.1 栈的应用(1)函数调用和递归:栈被用于保存函数调用时的局部变量和返回地址。
(2)表达式求值:使用栈来实现中缀表达式转换为后缀表达式,然后计算结果。
(3)括号匹配:通过栈检查括号是否配对合法。
(4)浏览器的前进和后退:把浏览器的访问记录保存在栈中,方便前进和后退操作。
3.2 队列的应用(1)任务调度:使用队列管理任务,在现有任务执行完毕后按照先后顺序执行新任务。
(2)缓存管理:常用的缓存淘汰策略是先进先出,即最早进入缓存的数据最早被淘汰。
(3)消息队列:实现进程间的异步通信,提高系统的并发性和可扩展性。
(4)打印队列:打印任务按照先后顺序排队执行,保证打印的顺序。
四、实现栈和队列可以通过数组或链表来实现。
使用数组实现的栈和队列称为顺序栈和顺序队列,而使用链表实现的栈和队列称为链式栈和链式队列。
数据结构之顺序栈SqStack
数据结构之顺序栈SqStack顺序栈SqStack基本操作1 Status InitStack()//构造⼀个空栈S2 Status DestroyStack()//销毁栈S,S不再存在3 Status ClearStack()//把S置为空栈4 Status StackEmpty()//若S为空栈,则返回true,否则返回false5int StackLength()//返回S的元素个数,即栈的长度6 Status GetTop(SElemType &e)//若栈不空,则⽤e返回S的栈顶元素,并返回OK,否则返回ERROR7 Status Push(SElemType e)//插⼊元素e为新的栈顶元素8 Status Pop(SElemType &e)//若栈不空,则删除S的栈顶元素,并⽤e返回其值,并返回OK,否则返回ERROR9 Status StackTraverse(int p)//从栈底到栈顶依次对栈中每个元素调⽤函数visit().⼀旦visit()失败则操作失败⼏个⼩程序(代码正误检验,数制转换,括号匹配检验,⾏编辑程序)1 CheckStackCode();//测试Stack代码正确性2 Conversion();//数制转换3 BracketsMatching();//括号匹配的检验4 LineEdit();//⾏编辑程序1//2//by coolxxx3//#include<bits/stdc++.h>4 #include<iostream>5 #include<algorithm>6 #include<string>7 #include<iomanip>8 #include<map>9 #include<stack>10 #include<queue>11 #include<set>12 #include<bitset>13 #include<memory.h>14 #include<time.h>15 #include<stdio.h>16 #include<stdlib.h>17 #include<string.h>18//#include<stdbool.h>19 #include<math.h>20#define min(a,b) ((a)<(b)?(a):(b))21#define max(a,b) ((a)>(b)?(a):(b))22#define abs(a) ((a)>0?(a):(-(a)))23#define lowbit(a) (a&(-a))24#define sqr(a) ((a)*(a))25#define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))26#define mem(a,b) memset(a,b,sizeof(a))27#define eps (1e-10)28#define J 1000029#define mod 100000000730#define MAX 0x7f7f7f7f31#define PI 3.1415926535897932332#pragma comment(linker,"/STACK:1024000000,1024000000")33#define N 1043435using namespace std;36 typedef long long LL;37/*38double anss;39LL aans,sum;40int cas,cass;41int n,m,lll,ans;42*/434445const int OK=1;46const int ERROR=0;47const int INFEASIBLE=-1;48const int STACK_INIT_SIZE=100;//存储空间初始分配量49const int STACKINCREMENT=10;//存储空间分配增量50 typedef int Status;51 typedef int SElemType;5253 Status OutputInt(SElemType e);54 Status OutputChar(SElemType e);55 typedef struct56 {57 SElemType *base;//栈构造之前和销毁之后,base的值为NULL58 SElemType *top;//栈顶指针59int stacksize;//当前已分配的存储空间,以元素为单位6061 Status InitStack()//构造⼀个空栈S62 {63base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));64if(!base)exit(OVERFLOW);//存储分配失败65 top=base;66 stacksize=STACK_INIT_SIZE;67return OK;68 }//InitStack6970 Status DestroyStack()//销毁栈S,S不再存在71 {72free(base);73base=NULL;74 top=NULL;75 stacksize=0;76return OK;77 }//DestroyStack7879 Status ClearStack()//把S置为空栈80 {81 top=base;82return OK;83 }//ClearStack8485 Status StackEmpty()//若S为空栈,则返回true,否则返回false86 {87if(top==base)return true;88return false;89 }//StackEmpty9091int StackLength()//返回S的元素个数,即栈的长度92 {93return top-base;94 }//StackLength9596 Status GetTop(SElemType &e)//若栈不空,则⽤e返回S的栈顶元素,并返回OK,否则返回ERROR97 {98if(top==base)return ERROR;99 e=*(top-1);100return OK;101 }//GetTop102103 Status Push(SElemType e)//插⼊元素e为新的栈顶元素104 {105if(top-base>=stacksize)//栈满,追加存储空间106 {107base=(SElemType *)realloc(base,(stacksize+STACKINCREMENT)*sizeof(SElemType));108if(!base)exit(OVERFLOW);//存储分配失败109 top=base+stacksize;110 stacksize+=STACKINCREMENT;111 }112 (*top++)=e;113return OK;114 }//Push115116 Status Pop(SElemType &e)//若栈不空,则删除S的栈顶元素,并⽤e返回其值,并返回OK,否则返回ERROR 117 {118if(top==base)return ERROR;119 e=(*--top);120return OK;121 }//Pop122123 Status StackTraverse(int p)//从栈底到栈顶依次对栈中每个元素调⽤函数visit().⼀旦visit()失败则操作失败124 {125 SElemType *i=base;126 Status (*visit)(SElemType);127if(p==1)visit=OutputInt;128else if(p==0)visit=OutputChar;129while(top>i)130 visit(*i++);131 puts("");132return OK;133 }//StackTraverse134 }SqStack;135136 Status OutputInt(SElemType e)137 {138 printf("%d ",e);139return OK;140 }141 Status OutputChar(SElemType e)142 {143 printf("%c",e);144return OK;145 }146147148void CheckStackCode()149 {150 typedef int SElemType;151int i;152 SqStack S;153 SElemType e;154if(S.InitStack()==OK)155 {156for(i=1;i<=12;i++)157 S.Push(i);158 }159 printf("栈中元素依次为:");160 S.StackTraverse(1);161 S.Pop(e);162 printf("弹出的栈顶元素 e=%d\n",e);163 printf("栈空否:%d(1:空 0:否)\n",S.StackEmpty());164 S.GetTop(e);165 printf("栈顶元素 e=%d 栈的长度为%d\n",e,S.StackLength());166 S.Push(13);167 printf("栈中元素依次为:");168 S.StackTraverse(1);169 S.GetTop(e);170 printf("栈顶元素 e=%d 栈的长度为%d\n",e,S.StackLength());171 S.DestroyStack();172 printf("销毁栈后,S.top=%d S.base=%d S.stacksize=%d\n",S.top,S.base,S.stacksize); 173 }174175void Conversion()//对于输⼊的任意⼀个⾮负⼗进制整数n,打印输出与其等值的⼋进制数176 {177 typedef int SElemType;178int n;179 SqStack S;180 SElemType e;181182 S.InitStack();//构造空栈183 scanf("%d",&n);184while(n)185 {186 S.Push(n%8);187 n/=8;188 }189while(!S.StackEmpty())190 {191 S.Pop(e);192 printf("%d",e);193 }194 puts("");195196 S.DestroyStack();197 }198199void BracketsMatching()//三种括号()[]{},检验是否合法200 {201202char s[N];203 SqStack S;204 SElemType e;205int i;206 S.InitStack();207 scanf("%s",s);208209for(i=0;i<strlen(s);i++)210 {211if(s[i]=='(' || s[i]=='{' || s[i]=='[')212 S.Push(s[i]);213else if(s[i]==')' || s[i]=='}' || s[i]==']')214 {215if(S.GetTop(e) && ((e=='(' && s[i]==')') || (e=='[' && s[i]==']') || (e=='{' && s[i]=='}'))) 216 S.Pop(e);217else218 {219 puts("NO");220 S.DestroyStack();221return;222 }223 }224 }225if(S.StackEmpty())puts("YES");226else puts("NO");227 S.DestroyStack();228 }229230void LineEdit()//从终端接收⼀⾏并传送⾄调⽤过程的数据区,#为退格符,@为退⾏符231 {232int i;233char ch;234 SqStack S;235 SElemType e;236 S.InitStack();237while(ch!=EOF)238 {239for(ch=getchar();ch!=EOF && ch!='\n';ch=getchar())240 {241if(ch=='#')S.Pop(e);242else if(ch=='@')S.ClearStack();243else S.Push(ch);244 }245 S.StackTraverse(0);246 S.ClearStack();247 }248 S.DestroyStack();249 }250251252int main()253 {254 #ifndef ONLINE_JUDGEW255 freopen("1.txt","r",stdin);256// freopen("2.txt","w",stdout);257#endif258int i,j,k;259// init();260// for(scanf("%d",&cass);cass;cass--)261// for(scanf("%d",&cas),cass=1;cass<=cas;cass++)262// while(~scanf("%s",s))263/*264 while(~scanf("%d%d",&n,&m))265 {266267 }268*/269270 CheckStackCode();//测试Stack代码正确性271272 Conversion();//数制转换273274 BracketsMatching();//括号匹配的检验275276 LineEdit();//⾏编辑程序277278return0;279 }280/*281//282283//284*/马踏棋盘问题(NxN)暴⼒(顺序栈实现)1//3//#include<bits/stdc++.h>4 #include<iostream>5 #include<algorithm>6 #include<string>7 #include<iomanip>8 #include<map>9 #include<stack>10 #include<queue>11 #include<set>12 #include<bitset>13 #include<memory.h>14 #include<time.h>15 #include<stdio.h>16 #include<stdlib.h>17 #include<string.h>18//#include<stdbool.h>19 #include<math.h>20#define min(a,b) ((a)<(b)?(a):(b))21#define max(a,b) ((a)>(b)?(a):(b))22#define abs(a) ((a)>0?(a):(-(a)))23#define lowbit(a) (a&(-a))24#define sqr(a) ((a)*(a))25#define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))26#define mem(a,b) memset(a,b,sizeof(a))27#define eps (1e-10)28#define J 1000029#define mod 100000000730#define MAX 0x7f7f7f7f31#define PI 3.1415926535897932332#pragma comment(linker,"/STACK:1024000000,1024000000")33#define N 834using namespace std;35 typedef long long LL;36double anss;37 LL aans;38int cas,cass;39 LL n,m,lll,ans;40int a[N][N];41bool u[N][N];42int dx[]={-2,-1,1,2,2,1,-1,-2};43int dy[]={1,2,2,1,-1,-2,-2,-1};4445const int OK=1;46const int ERROR=0;47const int INFEASIBLE=-1;48const int STACK_INIT_SIZE=10000;//存储空间初始分配量49const int STACKINCREMENT=10000;//存储空间分配增量50 typedef int Status;5152 typedef struct53 {54int x,y,dir;55 }SElemType;5657 Status OutputInt(SElemType e);58 Status OutputChar(SElemType e);59 typedef struct60 {61 SElemType *base;//栈构造之前和销毁之后,base的值为NULL62 SElemType *top;//栈顶指针63int stacksize;//当前已分配的存储空间,以元素为单位6465 Status InitStack()//构造⼀个空栈S66 {67base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType)); 68if(!base)exit(OVERFLOW);//存储分配失败69 top=base;70 stacksize=STACK_INIT_SIZE;71return OK;72 }//InitStack7374 Status DestroyStack()//销毁栈S,S不再存在75 {76free(base);77base=NULL;78 top=NULL;79 stacksize=0;80return OK;81 }//DestroyStack8283 Status ClearStack()//把S置为空栈84 {85 top=base;87 }//ClearStack8889 Status StackEmpty()//若S为空栈,则返回true,否则返回false90 {91if(top==base)return true;92return false;93 }//StackEmpty9495int StackLength()//返回S的元素个数,即栈的长度96 {97return top-base;98 }//StackLength99100 Status GetTop(SElemType &e)//若栈不空,则⽤e返回S的栈顶元素,并返回OK,否则返回ERROR101 {102if(top==base)return ERROR;103 e=*(top-1);104return OK;105 }//GetTop106107 Status Push(SElemType e)//插⼊元素e为新的栈顶元素108 {109if(top-base>=stacksize)//栈满,追加存储空间110 {111base=(SElemType *)realloc(base,(stacksize+STACKINCREMENT)*sizeof(SElemType));112if(!base)exit(OVERFLOW);//存储分配失败113 top=base+stacksize;114 stacksize+=STACKINCREMENT;115 }116 (*top++)=e;117return OK;118 }//Push119120 Status Pop(SElemType &e)//若栈不空,则删除S的栈顶元素,并⽤e返回其值,并返回OK,否则返回ERROR 121 {122if(top==base)return ERROR;123 e=(*--top);124return OK;125 }//Pop126127 Status StackTraverse(int p)//从栈底到栈顶依次对栈中每个元素调⽤函数visit().⼀旦visit()失败则操作失败128 {129 SElemType *i=base;130 Status (*visit)(SElemType);131if(p==1)visit=OutputInt;132else if(p==0)visit=OutputChar;133while(top>i)134 visit(*i++);135 puts("");136return OK;137 }//StackTraverse138 }SqStack;139 Status OutputInt(SElemType e)140 {141 printf("%d ",e);142return OK;143 }144 Status OutputChar(SElemType e)145 {146 printf("%c",e);147return OK;148 }149150 SqStack S;151void print()152 {153int i,j;154for(i=0;i<N;i++,puts(""))155for(j=0;j<N;j++)156 printf("%d ",a[i][j]);157 puts("");158 }159int main()160 {161 #ifndef ONLINE_JUDGEW162 freopen("1.txt","r",stdin);163// freopen("2.txt","w",stdout);164#endif165int i,j,k;166int x,y,z,xx,yy;167// init();168// for(scanf("%d",&cass);cass;cass--)169// for(scanf("%d",&cas),cass=1;cass<=cas;cass++)170// while(~scanf("%s",s))171while(~scanf("%d%d",&n,&m))172 {173 mem(a,0);mem(u,0);174 S.InitStack();175 SElemType e,to;176 e.x=n,e.y=m,e.dir=-1;177 u[n][m]=1;178 S.Push(e);179 loop : while(S.top-S.base<N*N && !S.StackEmpty())180 {181 SElemType & now=*(S.top-1);182for(++now.dir;now.dir<8;now.dir++)183 {184 xx=now.x+dx[now.dir],yy=now.y+dy[now.dir];185if(xx>=0 && xx<N && yy>=0 && yy<N && !u[xx][yy]) 186 {187 u[xx][yy]=1;188 to.x=xx,to.y=yy,to.dir=-1;189 S.Push(to);190goto loop;191 }192 }193 S.Pop(e);194 u[e.x][e.y]=0;195 }196if(S.StackEmpty()){puts("No Answer\n");continue;}197 SElemType *id;198for(id=S.base,cas=0;id!=S.top;id++)199 {200 e=(*id);201 a[e.x][e.y]=++cas;202 }203 print();204 S.DestroyStack();205 }206return0;207 }马踏棋盘贪⼼优化1//2//by coolxxx3//#include<bits/stdc++.h>4 #include<iostream>5 #include<algorithm>6 #include<string>7 #include<iomanip>8 #include<map>9 #include<stack>10 #include<queue>11 #include<set>12 #include<bitset>13 #include<memory.h>14 #include<time.h>15 #include<stdio.h>16 #include<stdlib.h>17 #include<string.h>18//#include<stdbool.h>19 #include<math.h>20#define min(a,b) ((a)<(b)?(a):(b))21#define max(a,b) ((a)>(b)?(a):(b))22#define abs(a) ((a)>0?(a):(-(a)))23#define lowbit(a) (a&(-a))24#define sqr(a) ((a)*(a))25#define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))26#define mem(a,b) memset(a,b,sizeof(a))27#define eps (1e-10)28#define J 1000029#define mod 100000000730#define MAX 0x7f7f7f7f31#define PI 3.1415926535897932332#pragma comment(linker,"/STACK:1024000000,1024000000")33#define N 834using namespace std;35 typedef long long LL;36double anss;37 LL aans;38int cas,cass;39 LL n,m,lll,ans;40int a[N][N];41bool u[N][N];42int dx[]={-2,-1,1,2,2,1,-1,-2};43int dy[]={1,2,2,1,-1,-2,-2,-1};44struct xxx45 {46int c,num;47 };48bool cmp(xxx aa,xxx bb)49 {50return aa.c<bb.c;51 }52void print()53 {54int i,j;55for(i=0;i<N;i++,puts(""))56for(j=0;j<N;j++)57 printf("%d ",a[i][j]);58 puts("");59 }60void cal(int x,int y,xxx d[])61 {62int i,j,xx,yy,x1,y1;63for(i=0;i<8;i++)64 {65 d[i].c=0;d[i].num=i;66 xx=x+dx[i],yy=y+dy[i];67if(xx>=0 && xx<N && yy>=0 && yy<N && !u[xx][yy])68 {69 d[i].c++;70for(j=0;j<8;j++)71 {72 x1=xx+dx[j],y1=yy+dy[j];73if(x1>=0 && x1<N && y1>=0 && y1<N && !u[x1][y1])74 {75 d[i].c++;76 }77 }78 }79 }80 }81void dfs(int x,int y,int top)82 {83if(top==65)84 {85 print();86 lll++;87return;88 }89int i,j,xx,yy;90 xxx d[8];91 cal(x,y,d);92 sort(d,d+8,cmp);93for(i=0;i<8;i++)94 {95if(d[i].c==0)continue;96 j=d[i].num;97 xx=x+dx[j],yy=y+dy[j];98if(xx>=0 && xx<N && yy>=0 && yy<N && !u[xx][yy])99 {100 u[xx][yy]=1;101 a[xx][yy]=top;102 dfs(xx,yy,top+1);103if(lll==cas)return;104 u[xx][yy]=0;105 a[xx][yy]=0;106 }107 }108 }109int main()110 {111 #ifndef ONLINE_JUDGEW112// freopen("1.txt","r",stdin);113// freopen("2.txt","w",stdout);114#endif115int i,j,k;116int x,y,z,xx,yy;117// init();118// for(scanf("%d",&cass);cass;cass--)119// for(scanf("%d",&cas),cass=1;cass<=cas;cass++)120// while(~scanf("%s",s))121 puts("输⼊起点坐标和需要的解的数量");122while(~scanf("%d%d",&n,&m))123 {124 scanf("%d",&cas);125 j=clock();126 mem(a,0);mem(u,0);lll=0;127 a[n][m]=1;u[n][m]=1;128 dfs(n,m,2);129 k=clock();130 printf("⽤时 %.3lf s\n",0.001*(k-j));131 puts("输⼊起点坐标和需要的解的数量"); 132 }133return0;134 }。
栈与队列实现先进先出和后进先出的数据结构
栈与队列实现先进先出和后进先出的数据结构数据结构是计算机科学中一门重要的基础课程,其中栈(Stack)和队列(Queue)是常用的数据结构。
栈和队列都具有不同的特点和应用场景,能够满足先进先出(FIFO)和后进先出(LIFO)的要求。
一、栈的实现先进先出栈是一种线性数据结构,具有后进先出(LIFO)的特点。
在栈中,只能在栈的一端进行操作,称为栈顶。
栈的基本操作包括入栈(Push)和出栈(Pop)。
1. 入栈(Push)操作:当要向栈中添加元素时,将新元素放置在栈顶,并将栈顶指针向上移动一位。
该操作保证了后添加的元素会处于栈顶的位置。
2. 出栈(Pop)操作:当要从栈中移除元素时,将栈顶的元素弹出,并将栈顶指针向下移动一位。
该操作保证了最后添加的元素会最先被移除。
栈的实现可以使用数组或链表来存储元素。
使用数组实现时,需要指定栈的最大容量。
使用链表实现时,栈的容量可以动态扩展。
二、队列的实现先进先出队列是一种线性数据结构,具有先进先出(FIFO)的特点。
在队列中,元素从队尾入队,从队头出队。
队列的基本操作包括入队(Enqueue)和出队(Dequeue)。
1. 入队(Enqueue)操作:当要向队列中添加元素时,将新元素放置在队尾,并将队尾指针向后移动一位。
该操作保证了后添加的元素会处于队列的尾部。
2. 出队(Dequeue)操作:当要从队列中移除元素时,将队头的元素弹出,并将队头指针向后移动一位。
该操作保证了最早添加的元素会最先被移除。
队列的实现也可以使用数组或链表。
与栈不同的是,队列的实现更适合使用链表,因为链表可以实现在队头和队尾高效地执行插入和删除操作。
三、使用栈和队列实现先进先出和后进先出为了实现先进先出和后进先出的数据结构,可以使用一种特殊的数据结构:双端队列(Double-ended Queue),也称为双端栈(Deque)。
双端队列具有栈和队列的特点,既可以在队尾插入和删除元素,也可以在队头插入和删除元素。
数据结构 3.1栈和队列(顺序及链栈定义和应用)
假设从终端接受了这样两行字符: whli##ilr#e(s#*s) outcha@putchar(*s=#++);
则实际有效的是下列两行: while (*s) putchar(*s++);
例4:迷宫求解
通常用 “回溯 试探方 法”求 解
##########
# Q # $ $ $ #
#
# #$ $ $ # #
3.1 栈的类型定义
实例引进 考虑问题:一个死胡同,宽度只能够一辆车进 出,现有三辆汽车依次进入胡同停车,后A车 要离开,如何处理? 用计算机模拟以上问题
小花车
小明家 小花家 能能家 点点家 强强家
小花车
点点车 强强车
基本概念
栈(STACK) ——一种限定性的 数据结构,限定只能在表的一端 进行插入和删除的线性表。
# $ $ # #
#
## ##
##
# #
##
# # #
#
## # ## # # #
#
Q #
##########
求迷宫路径算法的基本思想
若当前位置“可通”,则纳入路径,继续( 向东)前进; 若当前位置“不可通”,则后退,换方向 继续探索; 若四周“均无通路”,则将当前位置从路 径中删除出去。
一 顺序栈
顺序栈存储的特点 顺序栈各个基本操作顺序实现 完整的顺序栈c语言程序 模拟停车场
一 顺序栈
存储特点
利用一组地址连续的存储单元依次存放 自栈底到栈顶的数据元素
c语言中可用数组来实现顺序栈
设置栈顶指针Top
elem[arrmax]
a1 a2 a3 a4
Top
top的值
elem[arrmax]
顺序栈的类型定义
1、顺序栈的类型定义#define StackSize 100 //假定预分配的栈空间最多为100 个元素typedef char ElementType;//假定栈元素的数据类型为字符typedef struct{ElementType data[StackSize];int top;}SeqStack;注意:①顺序栈中元素用向量存放;②栈底位置是固定不变的,可设置在向量两端的任意一个端点;③栈顶位置是随着入栈和出栈操作而变化的,用一个整型量top(通常称top 为栈顶指针)来指示当前栈顶位置。
2、顺序栈的结构注意:top 指向入栈是下一个元素将要存放的位置;top-1(减1)是指向出栈时下一个元素的取值位置。
栈空的条件:top==base;栈满的条件:top-base>=stacksize3、顺序栈的基本操作前提条件:设S 是SeqStack 类型的指针变量。
若栈底位置在向量的低端,即S->data[0]是栈底元素。
top:(1)进栈操作进栈时,需要将S->top 加1注意:①入栈操作前,需要查看栈是否已满,S->top==StackSize-1 表示栈满②"上溢"现象--当栈满时,再做入栈运算产生空间溢出的现象。
上溢是一种出错状态,应设法避免。
(2)出栈操作退栈时,需将S->top 减1注意:①出栈操作前需要考虑栈中是否有元素,S->top<0 表示空栈②"下溢"现象——当栈空时,做出栈运算产生的溢出现象。
下溢是正常现象,常用作程序控制转移的条件。
顺序栈在入栈和出栈操作时的具体变化情况,分别如下图所示:(1)置空栈 void InitStack(SeqStack * S) { //置空顺序栈。
空栈时,栈顶指针不能是0,而只能是-1 S->top=-1; } (2) 判栈空 int StackEmpty(SeqStack * S) { return S->top==-1: }(3) 进栈(入栈) void Push(SeqStack * S,DataType x) { if(s->top==StackSize-1)printf("stack overflow"); else { S->top=S->top+1; //栈顶指针加1 S->data[S->top]=x; //将x入栈 } } (4) 退栈(出栈) DataType Pop(SeqStack * S) { if(StackEmpty(S))printf("stack underflow"); else return S->data[S->top--]; //返回栈顶元素后栈顶指针减1 } (5) 取栈顶元素(不改变栈顶指针) DataType GetTop(SeqStack * S){ if(StackEmpty(S)) printf("stack empty"); else return s->data[s->top];//返回栈顶元素 }。
大学《数据结构》第三章:栈和队列-第一节-栈
第一节栈
一、栈的定义及其运算
1、栈的定义
栈(Stack):是限定在表的一端进行插入和删除运算的线性表,通常将插入、删除的一端称为栈项(top),另一端称为栈底(bottom)。
不含元素的空表称为空栈。
栈的修改是按后进先出的原则进行的,因此,栈又称为后进先出(Last In First Out)的线性表,简称为LIFO表。
真题选解
(例题·填空题)1、如图所示,设输入元素的顺序是(A,B,C,D),通过栈的变换,在输出端可得到各种排列。
若输出序列的第一个元素为D,则输出序列为。
隐藏答案
【答案】DCBA
【解析】根据堆栈"先进后出"的原则,若输出序列的第一个元素为D,则ABCD入栈,输出序列为DCBA
2、栈的基本运算
(1)置空栈InitStack(&S):构造一个空栈S。
数据结构实验——括号匹配的检验(附程序).
#include<stdio.h>#include<stdlib.h>typedef struct SNode{char data;struct SNode *next;}SNode,*Stack;typedef struct{Stack top;int length;}SqStack;//定义链式栈的结构体char InitStack(SqStack &S){S.top=NULL;S.length=0;return 0;}//初始化链式栈char Push(SqStack &S,char e) {Stack p;p=(Stack)malloc(sizeof(SNode)); if(!p)exit(0); p->data=e;p->next=S.top;S.top=p;S.length++;return 0;}//插入元素echar Pop(SqStack &S){if(!S.top)return 0;else{Stack q;q=S.top;S.top=S.top->next; --S.length;free(q);}return 0;}//删除栈顶元素echar main(){SqStack S;char w,e;InitStack(S);//初始化链式栈printf("提示:输入“ = ”表示输入表达式结束,程序将自动检查括号是否匹配\n\n\n");printf("请输入表达式:\n\n\n");scanf("%c",&w);printf("\n");printf("\n");while(w!='='){switch(w){case '(': Push(S,w);break;case '[': Push(S,w);break;case ')': if(!S.top)return 0;elsee=S.top->data; if(e=='(')Pop(S); break;case ']': if(!S.top)return 0;elsee=S.top->data; if(e=='[')Pop(S); break;default: break;}scanf("%c",&w);}if(S.top==NULL)printf("输入括号匹配\n");else printf("输入括号不匹配,请检查后重新输入\n");return 0;}。
顺序栈的操作课程设计
顺序栈的操作课程设计一、课程目标知识目标:1. 学生能理解顺序栈的基本概念,掌握其存储结构特点;2. 学生能掌握顺序栈的基本操作,包括入栈、出栈、查看栈顶元素等;3. 学生能了解顺序栈在实际应用场景中的使用方法。
技能目标:1. 学生能运用所学知识,独立编写顺序栈的基本操作函数;2. 学生能通过顺序栈解决实际问题,如括号匹配、逆波兰表达式求值等;3. 学生能分析顺序栈操作的时间复杂度和空间复杂度。
情感态度价值观目标:1. 学生通过学习顺序栈,培养对数据结构的好奇心和求知欲;2. 学生在学习过程中,养成团队协作、共同解决问题的良好习惯;3. 学生能认识到顺序栈在实际应用中的重要性,增强对计算机科学的热爱。
分析课程性质、学生特点和教学要求:1. 本课程为计算机科学与技术专业的高职二年级学生设计,旨在让学生掌握顺序栈的基本知识和操作方法;2. 学生已具备一定的编程基础和线性表知识,但可能对栈结构的应用场景了解不多;3. 教学要求注重理论与实践相结合,以培养学生的实际操作能力和解决实际问题的能力。
二、教学内容1. 顺序栈的基本概念与存储结构- 栈的定义与特点- 顺序栈的存储结构设计2. 顺序栈的基本操作- 入栈操作- 出栈操作- 查看栈顶元素- 判栈空与判栈满3. 顺序栈的应用场景- 括号匹配问题- 逆波兰表达式求值- 简单计算器实现4. 顺序栈的时间复杂度与空间复杂度分析- 各个操作的时间复杂度分析- 顺序栈的空间复杂度分析5. 实践环节- 编写顺序栈的基本操作函数- 实现顺序栈应用场景的案例- 分析并优化顺序栈操作的性能教学内容安排与进度:第一课时:顺序栈的基本概念与存储结构第二课时:顺序栈的基本操作及实现第三课时:顺序栈应用场景及案例实现第四课时:顺序栈的时间复杂度与空间复杂度分析第五课时:实践环节,编写代码并优化教材章节关联:本教学内容与《数据结构》教材中第四章“栈与队列”相关,主要涉及顺序栈的原理、操作与应用实例。
括号匹配问题
东华理工大学长江学院课程设计报告数据结构课题设计报告设计题目:括号匹配问题姓名:班级:学号:指导老师:二0一0年五月目录1.设计内容 (1)问题描述 (1)问题分析 (1)2.概要设计 (2)2-1模块一:初始化一个堆栈 (2)2-2模块二:进栈 (2)2-3模块三:测试堆栈是否为空 (2)2-4模块四:退栈 (2)2-5模块五:各模块间的调用关系 (2)3.算法描述 (3)3-1程序流程图: (3)3-2程序代码: (4)4.算法分析 (6)5.心得体会 (8)6.参考资料 (8)1.设计内容问题描述假设一个算术表达式中可包含三种括号:圆括号,方括号和花括号且这三种括号可按任意次序嵌套使用。
试利用栈的运算,编写判别给定表达式中所含括号是否正确配对出现的算法。
问题分析此程序须要完成如下要求:表达式中有三种括号:圆括号、方括号和花括号,嵌套顺序任意。
实现本程序需要解决:①用什么数据结构;②怎样实现判断括号是否匹配;③括号匹配与否有几种情况;④输出与输入数据的形式。
本程序的难点在于怎么判断括号是否匹配。
2.概要设计2-1模块一:初始化一个堆栈堆栈的顺序存储结构可以利用一个具有M个元素的数组STACK[0..M-1]来描述。
其中,STACK作为堆栈的名字,且不妨设:#define M 100 */定义堆栈的最大容量,并初始化栈顶指针变量top=-1。
2-2模块二:进栈在容量为M的堆栈中插入一个新的元素E[i],栈顶元素的位置由top指出。
新的数据元素进栈,将栈顶指针加1,然后将新的数据元素E[i]插入到修改以后的top指出的新的栈顶位置上。
2-3模块三:测试堆栈是否为空测试堆栈是的栈顶指针top是否为-1。
2-4模块四:退栈从堆栈中退出当前栈顶元素,并保存在变量item中,同时将栈顶指针减1修改栈顶指针位置。
2-5模块五:各模块间的调用关系首先创建一个堆栈并初始化,依次读入字符直到文件的末尾。
如果读得的字符为左括号,则将其压入堆栈。
栈c语言题目
栈是一种后进先出(LIFO)的数据结构,在C语言中通常使用数组或链表来实现。
以下是一些关于栈的C语言题目:
1. 栈的定义和基本操作:定义一个栈数据结构,实现推入(push)、弹出(pop)、查看栈顶(peek)等基本操作。
2. 栈的应用:使用栈解决括号匹配问题,例如给定一个只包含'('、')'、'{'、'}'、'['、']'的字符串,判断字符串是否有效。
3. 逆波兰表达式求值:给定一个逆波兰表达式,利用栈计算表达式的值。
4. 浏览器前进后退功能的模拟:使用两个栈来模拟浏览器的前进和后退功能。
5. 最小值栈:设计一个栈,除了正常的push/pop操作外,还支持查询当前栈中的最小元素。
6. 有效的括号序列:给定一个只包含'('、')'、'{'、'}'、'['、']'的字符串,判断字符串是否为有效的括号序列。
7. 用栈实现队列:仅使用栈来实现队列的操作,如enqueue、dequeue等。
8. 括号的最大嵌套深度:给定一个只包含'('、')'、'{'、'}'、'['、']'的字符串,求出合法括号序列的最大嵌套深度。
9. 逆序对问题:给定一个数组,找出所有逆序对。
10. 汉诺塔问题:使用栈来解决经典的汉诺塔问题。
数据结构课后答案第3章
第 3 章特殊线性表——栈、队列和串2005-07-14第 3 章特殊线性表——栈、队列和串课后习题讲解1. 填空⑴设有一个空栈,栈顶指针为1000H,现有输入序列为1、2、3、4、5,经过push,push,pop,push,pop,push,push后,输出序列是(),栈顶指针为()。
【解答】23,1003H⑵栈通常采用的两种存储结构是();其判定栈空的条件分别是(),判定栈满的条件分别是()。
【解答】顺序存储结构和链接存储结构(或顺序栈和链栈),栈顶指针top= -1和top=NULL,栈顶指针top等于数组的长度和内存无可用空间⑶()可作为实现递归函数调用的一种数据结构。
【解答】栈【分析】递归函数的调用和返回正好符合后进先出性。
⑷表达式a*(b+c)-d的后缀表达式是()。
【解答】abc+*d-【分析】将中缀表达式变为后缀表达式有一个技巧:将操作数依次写下来,再将算符插在它的两个操作数的后面。
⑸栈和队列是两种特殊的线性表,栈的操作特性是(),队列的操作特性是(),栈和队列的主要区别在于()。
【解答】后进先出,先进先出,对插入和删除操作限定的位置不同⑹循环队列的引入是为了克服()。
【解答】假溢出⑺数组Q[n]用来表示一个循环队列,front为队头元素的前一个位置,rear为队尾元素的位置,计算队列中元素个数的公式为()。
【解答】(rear-front+n)% n【分析】也可以是(rear-front)% n,但rear-front的结果可能是负整数,而对一个负整数求模,其结果在不同的编译器环境下可能会有所不同。
⑻用循环链表表示的队列长度为n,若只设头指针,则出队和入队的时间复杂度分别是()和()。
【解答】O(1),O(n)【分析】在带头指针的循环链表中,出队即是删除开始结点,这只需修改相应指针;入队即是在终端结点的后面插入一个结点,这需要从头指针开始查找终端结点的地址。
⑼串是一种特殊的线性表,其特殊性体现在()。
顺序栈实验报告心得与体会
顺序栈实验报告心得与体会
顺序栈是数据结构中比较基础的一种数据结构,它是一种线性数据结构,采用先进后出的原则,类似于箱子叠放,后进的箱子需要先取出来,这就是顺序栈的特点。
在学习顺序栈的过程中,我通过实验掌握了顺序栈的创建、入栈、出栈等基本操作,同时也深刻理解了顺序栈数据结构的特性。
首先,在创建顺序栈时,需要先确定栈的大小,通过开辟一定大小的数组来实现。
然后,需要定义两个指针:一个指向栈底,一个指向栈顶。
栈底指针始终指向数组第一个元素,而栈顶指针用于指示当前栈顶所在位置。
在进行入栈操作时,将数据元素插入到栈顶位置,同时栈顶指针加1;而在进行出栈操作时,将栈顶元素弹出,同时栈顶指针减1。
此外,在顺序栈的实验中,我也学到了一些相关的应用。
例如,在计算表达式的过程中,可以利用顺序栈来实现后缀表达式的计算。
同时,在进行算法设计时,顺序栈也是一种常用的数据结构,例如深度优先搜索(DFS)中的路径保存、括号匹配、逆波兰表达式等。
总的来说,通过实验,我对顺序栈数据结构有了更深入的理解,也学会了顺序栈的基本操作和应用,这对我今后的数据结构算法学习将有很大帮助。
Python中的栈
Python中的栈一、引言栈是一种常见的数据结构,它的特点是先进后出(Last In First Out,LIFO)。
在计算机领域,栈常用于函数调用和中缀表达式转后缀表达式等算法中。
Python作为一种强大的编程语言,自然也支持栈的使用。
本文将介绍Python中栈的基本概念、实现方法和使用场景等方面的内容,旨在帮助读者更深入地理解计算机中栈的概念和应用。
二、栈的概念栈是一种具有特定限制的线性数据结构,它具有先进后出的特点。
在栈结构中,只允许在栈顶部进行插入和删除等操作。
栈是一种操作受限制的线性结构,它的基本操作包括压栈(Push)和弹出(Pop)。
1.压栈压栈就是将一个元素加入到栈顶的过程。
在Python中,可以使用append方法实现在列表(List)中添加元素的操作,从而实现压栈的效果。
具体代码如下:stack = [] #定义一个空栈stack.append(1) #压入元素1stack.append(2) #压入元素22.弹出弹出就是将栈顶元素弹出的过程。
在Python中,可以使用pop方法实现在列表中删除元素的操作,从而实现弹出的效果。
具体代码如下:stack = [1, 2] #定义一个栈stack.pop() #弹出栈顶元素,即2stack.pop() #弹出栈顶元素,即1三、栈的实现方式在Python中,可以使用列表(List)实现栈结构。
因为Python 的列表支持动态扩容和缩容等操作,所以可以灵活地实现栈的操作。
1.基于列表的栈每个元素都存储在一个列表中,栈顶元素即为列表的末尾元素。
使用append方法可以实现在列表的末尾添加元素的操作,使用pop方法可以删除列表的末尾元素。
具体代码如下:class Stack:def __init__(self):self.items = []def push(self, item):self.items.append(item)def pop(self):return self.items.pop()def is_empty(self):return len(self.items) == 02.基于链表的栈栈的每个元素都存储在一个结点中,结点之间通过指针连接起来。
表达式括号匹配配对判断 大二数据结构实验
实验表达式括号匹配配对判断问题1,问题的描述假设一个算法表达式中包括圆括号,方括号两种,设计判别表达式中括号是否正确匹配的算法。
2,数据结构设计(1)匹配判别发生在右括号出现时,且被匹配的左括号应是距离右括号最近被输入的,二不是最先被输入的括号,即“先入后匹配”。
因此用栈来解决。
struct Node{int top;char data[stacksize];};Node node;void InitStack( ) // 初始化栈{node.top=-1;}(2)一是表达式的串;二是栈。
串可以采用顺序表表示。
所以采用顺序栈,站元素类型为字符型。
sqstack(int n){ base=newT[m];if(base=NULL){cout<<“创栈失败”;exit(1);}stacksize=m;top=-1;}}3,算法设计(1)进栈的算法设计voidPush(charx){if(node.top==stacksize-1);node.top++;node.data[node.top]=x;}(2)出栈的算法设计void Pop(char &x){if(node.top==-1);x=node.data[node.top--];}(3)判断是否匹配的算发。
如果右括号,进栈,取下个字符;如果是左括号,出栈,取下个字符;最后判断栈是否为空;得出结论。
3.1因为其中包含几种括号,所以用采用switch语句for(i=0;*(p+i)!='\0'&&count!=0;i++){switch (*(p+i)){case '(' :Push(*(p+i)) ;break ;case '[' :Push(*(p+i) ) ;break ;case ')' :{Pop(e) ;if ( e!='(' )count=0 ;};break ;case ']' :{Pop(e) ;if ( e!='[' )count=0 ;}; break ;default:break;}}3.2利用进出栈判断括号是否匹配if ( !StackEmpty () || count==0 ) //条件为:栈不空,而且有出现括号不匹配的情况{cout<<"括号无法匹配!"<<endl;cout<<"你想要继续吗?(y/n)"<<endl;cin>>s;if(s=='y'||s=='Y')goto input;else if(s=='n'||s=='N')cout<<"退出程序!"<<endl;return 0;}else{cout<<"括号能够匹配!"<<endl;cout<<"你想要继续吗?(y/n)"<<endl;cin>>s;if(s=='y'||s=='Y')goto input;else if(s=='n'||s=='N')cout<<"退出程序!"<<endl;return 0;}4.测试与运行(1)显示菜单,如下图:(2)运行结果如下图:5.调试的收获通过这次实验好的感觉到自己还有不足之处,一个程序高那么久才搞定,以后要多加练习。
2024年黑龙江省数据结构C语言版知识大全
一、线性表1.线性表的定义和基本操作:初始化、插入、删除、查找、修改、遍历。
2.线性表的顺序存储结构:使用一维数组实现线性表。
3.线性表的链式存储结构:使用链表实现线性表。
4.静态链表:使用数组模拟链表。
5.线性表的应用:多项式相加、括号匹配、栈的应用等。
二、栈和队列1.栈的定义和基本操作:初始化、入栈、出栈、取栈顶元素、判断栈空、判断栈满。
2.栈的应用:逆序输出、括号匹配、表达式求值等。
3.队列的定义和基本操作:初始化、入队、出队、取队头元素、判断队空、判断队满。
4.队列的顺序存储结构:使用一维数组实现队列。
5.队列的链式存储结构:使用链表实现队列。
6.队列的应用:进程调度算法、狗腿问题、银行排队等。
三、串1.串的定义和基本操作:初始化、插入、删除、查找、替换、连接、比较。
2.串的顺序存储结构:使用一维数组实现串。
3.串的链式存储结构:使用链表实现串。
4.串的模式匹配:朴素模式匹配算法、KMP算法。
四、树1.树的基本概念:节点、根、子树、叶子等。
2.二叉树的基本概念:满二叉树、完全二叉树、二叉树的遍历方式(前序、中序、后序)。
3.二叉树的顺序存储结构:使用一维数组实现二叉树。
4.二叉树的链式存储结构:使用链表实现二叉树。
5.二叉树的应用:表达式树、赫夫曼树。
6.线索二叉树:前驱节点和后继节点的操作。
五、图1.图的基本概念:顶点、边、度、路径、连通图等。
2.图的存储结构:邻接矩阵、邻接表。
3.图的遍历:深度优先(DFS)、广度优先(BFS)。
4. 最小生成树:Prim算法、Kruskal算法。
5. 最短路径:Dijkstra算法、Floyd算法。
六、排序和查找1.内部排序算法:冒泡排序、插入排序、选择排序、快速排序、归并排序、希尔排序、堆排序。
2.外部排序算法:多路归并排序。
3.查找算法:顺序查找、二分查找、哈希查找。
栈的应用举例
数据结构
栈的应用举例
1、数制转换(十转N)
设计思路:用栈暂存低位值
2、括号匹配问题
设计思路:用栈暂存左括号
3、子程序的调用
设计思路:用栈暂存指令地址
4、逆置一个单链表
设计思路:用栈暂存每一结点
例3.2 将十进制整数转换成二至九之间的任一进 制数输出
将一个十进制数4327转换成八进制数(10347)8:
void conversion(int N, int r)
解题思路如下:
{ int x=N,y=r; SeqStack *s;
s=InitStack(); while(Ns中;
{ Push(s, N %r ); N=N/r ;
2、用N/r代替N;
数据结构
解题思路如下:
1、建立一个带头结点的单链表 head; 2、输出该单链表; ; 3、建立一个空栈s(顺序栈); 4、依次将单链表的数据入栈; 5、依次将单链表的数据出栈, 并逐个将出栈的数据存入单链 表的数据域(自前向后);
6、再输出单链表。
linklist*backlinklist(linklist *head) {linklist *p;
3、若N>0,则重复 (1)、(2);若N=0, 则将栈s的内容依次出 栈。
}
printf(“\n 十 进 制 数 %d 所 对 应 的 %d 进 制 数是:”,x,y);
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include<stdlib.h>
#include<stdio.h>
/*初始化栈的最大空间值*/
#define INIT_STACK_SIZE 100
/*栈空间满后,空间的增量*/
#define STACKINCREMENT 10
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define NULL 0
typedef int Status;
typedef char ElemType;
typedef struct{
ElemType * Top;
ElemType *Base;
int StackSize;
}Stack;
/*初始化栈*/
Status InitStack(Stack *S){
S->Base=(ElemType *)malloc(INIT_STACK_SIZE * sizeof(ElemType)); if(!S->Base) exit(OVERFLOW);
S->Top=S->Base;
S->StackSize=INIT_STACK_SIZE;
return OK;
}
/*销毁栈*/
Status DestroyStack(Stack *S){
free(S->Base);
S->Base=NULL;
S->Top=NULL;
S->StackSize=0;
return OK;
}
/*清空栈*/
Status ClearStack(Stack *S){
S->Base=S->Top;
return OK;
}
/*判断栈是否空*/
Status StackEmpty(Stack S){
if(S.Base==S.Top) return TRUE;
return FALSE;
}
/*求的栈的长度*/
int StackLength(Stack S){
int i=0;
i=S.Top-S.Base;
return i;
}
/*获取栈顶的值*/
Status GetTop(Stack S,ElemType *e){
*e=*(S.Top-1);
return OK;
}
/*入栈*/
Status Push(Stack *S,ElemType e){
if((S->Top-S->Base)>=S->StackSize){
S->Base=(ElemType *)realloc(S->Base,(S->StackSize+STACKINCREMENT)*sizeof(ElemType)); if(S->Base) exit(OVERFLOW);
S->Top=S->Base+S->StackSize;
S->StackSize+=STACKINCREMENT;
}
*(S->Top++)=e;
return OK;
}
/*出栈*/
Status Pop(Stack *S,ElemType *e){
if(S->Top==S->Base) return ERROR;
*e=*(--S->Top);
return OK;
}
main()
{
Stack S;
ElemType e;
int flag,length,i;
flag=1;
if(InitStack(&S))
printf("InItStack S is Sussfully!\ninput the Brackets and press '#' to show the end:\n"); while(e!='#'&&flag){
ElemType x;
scanf("%c",&e);
switch (e){
case '(':
if(!StackEmpty(S)){ GetTop(S,&x);if(x=='(') flag=0;else Push(&S,e);}
else Push(&S,e);
break;
case '[':
if(!StackEmpty(S)){ GetTop(S,&x);if(x=='('|x=='[') flag=0;else Push(&S,e);}
else Push(&S,e);
break;
case '{':
if(!StackEmpty(S)){ GetTop(S,&x);if(x=='('|x=='['|x=='{') flag=0;else Push(&S,e);}
else Push(&S,e);
break;
case ')':
if(!StackEmpty(S)){GetTop(S,&x);if(x=='(') Pop(&S,&e);else flag=0;}
else flag=0;
break;
case ']':
if(!StackEmpty(S)){GetTop(S,&x);if(x=='[') Pop(&S,&e);else flag=0;}
else flag=0;
break;
case '}':
if(!StackEmpty(S)){GetTop(S,&x);if(x=='{') Pop(&S,&e);else flag=0;}
else flag=0;
break;
}
}
length=StackLength(S);
for(i=length;i>=1;i--){
Pop(&S,&e);printf("%c",e);
}
if(flag)
printf("\nMatch!\n");
else
printf("Match Miss!\n");
if(DestroyStack(&S))
printf("DestroyStack S is Sussfully!\n"); else
printf("DestroyStack S is Miss!\n"); printf("press any key to continue!\n"); getch();
return 0;
}。