目录
栈和队列的基本概念
栈的基础概念
栈是只允许在一端进行插入或删除操作的线性表。首先栈是一种线性表,但限定这种线性表只能在某一端进行插入和删除操作
栈顶【TOP】:线性表允许进行插入删除的那一端
栈底【Bottom】:固定的,不予许进行插入和删除的另一端
空栈。不包含任何元素的空表
栈的操作特性可以明显地概括为后进先出
队列的基本概念
队列简称队,也是一种操作受限的线性表,只允许在表的一端进行插入,而在表的另一端进行删除。向队列中插入元素称为入队或进队;删除元素称为出队或离队。其操作的特性是先进先出
队头:允许删除的一端,又称队首
队尾:允许插入的一端
空队列:不含任何元素的空表
队列常见的基本操作:
InitQueue(&Q):初始化队列,构造一个空队列Q
QueueEmpty(&Q):判队列空,若队列Q为空,返回True , 否则返回false
Enqueue(&Q,x):入队,若队列Q未满,将x加入,使之成为新的队尾
DeQueue(&Q,&x):出队,若队列Q非空,删除队头元素,并用x返回
GetHead(Q,&x):读对头元素,若队列Q非空,则将对头元素赋给x
需要注意的是,栈和队列是操作受限的线性表,因此不是任何对线性表的操作都可以作为栈和队列的操作。比如,不可以随便读取栈或队列中间的某个数据
栈和队列的顺序存储结构及其存储特点
栈的顺序存储结构及其存储特点
采用顺序存储的栈称为顺序栈,它利用一组地址连续的存储单元存放自栈底到栈顶的数据元素,同时附设一个指针指向当前栈顶元素的位置。
栈的顺序存储类型可描述为
#define MaxSize 50 // 定义栈中元素的最大元素个数
typedef struct{
ElemType data[MaxSize] ; // 存放栈中元素
int top ; // 栈顶指针
}SqStack ;
栈顶指针:s.top , 初始时设置s.top = 1 ;
栈顶元素:s.data[s.top] ;
进栈操作(push):栈不满时,栈顶指针先加1 , 再送值到栈顶元素;
出栈操作(pop):栈非空时,先取栈顶元素值,再将栈顶指针减1 ;
栈空条件:s.top == -1 ;
栈满条件:s.top == MaxSize +1 ;
栈长 :s.top +1 ;
由于顺序栈的入栈操作受数组上届的约束,当对栈的最大使用空间估计不足时,有可能发生栈溢出,此时应及时向用户报告信息,以便及时处理,避免出错。
注意:栈和队列的判空、判满条件,会因实际给的条件不同而变化,上面提到的方法以及下面的代码实现只是在栈顶指针设定的条件下的相应方法,而其他情况则需具体问题具体分析
队列的顺序存储结构及其存储特点
队列的顺序实现是指分配一块连续的存储单元存放队列中的元素,并附设两个指针:对头指针front指向对头元素,队尾指针rear指向队尾元素的下一个位置(这里的front和rear的定义也可以不一样)
队列的顺序存储类型可描述为
#define MaxSize = 50 ; //定义队列中元素的最大个数
typedef struct {
ElemType data[MaxSize] ; // 存放队列元素
int front , rear ; // 队头指针和队尾指针
}sqQueue ;
初始状态(队空条件):Q.front==Q.rear==0
进队操作:队不满时,先送值到队尾元素,再将队尾指针加1 。
出队操作:队不空时,先取对头元素值,再将对头指针加1
队列的初始初始状态,有Q.front = Q.rear == 0成立, 该条件可以作为队列判空的条件。但能否用Q.rear == MaxSize 作为队列满的条件呢? 显然不能。队列中仅有一个元素,但仍满足该条件,这是入队出现“上溢出”,但这种溢出并不是真正的溢出,在data数组中依然存在可以存放元素的空位置所以是一种“假溢出”
栈和队列的链式存储结构及其存储特点
栈的链式存储结构及其存储特点
采用链式存储的栈称为链栈,链栈的优点是便于多个栈共享存储空间和提高其效率,且不存在栈满上溢的情况。通常采用单链表实现,并规定所有操作都是单链表地表头进行。这里规定链栈没有头结点,Lhead指向栈顶元素。
栈的离岸市场存储类型可描述为
typedef struct {
ElemType data ; // 数据域
struct Linknode *next ; // 指针域
} *LisStack ; // 栈类型定义
采用链式存储,便于节点的插入与删除。链栈的操作与链表类似,入栈和出栈的操作都在链表的表头进行。需要注意的是,对于带头结点和不带头结点的链栈,具体的实现会有所不同
队列的链式存储结构及其存储特点
队列的链式表示为链队列,他实际上一个同事带有队头指针和队尾指针的单链表,头指针指向对头节点,尾指针指向队尾节点,即单链表的最后一个节点(注意与顺序存储的不同)
队列的链式存储类型可描述为
typedef struct { // 链式队列节点
ElemType data ;
struct LinkNode *next ;
}LinkNode ;
typedef struct { // 链式队列
LinkNode *front , *rear ; // 队列的队头和队尾指针
}LinkQueue ;
当Q.front == null 且 Q.rear == null 时链式队列为空
出队时,首先判断队列是否为空,若不空,则取出队头元素,将其从链表中摘除,并让Q.front指向下一个节点(若该节点为最后一个节点,则置Q.front和Q.rear都为null)。入队时,建立一个新节点,将新节点插入到链表的尾部,并改让Q.rear 指向这个新节点(若原队列为空队列, 则令Q.front也指向该节点)