数据结构与算法分析2.表、栈、队列、字符串
线性表是 n 个数据元素的有限队列,同一线性表中的元素必定具有相同的特性,即属于同一数据对象,相邻数据元素之间存在着序偶关系。
线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素,通常是用数组实现。在Java语言中,主要是 java.util.ArrayList 实现。
线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的),所以对数据元素而言,除了存储其本身的信息之外,还需要一个指示其后继数据元素的信息。
栈(Stack)是限定只能在表尾进行插入或删除的线性表。对栈来说, 表尾称为栈顶,表头称为栈底 。栈又称为后进先出线性表(LIFO,Last In First Out)。Java中由于 java.util.Stack 和 java.util.Vector 先天的设计问题,并不推荐使用;一般使用LinkedList来当作栈。
[图片上传失败...(image-b267ad-1582731953399)]
[图片上传失败...(image-72fd67-1582731953399)]
假设一个算术表达式中可以包含两种括号:圆括号和方括号,且这两种括号可按任意的次序嵌套使用,编写判别给定表达式中所含括号是否正确配对出现的算法。
迷宫问题是栈的典型应用,栈通常也与回溯算法连用,回溯算法的基本描述是:
尚需说明一点的是,所谓当前位置可通,指的是未曾走到过的通道块,即要求该方块位置不仅是通道块,而且既不在当前路径上(否则所求路径就不是简单路径),也不是曾经纳入过路径的通道块(否则只能在死胡同内转圈)。
为实现算符优先算法,可以使用两个工作栈。一个称做OPTR,用以寄存运算符;另一个称做OPND,用以寄存操作数或运算结果。算法的基本思想如下:
(1) 首先置操作数栈OPND为空栈,表达式起始符"#"为运算符栈OPTR的栈底元素;
(2) 依次读入表达式中每个字符,若是操作数则进OPND栈,若是运算符则和OPTR的栈顶元素符比较优先权后作相应操作,直至整个表达式求值完毕(即OPTR栈的栈顶元素和当前读入的字符均为"#")。
一个直接调用自己或通过一系列的调用语句间接地调用自己的函数。
假设有3个分别命名为X、Y和Z的塔座,在塔座X上插有n阶Hanoi塔个直径大小各不相同、依小到大编号1,2,...,n的圆盘。现要求将X轴上的n阶Hanoi塔个圆盘移至塔座Z上并仍按同样顺序叠排,圆盘移动时必须遵循下列规则:
用链表表示的队列简称为链队列。一个链队列显然需要两个分别指示队头和队尾的指针(分别称为头指针和尾指针)才能唯一确定。和线性表的单链表一样,为了操作方便起见,我们也给链队列添加一个 头结点 ,并令头指针指向头结点。由此,空的链队列的判断条件为头指针和尾指针均指向头结点,如图所示:
在实际使用队列时,为了使队列空间能重复使用,往往对队列的使用方法稍加改进:无论插入或删除,一旦rear指针增1或front指针增1时超出了所分配的队列空间,就让它指向这片连续空间的起始位置。自己真从MaxSize-1增1变到0,可用取余运算rear%MaxSize和front%MaxSize来实现。这实际上是把队列空间想象成一个环形空间,环形空间中的存储单元循环使用,用这种方法管理的队列也就称为循环队列。
在循环队列中,当队列为空时,有front=rear,而当所有队列空间全占满时,也有front=rear。为了区别这两种情况,规定循环队列最多只能有MaxSize-1个队列元素,当循环队列中只剩下一个空存储单元时,队列就已经满了。因此,队列判空的条件时front=rear,而队列判满的条件时front=(rear+1)%MaxSize。队空和队满的情况如图:
双端队列,是限定插入和删除操作在表的两端进行的线性表,尽管双端队列看起来比栈和队列灵活,但实际上在应用程序中远不及栈和队列有用。
2024-11-30 广告