第3章学习小结
一
学习小结
第3章学习关于栈和队列的线性表示和链式表示,及以下知识点
1.调用函数是栈结构——先进后出
2.递归算法 优:结构清晰,程序可读性强 缺:时间,空间开销大 可以用循环将递归转为迭代
3.使用rear=(rear+1)%MAXSIZE实现循环队列,同理也可以用于限定随机数的范围
4.为了避免判断队满队空都为Q.front=Q.rear,而出现错误,可以少用一个元素的空间,尾指针指向最后一个元素的后一个空间,当Q.front=Q.rear则为队空,当(Q.rear+1)%MAXSIZE==Q.front 时,则队满
5.链队头部入队,尾部出队(若头部出队,则其后元素的地址丢失)
二
完成作业的心得体会
在括号匹配这道题中,因为老师在课堂上为我们梳理了思路,在实际打代码过程中,不断往老师说的框架中填充,拓展,完善,最后完成了这道题,//确实如老师所言,写代码不要一开始就入手#include <iostream>……,先想好大概怎么做,思路清晰,再写不迟.。通过这道题还学会了用flag标记括号当前是否匹配,匹配置1,不匹配为0,最后通过判断flag的值来判断最终是否匹配
在完成银行业务队列简单模拟时,总是输出不了C队列,看代码看了很久都没发现问题在哪,最后才知道原来把A/B队列中元素入队到C队后,漏了A.front=(A.front+1)%MAXSIZE;这一步,还是不够细心,导致多耗了许多时间,磨刀不误砍柴工
三
关于上次确定的目标及接下来的目标
上次希望写代码可以脱离教材,但是后来得知这样抗拒书本的代码,其他人的代码反而效率更低,要内化成自己的知识,熟练运用还需要接下来多加练习
接下来要保证每周都至少要打一个代码,从一个起,熟悉后,速度提高了再增加量
括号匹配
#include <iostream>
#include <cstdlib>
using namespace std;
#include <cstdlib>
using namespace std;
#define MAXSIZE 100000 //顺序栈存储空间的初始分配量
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef char ElemType;
typedef struct
{
ElemType *base; //栈底指针
ElemType *top; //栈顶指针
int stacksize; //栈可用最大容量
}SqStack;
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef char ElemType;
typedef struct
{
ElemType *base; //栈底指针
ElemType *top; //栈顶指针
int stacksize; //栈可用最大容量
}SqStack;
Status InitStack(SqStack &S); //函数原型申明
Status Push(SqStack &S,ElemType e);
Status Pop(SqStack &S,ElemType &e);
ElemType GetTop(SqStack S);
Status Push(SqStack &S,ElemType e);
Status Pop(SqStack &S,ElemType &e);
ElemType GetTop(SqStack S);
int main()
{
int i=0, flag=1; //用flag标记是否匹配
ElemType a[100];
ElemType ch,e;
SqStack S;
InitStack(S);
cin.getline(a, 100); //输入要判断的内容:数组a进行判断
while(flag==1 && a[i]!='\0') //当前匹配且a非空,则进行下一轮匹配
{
if(a[i]=='(' || a[i]=='[' || a[i]=='{') //若为3个左括号任一,则入栈
{
Push(S,a[i]);
}
else if(a[i]==')' || a[i]==']' || a[i]=='}') //若为3个右括号任一
{
if(S.top==S.base) //先判断栈此时是否已空
flag=0; //若栈空,则不匹配
else
{
ch=GetTop(S); //取栈顶元素与当前扫描的元素比较
Pop(S,e); //
if(!(a[i]==')'&&ch=='(' || a[i]==']'&&ch=='[' || a[i]=='}'&&ch=='{')) //若不匹配,flag=0
{
flag=0;
}
}
}
++i; //扫描a中下一个元素,
}
if(flag==1)
{
cout<<"yes"<<endl;
}
else
{
cout<<"no"<<endl;
}
return 0;
}
{
int i=0, flag=1; //用flag标记是否匹配
ElemType a[100];
ElemType ch,e;
SqStack S;
InitStack(S);
cin.getline(a, 100); //输入要判断的内容:数组a进行判断
while(flag==1 && a[i]!='\0') //当前匹配且a非空,则进行下一轮匹配
{
if(a[i]=='(' || a[i]=='[' || a[i]=='{') //若为3个左括号任一,则入栈
{
Push(S,a[i]);
}
else if(a[i]==')' || a[i]==']' || a[i]=='}') //若为3个右括号任一
{
if(S.top==S.base) //先判断栈此时是否已空
flag=0; //若栈空,则不匹配
else
{
ch=GetTop(S); //取栈顶元素与当前扫描的元素比较
Pop(S,e); //
if(!(a[i]==')'&&ch=='(' || a[i]==']'&&ch=='[' || a[i]=='}'&&ch=='{')) //若不匹配,flag=0
{
flag=0;
}
}
}
++i; //扫描a中下一个元素,
}
if(flag==1)
{
cout<<"yes"<<endl;
}
else
{
cout<<"no"<<endl;
}
return 0;
}
Status InitStack(SqStack &S) //构造空栈
{
S.base=new ElemType[MAXSIZE]; //为顺序栈动态分配一个最大容量为MAXSIZE的数组空间
if(!S.base) exit(OVERFLOW);//储存分配失败
S.top=S.base; //top初始为base,空栈
S.stacksize=MAXSIZE; //stacksize置为栈的最大容量MAXSIZE
return OK;
}
{
S.base=new ElemType[MAXSIZE]; //为顺序栈动态分配一个最大容量为MAXSIZE的数组空间
if(!S.base) exit(OVERFLOW);//储存分配失败
S.top=S.base; //top初始为base,空栈
S.stacksize=MAXSIZE; //stacksize置为栈的最大容量MAXSIZE
return OK;
}
Status Push(SqStack &S,ElemType e) //插入元素e为新的栈顶元素
{
if(S.top-S.base==S.stacksize) //判断栈满
return ERROR;
*S.top++=e; //元素e压入栈顶,栈顶指针加1
return OK;
}
{
if(S.top-S.base==S.stacksize) //判断栈满
return ERROR;
*S.top++=e; //元素e压入栈顶,栈顶指针加1
return OK;
}
Status Pop(SqStack &S,ElemType &e) //删除栈顶元素,用e返回其值
{
if(S.top==S.base) //判断栈空
return ERROR;
e=*--S.top; //栈顶指针减1,将栈顶元素赋给e
return OK;
}
{
if(S.top==S.base) //判断栈空
return ERROR;
e=*--S.top; //栈顶指针减1,将栈顶元素赋给e
return OK;
}
ElemType GetTop(SqStack S) //返回S的栈顶元素,不修改栈顶指针
{
if(S.top!=S.base) //栈非空
return *(S.top-1);
}
{
if(S.top!=S.base) //栈非空
return *(S.top-1);
}
银行业务队列简单模拟
#include <iostream>
using namespace std;
using namespace std;
#define MAXSIZE 1000 //队列可能达到的最大长度
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef int ElemType;
typedef struct
{
ElemType *base; //存储空间的基地址
int front; //头指针
int rear; //尾指针
}SqQueue;
typedef int ElemType;
typedef struct
{
ElemType *base; //存储空间的基地址
int front; //头指针
int rear; //尾指针
}SqQueue;
Status InitQueue(SqQueue &Q); //函数原型申明
Status EnQueue(SqQueue &Q,ElemType e);
//Status DeQueue(SqQueue &Q,ElemType &e);
void print(SqQueue &A,SqQueue &B,SqQueue &C);
Status EnQueue(SqQueue &Q,ElemType e);
//Status DeQueue(SqQueue &Q,ElemType &e);
void print(SqQueue &A,SqQueue &B,SqQueue &C);
int main()
{
SqQueue A,B,C; //定义A B两个队列分别存储两个窗口的顾客编号,C用于存储最后的输出队列
int N,i=0;
cin>>N; //输入顾客的数量
int a[N];
InitQueue(A); //初始化队列A,B ,C
InitQueue(B);
InitQueue(C);
for(i=0;i<N;i++) //输入所有顾客的编号
{
cin>>a[i];
if(a[i]%2) //编号为奇数的顾客入A队
{
EnQueue(A,a[i]);
}
else //编号为偶数的顾客入B队
{
EnQueue(B,a[i]);
}
}
print(A,B,C);
return 0;
}
{
SqQueue A,B,C; //定义A B两个队列分别存储两个窗口的顾客编号,C用于存储最后的输出队列
int N,i=0;
cin>>N; //输入顾客的数量
int a[N];
InitQueue(A); //初始化队列A,B ,C
InitQueue(B);
InitQueue(C);
for(i=0;i<N;i++) //输入所有顾客的编号
{
cin>>a[i];
if(a[i]%2) //编号为奇数的顾客入A队
{
EnQueue(A,a[i]);
}
else //编号为偶数的顾客入B队
{
EnQueue(B,a[i]);
}
}
print(A,B,C);
return 0;
}
Status InitQueue(SqQueue &Q) //构造一个空队列
{
Q.base=new ElemType[MAXSIZE]; //为队列分配一个最大容量为MAXSIZE的数组空间
if(!Q.base) exit(OVERFLOW); //存储分配失败
Q.front=Q.rear=0; //头指针和尾指针置为零,队列为空
return OK;
}
{
Q.base=new ElemType[MAXSIZE]; //为队列分配一个最大容量为MAXSIZE的数组空间
if(!Q.base) exit(OVERFLOW); //存储分配失败
Q.front=Q.rear=0; //头指针和尾指针置为零,队列为空
return OK;
}
Status EnQueue(SqQueue &Q,ElemType e) //入队:插入元素e为Q的新的队尾元素
{
if((Q.rear+1)%MAXSIZE==Q.front) //尾指针在循环意义上加1后等于头指针,表明队满
return ERROR;
Q.base[Q.rear]=e; //新元素插入队尾
Q.rear=(Q.rear+1)%MAXSIZE; //队尾指针加1
return OK;
}
{
if((Q.rear+1)%MAXSIZE==Q.front) //尾指针在循环意义上加1后等于头指针,表明队满
return ERROR;
Q.base[Q.rear]=e; //新元素插入队尾
Q.rear=(Q.rear+1)%MAXSIZE; //队尾指针加1
return OK;
}
void print(SqQueue &A,SqQueue &B,SqQueue &C) //输出顾客
{
int n=1;
while(A.front!=A.rear || B.front!=B.rear) //当还有顾客没有入新队,则执行以下操作:将顾客编入新队
{
if((n==1) || (n==2))
{
if(A.front!=A.rear) //当前A非空
{
EnQueue(C,A.base[A.front]); //将A队列的当前元素入新队
A.front=(A.front+1)%MAXSIZE; //A队头指针+1:操作A队下一个顾客
}
}
else
{
if(B.front!=B.rear) //当前B非空
{
EnQueue(C,B.base[B.front]); //将B队列的当前元素入新队
B.front=(B.front+1)%MAXSIZE; //B队头指针+1:操作B队下一个顾客
}
}
n++;
if(n>3)
n=1;
}
cout<<C.base[C.front]; //新队的第一个元素输出,不带空格
C.front=(C.front+1)%MAXSIZE; //往后一个输出剩余元素
while(C.front!=C.rear)
{
cout<<" "<<C.base[C.front];
C.front=(C.front+1)%MAXSIZE;
}
}
{
int n=1;
while(A.front!=A.rear || B.front!=B.rear) //当还有顾客没有入新队,则执行以下操作:将顾客编入新队
{
if((n==1) || (n==2))
{
if(A.front!=A.rear) //当前A非空
{
EnQueue(C,A.base[A.front]); //将A队列的当前元素入新队
A.front=(A.front+1)%MAXSIZE; //A队头指针+1:操作A队下一个顾客
}
}
else
{
if(B.front!=B.rear) //当前B非空
{
EnQueue(C,B.base[B.front]); //将B队列的当前元素入新队
B.front=(B.front+1)%MAXSIZE; //B队头指针+1:操作B队下一个顾客
}
}
n++;
if(n>3)
n=1;
}
cout<<C.base[C.front]; //新队的第一个元素输出,不带空格
C.front=(C.front+1)%MAXSIZE; //往后一个输出剩余元素
while(C.front!=C.rear)
{
cout<<" "<<C.base[C.front];
C.front=(C.front+1)%MAXSIZE;
}
}