数据结构2.1栈、队列和串

特殊线性表

栈、队列和串是三种特殊的线性表。其中,栈和队列是操作受限制的线性表,串是数据类型受限制的线性表。

栈(stack)

栈的定义

栈是一种特殊的线性表,只允许在一端进行插入和删除操作。允许插入和删除的一端称为栈顶,另一端称为栈底。处于栈顶位置的元素称为栈顶元素。栈中含有元素的个数称为栈长,含有0个数据元素的栈称为空栈。其特点为后进先出或先进后出,因此栈又称为后进先出的线性表。
习惯上,把栈的插入操作称为入栈(或称为进栈、压栈),把栈的删除操作称为出栈(或称为退栈、弹栈)。

栈的基本操作

1->初始化操作initstack(S),其作用是初始化一个空栈S。
2->求栈长操作getlen(S),其作用是返回栈S的元素个数,即栈长。
3->取栈顶元素操作gettop(S,x),其作用是通过x带回栈S的栈顶元素值。
4->入栈操作push(S,x),其作用是将值为x元素压入到栈S中,使x成为新的栈顶元素。
5->出栈操作pop(S,x),其作用是将非空栈的栈顶元素删除,同时将栈顶元素值赋给x,新的栈顶元素为栈S中原栈顶的下一个元素。
6->判栈空操作emptystack(S),其作用是判断栈S是否为空,若栈S为空,则返回1,否则返回0。
7->输出栈操作list(S),其作用是依次输出栈S中的所有元素。

顺序栈

栈的顺序存储结构,即用一段地址连续的存储单元依次存放从栈底到栈顶之间的数据元素,同时利用一个变量记录当前栈顶的位置(下标或指针),称为栈顶指针。
在初始化栈时,栈顶指针值为0,表示空栈;在栈中插入新的元素后,栈顶指针增加1;在栈中删除栈顶元素时,栈顶指针减少1。

顺序栈的类型定义
#define INIZSIZE 100//存储空间的初始分配量
typedef int ElemType;//在实际应用中,根据需要定义所需的数据类型
typedef struct{
int top;//栈顶指针
ElemType *base;//存放元素的动态数组空间
int stacksize;//当前栈空间的大小
}sqstack;

栈在计算机语言处理和将递归算法改为非递归算法等方面起着非常重要的作用。

链栈

栈的链式存储结构。实际上是一个仅在表头进行操作的单链表,这种单链表的第一个结点称为栈顶结点,最后一个结点称为栈底结点,头指针指向栈顶结点或头结点(取决于是否含头结点)。

链栈的类型定义
typedef int ElemType;
typedef struct node{
ElemType data;//数据域
struct node *next;//指针域
}linkstack;

这实质上就是单链表的结点类型定义

队列

队列只允许在一端进行插入操作,在另一端进行删除操作。允许插入的一端 称为队尾,允许删除的一端称为队头,新插入的结点只能添加到队尾,要删除的结点只能是排在队头的结点。插入结点称为入队列,删除结点称为出队列
其特点是先进先出或后进后出。因此队列又称为先进先出的线性表。

队列的基本操作

1->初始化操作initqueue(Q),其作用是初始化一个队列Q。
2->求栈长操作getlen(Q),其作用是返回队列Q的元素个数,即队列的长度。
3->取队头元素操作getfront(Q,e),其作用是通过e返回队列Q的队头元素值。
4->入队操作outqueue(Q,e),其作用是将值为x元素插入到队列Q中,使x成为新的队尾元素。
5->出队操作outqueue(Q,e),其作用是删除队列Q的队头元素,同时将队头元素值通过e带回,原队列中的第二个元素称为新的队头元素。
6->判队空操作emptyqueue(Q),其作用是判断队列Q是否为空,若队列为空,则返回1,否则返回0。
7->输出队操作list(Q),其作用是从队头到队尾依次输出队列Q中的所有元素。

顺序队列和循环队列

顺序队列

队列的顺序存储结构,就是利用一组数据连续的存储单元依次存放从队头到队尾的数据元素,同时利用两个变量分别记录当前队列中队头元素和队尾元素的位置,这两个变量分别称为队头指针队尾指针(不一定是指针变量)。在初始化空队列时,队头指针和队尾指针的值都为0;元素入队列后队尾指针增1;出队列后队头指针增1。

顺序队列的类型定义
#define MAXQSIZE 100//队列空间的初始分配量
typedef int ElemType;
typedef struct{
ElemType *base;//基地址
int front;//队头指针
int rear;//队尾指针
}squeue;

当front== rear时,队列为空,当rear ==MAXQSIZE时队列为满。

循环队列

