第三章 栈和队列

 

         第三章学习了栈和队列,以下是我对本章的一些小结:

          一 、栈

  栈又称为后进先出的线性表,仅在栈顶进行插入或删除的操作。顺序栈非空时,top始终指向栈顶元素的上一个位置。(top为数组下标)

  1、顺序栈和链栈

  ①定义

   顺序栈:先分配一个固定大小的存储空间

   链栈:定义结点,包括数据域和指针域

  ② 初始化

  顺序栈:下标top为0

  链栈:栈顶指针置空

  ③ 判断栈空

   顺序栈:top为0时栈空

   链栈:栈顶指针是否为空

       判断栈满

   顺序栈:top的值等于数组的最大值

   链栈:不需要判断栈满

  ④ 入栈

   顺序栈: 先判断栈是否满,未满则在栈顶插入新元素时,top加1 

   链栈:不需要判断栈满,为入栈元素动态分配结点空间,将新结点插入栈顶

  ⑤  出栈

    顺序栈:判断栈是否为空,将栈顶元素删除,top减1

    链栈:判断栈是否为空,修改栈顶指针,指向新的栈顶元素,释放原栈顶元素的空间

  2、栈与递归

   void p(参数表)

  {

      if(递归结束条件成立) 可直接求解;    //递归必须给出终止条件

      else p(较小的参数);    //逐渐接近递归条件

  }

 递归程序结构清晰,形式简洁,但是占用内存空间较多,运行效率较低。

         二、队列

   队列是一种先进先出的线性表,只允许在队尾插入,在队头删除元素。

   1、循环队列(顺序实现)和链队

   循环队列可用“模”运算实现,如Q.rear = (Q.rear+1)%MAXSIZE

   ①  初始化

   循环队列:将头尾指针置0   Q.rear = Q.front = 0;

   链队:队头和队尾指针指向头结点,头结点指针域置空   Q.front = Q.rear = new QNode;   Q.front->next = NULL;

   ②  判断队满和队空

   循环队列:队空 Q.front == Q.rear

                     队满 (Q.rear+1) % MAXSIZE == Q.front

   链队:队空 Q.front == Q.rear

  ③ 入栈

   循环队列:新元素插入队尾,队尾指针加1  Q.base[ Q.rear ] = e ; Q.rear = ( Q.rear+1 ) % MAXSIZE;

   链队:新结点插入队尾,修改队尾指针  p->next = NULL; Q.rear->next = p; Q.rear = p;

  ④ 出栈 

  循环队列:判断队空,队头指针加1  if(Q.front != Q.rear) Q.front = (Q.front + 1) % MAXSIZE;

  链队:判断队空,修改头结点的指针域,若最后一个元素被删,队尾指针指向头结点,释放原队头元素

            Q.front->next = p->next; if(Q.rear == p) Q.rear = Q.front;  delete p;

   

       完成作业与实践时,遇到很多问题,也一直在努力的寻找解决方案,以下是发现问题和解决问题的心得和体会:

1.作业的选择题中,有两道题是关于不同链表性质和操作的,我刚看到题目的时候很混乱,具体的一些区别不能回忆起来,所以我先看书复习相关的知识点,然后大概归纳了一下。

    单链表      

         单链表,它包含一个数据域和一个指针域。这个链接指向表中的下一个节点,而最后一个节点则指向一个空值NULL。单向链表只可向一个方向遍历。查找一个节点的时候需要从第一个节点开始每次访问下一个节点,一直访问到需要的位置。也可以提前把一个节点的位置另外保存起来,然后直接访问。

    双向链表      

        双向链表中不仅有指向后一个节点的指针,还有指向前一个节点的指针。第一个节点的"前连接"指向NULL,最后一个节点的"后连接"指向NULL。这样可以从任何一个节点访问前一个节点,也可以访问后一个节点,以至整个链表。

    单向循环链表    

       循环链表的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环。单循环链表的判别条件与单链表不同,p != L;或 p->next != L;

    双向循环链表

        在最后一个结点之后插入一个结点或删除最后一个结点,采用这种存储方式最节省运算时间,以空间换时间。

 (参考资料 https://blog.csdn.net/zhongwen7710/article/details/39102523 和 https://blog.csdn.net/kangxidagege/article/details/80211225)

2.作业的编程题是括号匹配问题,当老师在课堂上讲到这道题时,我只知道应该用栈实现,但是具体操作不清楚。于是,我先在课本上找找思路,按着书本的算法打了一遍,并在无数次失败后获得了成功。但是,书本是用switch语句,而老师推荐我们用if语句,所以我按着老师的思路又打了一遍。

     我用if语句实现的时候,当要判断栈空或非空,我只考虑到非空的情况,而没有考虑空的情况,所以答案只是部分正确。后来,发现当判断到右括号,而栈为空时,也是不匹配的,flag应该置为0,改过来以后就答案正确了。在判断出栈字符是否与当前字符匹配时,不仅可以直接比较出栈字符是否为 '(' , '[' , '{' ,还可以比较它们的ASCII码值,左括号和右括号的ASCII码值只是相差1或者2,这样程序写起来更简单。

  (参考资料https://www.cnblogs.com/luolizhi/p/5746775.html  cin,cin.getline()等函数的用法和比较)

    心得:写程序时必需要有明确的思路,而且要细心,考虑问题要全面,多学习别人的优秀的代码,同一个问题可以有不同的解决方法,要灵活处理,多思考。

    疑惑:为什么括号匹配问题的答案测试中要有最长字符串的测试点?

 

      正在努力实现上次博客的目标,虽然栈和队列又是不同的数据结构,操作实现也有些区别,但是打代码的感觉比之前好了很多,对代码的理解也容易了很多。以后也会继续努力,不依赖书本就能写出代码。这次的目标是在学了很多种数据结构之后,也能明确它们之间的区别,明确它们的应用场景。

 

posted @ 2019-03-30 15:44  Jimin~  阅读(324)  评论(3编辑  收藏  举报