凉城c

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

一、本章内容小结

  本章节主要讲解的是栈和队列两种线性表,其中包括它们的定义、特点、操作和实现。同时书本上也引入了一些案例,让我们知道了运用不同的线性表可以解决不同的问题。

  栈是限定仅在表尾进行插入或删除操作的线性表,我们可以认为它是一种后进先出的线性表;队列的特点是它只允许在表的一端进行插入,而在另一端删除元素,我们可以认为它是一种先进先出的线性表。栈可以用来解决数制的转换问题:在计算过程中依次将得到的余数压入栈中,计算完毕后,再依次弹出栈中的余数就是数制转换的结果。队列可以用来解决舞伴问题:先出队的男士和女士应先出队配成舞伴,因此这种问题具有先进先出的特性。

  下面是关于栈和队列的思维导图。对我而言,相比第二章所学的内容,第三章的内容更加抽象,较难以理解。当然,本章也和第二章有一些关联,比如存储结构方面的知识:栈也分循序栈和链栈,它们的存储分配方式与顺序表、链表相似。因此,如果我们深刻理解了第二章的知识,那么学习第三章也不会特别困难。

 

二、完成作业实践时的心得体会

(1) 关于第三章作业

  第三章作业的编程题就是关于括号匹配的问题,我按照书本上的思路用了栈解决了这道题。要想实现入栈和出栈等功能,我们需要自己写出实现这些功能的函数,在这道题中,我创建了如下函数:

typedef struct
{
SElemType* base; //栈底指针
SElemType* top; //栈顶指针
int stacksize; //栈可用最大容量
}SqStack;

bool InitStack(SqStack &S) //构造空栈函数
{
S.base = new SElemType[MAX];
if (!S.base)
return false; //存储分配失败,返回值为false
S.top = S.base;
S.stacksize = MAX; //stacksize置为栈的最大容量MAX
return true;
}

bool IsEmpty(SqStack &S) //判断是否栈空
{
if (S.top == S.base)
return true;
return false;
}

bool Push(SqStack &S, SElemType e) //插入元素e为新的栈顶元素
{
if (S.top - S.base == S.stacksize)
return false; //如果栈满,则将插入失败,返回值为false
*S.top++ = e;
return true;
}

bool Pop(SqStack &S, SElemType &e) //删除S的栈顶元素,用e返回其值
{
if (S.top == S.base)
return false; //如果栈空,则将删除失败,返回值为false
e = *--S.top;
return true;
}

  我将这些函数返回值定义为bool型而不是void型,是因为可能会出现栈满或是存储分配失败的问题,当这种问题发生时,函数将中断后面的步骤,直接返回false。如果步骤能够正常进行,函数返回true。在主函数中,如果子函数返回值为false,就输出no或是直接退出程序,如:

 

if (!Pop(S, e))
{
cout << "no";
return 0; //如果函数返回值为false,cout "no",然后退出程序
}

 

  在这次作业中,我见到了两个不认识的词:SElemType和Status。一开始我直接使用这两个标识符,结果编译器报错,原因是这两个标识符未定义。后来才发现这两个词在使用前是需要定义的。

typedef char SElemType; //SElemType意思为栈中元素,此处定义SElemType为char型

typedef int Status;

  书上的ERROR和OK其实是这么实现的:#define ERROR 0  #define OK 1

  而0和1属于整数,所以在搭配typedef int Status时,return ERROR可以相当于bool型函数中的return false, return OK可以相当于bool型函数中的return true,可以说是bool型的另一种表达方式。

  在这道题中,SElemType和Status的本质其实就是char型和int型,将它们分别用char和int替换掉是完全OK的。我有段时间一直想不明白为什么不直接用char和int,而是把它们化成SElemType和Status这种奇怪的东西,后来我才知道这些词的出现是为了方便理解,但是有些抽象,一开始接触的时候难以接受,所以我才会有关于SElemType和Status的困惑吧。

 

(2) 关于第三章实践

  这道题卡我时间比较长,主要是因为没想到能解决问题的算法,后来才发现其实可以这样解决:

if (x <= s1) { if (j) cout << " "; cout << b[x - 1]; x++; j++; }
if (x <= s1) { if (j) cout << " "; cout << b[x - 1]; x++; j++; }
if (y <= s2) { if (j) cout << " "; cout << c[y - 1]; y++; j++; }

   其中s1代表奇数号顾客的集合,s2代表偶数号顾客的集合,因数组中的第一个下标为0,所以if(j)语句可以实现第一个元素直接输出,之后按照‘ ’a[j-1]的方式输出。

  找到问题之后我也没有全对,只是24分,后来才知道奇数号顾客的集合和偶数号顾客的集合并不用排序,而我却下意识地认为小号在前,大号在后,所以演了这么一出乌龙。

 

三、参考的资料

  本章的学习主要参考书本上的知识,书本上提供了一些基本功能的实现,但还不够精细,所以我通常参考的另一个途径是百度。

  https://jingyan.baidu.com/article/295430f1c008920c7e0050d9.html

 

四、待改进的问题

  (1)有些题的算法没想到,或者是不知道用何种方式表达最恰当,最后就容易导致没做出来或程序臃肿,效率低。

  (2)理解能力还需要加强,更能接受新知识。

 

五、接下来的目标

  多打题,改进思维方式,养成课前预习课后复习的好习惯,有些本章的知识不理解,也许预习了下一章后就想通了,以前就是学习了链表后就弄清楚了指针的作用。

 

posted on 2019-03-31 22:24  凉城c  阅读(248)  评论(2编辑  收藏  举报