当队尾指针=MAXQSIZE时,称为满队列状态,但若此时front != 0,即有队头元素已被删除时,称之为“假满”,此时进行入队操作则会产生“假溢出”现象。为了充分利用空间,解决假溢出现象,可以把顺序队列从逻辑上看成是一个环,即当队尾指针或队头指针达到最大下标值MAXQSIZE时,再从下标为0的位置开始,这种队列称为循环队列。
当循环队列呈空或满状态时都有front==rear,这就产生了二义性,显然是不合理的,因为无法判断循环队列究竟是空还是满。因此为了区分空满状态,可以有多种方法解决,如另设标志区分循环队列的空和满等。

循环队列的类型定义
#define MAXCSIZE 100//队列空间的初始分配量
typedef int ElemType;
typedef struct{
ElemType *base;//基地址
int front;//队头指针
int rear;//队尾指针
}cqueue;

链队列

队列的链式存储结构,链队列实际上是一个带头指针和尾指针的单链表,这种单链表的第一个结点称为队头结点,最后一个结点称为队尾结点,队尾指针始终指向队尾结点。在带头结点的链队列中,队头指针指向头结点;在不带头结点的链队列中,队头指针指向队头结点。

链队列的类型定义
typedef int ElemType;
typedef struct node{
ElemType data;//数据域
struct node *next;//指针域
}qlink;//结点类型定义
typedef struct{
qlink *front;//队头指针
qlink *rear;//队尾指针
}linkqueue;//链队列类型定义

串又称字符串,是一种特殊的线性表,表中每一个元素是一个字符,即串是由零个或多个字符组成的有限序列,一般记为S=“a1a2a3…an”(n>=0)
其中,S是串名,用双引号括起来的字符序列是串值,双引号本身不是串的内容,是串的定义符。ai(1<=i<=n)代表一个字符,可以是字母、数字或其他字符。串中的字符个数n称为串长,含有0个字符的串称为空串
串中任意连续的字符组成的子序列称为该串的子串,包含子串的串称为主串。字符在串中的位序称为该字符在串中的位置。子串在主串中的位置是以子串的第一个字符在主串中的位置来表示的。若两个串的长度相等,并且各个对应位置上的字符都相同,则称这两个串相等

串的基本操作

1-> 初始化操作initstring(s),其作用是初始化一个字符串。
2->串赋值操作strassign(s1,s2),其作用是将一个串常量s2赋给串常量s1。
3->串复制操作assign(s1,s2),其作用是将串s2的值赋给串变量s1。
4->求串长操作length(s),其作用是返回串s的长度。
5->判串等操作equal(s,t),其作用是判断串s和t的值是否相等,若相等返回1,否则返回0。
6->串连续操作concat(s,s1,s2),其作用是将串s2连接到串s1的后面,结果存到串s中。
7->取子串操作substr(s,i,j,t),在串s中取出第i个字符开始的j个连续字符存到t中。在此1<=i<=length(s),0<=j<=length(s)-I+1。
8->插入操作insert(s,i,t),其作用是将串t插入到串s的第i个字符之前。在此,1<=i<=length(s)+1。
9->删除操作delete(s,i,j),其作用是在串s中删除从第i个字符开始的长度为j的子串。在此1<=i<=length(s),1<=j<=length(s)-i+1。
10->串查找操作index(s,t,pos),其作用是在主串s的第pos个字符开始查找子串t出现的位置。在此1<=pos<=length(s)。该操作也称为串的模式匹配。
11->替换操作replace(s,i,j,t),其作用是将串s的从第i个字符开始的连续j个字符替换成串t。在此,1<=i<=length(s),1<=j<=length(s)-I+1。
12->输出操作list(s),其作用是输出串s的值。

顺序串

串的顺序存储结构,即串中的字符被一次存放在一组连续的存储单元中。一般来说一个字符占用一个字节的存储空间,因此一个存储单元可以存储多个字符。例如一个32位的内存单元可以存储4个字符。串的顺序存储有两种格式:一种是每个存储单元只存放一个字符,称为非紧缩格式;另一种是每个存储单元存放多个字符,称为紧缩格式

顺序串的类型定义
#define INIZTSTRLEN 100
typedef struct{
char *ch;//串存放的起始地址
int length;//串长
int strsize;//当前为串分配的存储空间大小
}string;

链串

串的链式存储结构。链中的一个结点可以存储一个字符,也可以存储多个字符。每个结点所存储的字符个数称为结点大小
当结点大小大于1时,如果串的长度不是结点大小的倍数,则链串的最后一个结点的数据域不能被字符占满,此时应用非串值字符(如#)填满。
链串的结点大小越大,则存储密度越大,但给一些操作(如插入、删除、替换等)带来不便,可能引起大量的字符移动。结点大小越小(结点大小为1时),操作处理越方便,但存储密度下降。

链串的类型定义
typedef struct node{
char ch;//数据域
struct node *next;//指针域
}linkstr;

猜你喜欢

转载自blog.csdn.net/weixin_43451616/article/details/86468365