上一章总结:
什么是线性表?(或者说线性表的定义是什么?)
线性表 是具有相同特性的数据元素的一个有限序列
同一线性表中的元素必定具有相同特性, 数据元素间的关系是线性关系
线性表的逻辑特征是什么?
1.在非空的线性表, 有且仅有一个开始结点a1, 它没有直接前趋, 而仅有一个直接后继 a2
2. 有且仅有一个终端结点 an ,他没有直接后继, 而仅有一个直接前趋a n-1
3. 其余的内部结点 ai( 2<=i<=n-1) 都有且仅有一个直接前趋 ai-1 和一个直接后继 ai+1
线性表是一种典型的线性结构
顺序存储存在那些问题?
1) 存储空间分配不灵活
2) 运算的空间复杂度高
微总结:
线性表中数据元素的类型可以分为简单类型, 也可以为复杂类型
许多实际应用问题所涉的基本操作有很大相似性, 不应为每个具体应用单独编写一个程序
从具体应用中抽象出共性的逻辑结构和就基本操作(抽象数据类型) , 然后实现其存储结构和基本操作
在线性表的基本操作具体指的是什么?
InitList(&L) (Initialization List)
操作结果: 构造一个空的线性表L
DestroyList(&L)
初始条件: 线性表L已经存在.
操作结果: 销毁线性表L
ClearList(&L)
初始条件: 线性表L已经存在
操作结果: 将线性表L重置为空表
ListEmpty(L)
初始条件: 线性表L已经存在
操作结果: 若线性表L为空表., 则返回TURE; 否则返回FALSE.
ListLength(L)
初始条件: 线性表L已经存在
操作结果: 返回线性表L中的数据元素个数
GetElem(L, i, &e);
初始条件: 线性表L已经存在, compare()是数据元素判定函数
操作结果: 用e返回线性表L中第i个数据元素的值
LocateElent(L, e, compare())
初始条件: 线性表L已经存在, compare()是数据元素判断函数
操作结果: 返回L中第1个与e满足compare()的数据元素的位序. 若这样的数据元素不存在则返回值为0
PriorElem(L, cur_e, &pre_e)
初始条件: 线性表L已经存在
操作结果: 若cur_e是L的数据元素, 且不是第一个, 则用pre_e返回它的前趋否则操作失败; pre_e无意义
NexyElem(L, cur_e, &next_e)
初始条件: 线性表L已经存在
操作结果: 若cur_e是L的数据元素, 且不是第最后一个元素, 则用next_e返回它的后继, 否则操作失败, nexy_e无意义
ListLnsert(&L, i, e)
初始条件: 线性表已经存在, 1<=i<=ListLength(L)+1
操作结果: 在L的i个位置之前插入新的数据元素e, L的长度加一
ListTraverse(&L, visited())
初始条件:线性表L已经存在
操作结果:依次对线性表中每个元素调用visited()
以上的运算时逻辑结构上定义的运算, 是给出了运算的功能是"做什么" , 至于 "如何做"等实现细节, 只有待确定了存储结构之后才考虑
线性表的顺序表示和实现具体指的是什么?
线性表有两种基本的存储结构: 1) 顺序存储结构 2) 链式存储结构
线性表内的逻辑结构: 除了第一个元素没有前趋和最后一个元素没有后继, 任意一个元素 都有且只有一个前趋,一个后继
线性表的顺序表示 也可以称为 顺序存储结构 或者是 顺序映像
顺序存储定义: 把逻辑上相邻的数据元素存储在物理上相邻的存储单元中的存储结构
总之就是: 在逻辑上相邻, 则在物理上也相邻
线性表的 第一个 数据元素a1的存储位置, 我们可以将其称作 起始地址或基地址
注意:
1) 要依次存储, 地址连续----中间没有空除的存储单元 则是一个典型的线性表顺序存储结构
2)地址不连续---中间存在空的存储单元 则不是一个线性表顺序存储结构
线性表顺序存储结构占用一片连续的存储空间,. 知道某个元素的存储位置就可以计算其他元素的存储位置
其中的 L为每个元素需要占 L 个存储单元
顺序表的特点: 以物理位置相邻表示逻辑关系. 任一元素均可随机存取(优点)
顺序表可以用一维数组表示顺序表
线性表长可变 (删除)
数组长度不可动态定义
上述代码 是线性表定义的一个模板
C++中的参数传递
函数调用时传送个给形参表的实参必须与形参三个一致
类型 个数 顺序
参数传递有两种方式
传值方式 (参数为整型, 实型, 字符型等)
传地址
参数为指针变量
参数为引用类型
参数为数组名
当数组名作为参数 实际上是传递的是数组的首地址
对形参数组所作的任何改变都将反映到实参数组中
传地址方式 --- 引用类型作参数
什么是引用?
引用: 它用来给一个对象提供一个替代的名字
引用类型作形参的三点说明 (引用形使用的较多)
1) 传递引用给函数与传递指针的效果是一样的, 形参变化实参也发生变化
2) 引用类型作形参, 在内存中并没有产生实参的副本, 它直接对形参操作; 而一般变量作为参数, 形参与实参就占用不同的存储单元, 所以形参变量的值是实参变量的副本. 因此, 当参数传递的数据量较大时, 用引用比用一般变量传递参数的时间和空间效率都好
3) 指针参数虽然也能达到与使用引用的效果, 但在被调函数中需要重复使用 " *指针变量名 " 的形式进行运算, 这很容易产生错误且程序的阅读性较差; 另一方面, 在主调函数的调用点除, 必须用变量的地址作为实参
为了表达 线性表的顺序存储 我们需要 elem和length 这两个部分 放在一起共同来表达 这个顺序表(Squence List)
其中的逻辑结构与存储结构之间相差1 即 逻辑位序和物理位序相差1
顺序表上的查找操作
在线性表L中查找与指定值e相同的数据元素的位置
从表的一端开始, 逐个进行记录的关键字和给定值的比较. 找到, 返回该元素的位置符号 , 未找到, 返回0;
顺序表的查找算法分析是什么?
顺序表的查找算法分析:
平均查找长度 ASL (Average Search Length):
为确定记录在表中的位置, 需要与给定值进行比较的关键字的个数的期望值叫做查找算法的平均查找长度
什么是顺序表的插入?
线性表的插入运算是指在表的第 i (1<=i <= n+1) 个位置上, 插入一个新节点 e , 使长度为 n 的线性表 (a1, ...., a1-1, ...., an)变成长度为 n+1 的线性表 (a1, ..., ai-1, e, ai, ..., an)
算法思想:
1. 判断插入位置 i 是否合法
2. 判断顺序表的存储空间是否已满, 若已满返回 ERROR
3. 将第n至第i位的元素依次向后移动一个位置, 空出第 i 个位置.
4.将要插入的新元素e 放入第i个位置
5. 表长加1, 插入成功返回 OK
什么是顺序表的删除?
顺序表的删除
线性表的删除运算是指将表的第 i (1<=i<=n) 个结点删除
使长度为n的线性表
变成长度为n-1的线性表
算法思想:
1.判断删除位置i是否合法 (合法值为 1<=i<=n)
2.将欲删除的元素保留在 e 中
3.将第 i+1 至 第 n位的元素依次向前移动一个位置
4. 表长减1, 删除成功返回 OK
若要考虑在各种位置删除 (共 n 种可能) 的平均移动次数, 该如何计算?
平均移动次数 = (n-1) / 2 数量级 也是 O(n)