第三章:栈和队列P44
3.1.1栈的定义
栈(stack)是一种仅允许在一段进行插入和删除运算的线性表。
注意:栈的插入和删除操作只能在栈顶一端进行,后进栈的元素必定先出栈,所以栈又称为后进先出(Last In First Out)的线性表(简称为LIFO结构)。
栈有两种存储表示方法:顺序存储和链式存储。
顺序存储的栈称为顺序栈,链式存储的栈称为链栈。
3.1.2.顺序栈存储结构和操作的实现
1)顺序栈存储结构的定义
顺序栈利用一组地址连续的存储单元依次存放从栈底到栈顶的数据元素。在C语言中,可以用以为数组描述顺序栈中数据元素的存储区域,并预设一个数组的最大空间。
顺序栈进行插入和删除运算相当于是在顺序表的表尾进行的,骑士剑复杂度为 O(1)。
2)顺序栈的基本操作
注意:在做入栈操作前,首先要判定栈是否满。在做出站操作前,又得先判断栈是否空。
尤其注意栈为空的条件是什么:若是top=-1为栈空,则说明top指的是待空下标的前一个值。
若top=0为栈空,则说明top指的是待空下标的值。
P48
入栈操作:栈顶指针加1,然后入栈;当然也可以定义先入栈,然后栈顶指针加1.
同样出栈操作也可以栈顶指针减1,然后出栈。
什么是栈的溢出?
对于顺序栈,入栈是必须先判断栈是否满,栈满的条件是S->top==maxsize-1.栈满时不能入栈,否则会产生错误,此现象称为上溢。
出栈时必须先判断栈是否为空,栈空的条件时S->top==-1.栈空时不能出栈,否则会产生错误,此现象称为下溢。
3.1.3.链栈的存储结构和操作的实现
栈的链式存储结构与线性表的链式存储结构相同,(操作方式为:栈)栈的单链表(存储方式为:链式存储)称为链栈。
链栈是动态分配结点空间,所以无需考虑上溢问题。
由于链栈的入栈、出栈操作限定在栈顶方向进行,其时间复杂度为O(1),因此没有必要加一个头结点。
P50:
2.链栈一般不会出现栈满情况,除非空间不足,导致malloc分配失败。
3.链栈的入栈、出栈操作就是栈顶的插入与删除操作,修改指针即可完成。
4.链栈的优点:可使多个栈共享空间;在栈中元素变化的数量较大,且存在多个栈的情况下,链栈是栈的首选存储方式。
3.3.1队列的定义与基本操作
队列(queue):是一种限定在表的一端进行插入而在另一端进行删除的线性表。
队列遵循先进先出(First In First Out,FIFP)原则。
注意:只能从队尾插入元素,从队头删除元素。
3.3.2链队列的存储结构和操作的实现
链队列:就是用链表进行存储,行为限制为:在表头进行删除和在表尾进行插入的单链表。
一个链队列需要两个分别指示队头和队尾的指针(分别称为头指针和尾指针)才能唯一确定。
判断链队列为空的条件是队头指针与队尾指针均指向头结点。
注意:删除队头元素算法中存在特殊情况。一般情况下,删除队头元素时仅需要修改头结点中的指针,但当队列中最后一个元素被删除后,队列尾指针也丢失了,因此需要对队尾指针重新赋值(指向头结点)。
3.3.3顺序队列的存储结构和操作的实现
队列的顺序存储结构称为顺序队列。
注意:顺序队列的存储结构比栈的顺序存储结构复杂一些,除了定义一个一维数组外,还需附设两个指针front和rear分别指示当前队头元素和队尾元素在数组中的位置。
在非空队列中,头指针始终指向队头元素,而尾指针始终指向队尾元素的下一个位置。
当进行了若干次入队和出队操作后,队尾指针到了最后,无法插入了,但队列并没有满,即元素的个数少于队列满时的个数maxsize,这种现象称为假溢出。
避免假溢出的两种办法:
1)每次一个元素出队后,将整个队列的所有元素向前移动一个位置。
2)(采用循环队列来解决)将顺序队列的数据区data[0~maxsize-1]看成一个首尾相接的圆环,当存到maxsize-1时,下一个”地址“就翻转成0,使data[0]接在data[maxsize-1]之后,且头尾指针的关系不变,这种队列称为循环队列。
由于入队时尾指针向前追赶头指针,出队时头指针向前追赶尾指针,故队空和队满时头尾指针均相等。注意:因此,无法通过front=rear来判断队列是”空“还是”满“。
解决以上问题的方法有两种:
一、另设一个标志位以区别队列的”空“和”满“;
二、少用一个元素的空间,约定以”队头指针在队尾指针的下一位置(指环状下一位置)上“作为队列”满“的标志,若数组的大小是maxsize,则该数组所表示的循环队列最多允许存储maxsize-1个结点(注意:rear所指的单元始终为空,也可以是front始终指向队头元素的前一个空元素,rear始终指向队尾元素)
基于以上情况:循环队列满的条件:(rear+1)%maxsize==front
循环队列空的条件:rear==front
P75:
第三章小结
1)栈和队列是运算受限制的线性表。
2)栈的插入和删除均在栈顶进行,特点是后进先出(或先进后出);
队列的插入在队尾进行,删除在队头进行,特点是先进先出(或后进后出);
3)在解决具有”后进先出“特点问题时,可以使用”栈“;
在解决具有”先进先出“特点问题时,可以使用”队列“。
4)存储方式不同:栈可以分为顺序栈和链栈;
队列可以分为顺序队列和链队列,
一般情况下使用的顺序队列是循环队列。
第四章:串P79
4.1串的定义和基本操作
字符串(简称串)是一种特殊的线性表,它的每个结点仅由一个字符组成。
4.1.1串的定义
串(string)是字符串的简称,是由零个或多个字符组成的有限序列。
记为:S=”a1,a2,...an“(n>=0)
1)S是串名。
2)用双引号(”“)括起来的字符序列是串的值。通常用双引号把字符括起来,但双引号本身不属于串,它的作用是避免串域常数或与标识符混淆。
注意:C语言中,s1='a' 与 s2="a"是不同的,s1表示字符,s2表示字符串。
eg:”123“是数字字符串,不同于整数123。
3)ai(1<=i<=n)可以是字母、数字或其他字符。
4)串字符的数目n称为该串的长度。长度为零(n=0)的串称为空串(null string),不包含任何字符。
注意P80: