数据结构和算法笔记 lesson3 线性表顺序存储结构
2016-11-01 08:50
429 查看
线性表
List 由 零个或多个数据元素组成的有限序列。是一个序列,有个先来后到的顺序
若有多个,第一个元素只有后驱,最后一个元素只有前驱,中间的元素有一个后驱和一个前驱
有限的元素
抽象数据类型 (ADT)
对已有的数据类型进行抽象。 是指一个数学模型及定义在该模型上的一组操作。抽象数据类型的定义仅取决于它的一组逻辑特性,而与其在计算机内部如何表示和实现无关。
为什么会有多种数据类型
进行分类,用不同数据类型进行计算,节省空间Operation
InitList( *L) : 初始化操作,建立一个空的线性表L.ClearList(*L): 清空线性表
ListEmpty(L): 判断线性表是否为空表 ,返回true 和 false
GetElem(L,i,*e): 将线性表L中的第i个位置元素返回给e
LocateElem(L,e): 在线性表L中查找与给定值e相等的元素,成功返回序号,返回0表示失败。
ListInsert(*L,i,e) : 在线性表L中第i 个位置插入新元素e
ListDelete(*L,i,*e) : 删除 线性表L中第i 个位置元素,并用e返回其值
ListLength(L): 返回线性表L的元素个数
实现线性列表的并集
循环遍历集合B中的每一个元素,判断元素是否存在A中,若不存在 ,则插入A中void unionL (List * La, list Lb) { int La_len , Lb_len , i ; ElemType e; La_len = ListLength(*La); Lb_len = ListLength(Lb); for( i = 1 ; i <= Lb_len; i++); { GetElem(Lb, i , &e ); if( !LocalElem( *La , e )) { ListInsert(La,++La_len,e); } } }
线性表的物理存储结构:
顺序存储结构
用一段地址连续的存储单元依次存储线性表的数据元素物理上的存储方式事实上就是在内存中找个初始地址,然后通过占位的形式,把一定的内存空间给占了,然后把相同数据类型的数据元素依次放在这块空地中
结构代码
#define MAXSIZE 20 typedef int ELemType typedef truct { ElemType data[MAXSIZE]; int length; //当前线性表长度 }SqList;
顺序结构封装需要三个属性:
存储空间的起始位置,数组data,它的存储位置就是线性表存储空间的存储位置。线性表的最大存储容量:数组的长度 MAXSIZE
线性表的当前长度: length
数组的长度与线性表的当前长度需要区分
数组的长度是存放线性表的存储空间的总长度,一般初始化后不变。线性表的当前长度是线性表中元素的个数,是会变化的。
地址的计算方法
假设ElemType占用的是c个存储单元(字节),那么线性表中第i 个数据元素和第i个数据元素的存储位置的关系是 LOC(ai+1) = LOC(ai) + c (LOC表示获得存储位置的函数)所以对于第i个元素ai的存储位置可以由a1 推算出: LOC(ai) = LOC(ai)+(i-1)*c
获得元素操作
Status GetElem (SqList* L , int i , ElemType *e) { if(L.length == 0 || i <1 || i> L.Length) return 0; *e = L.data[ i - 1]; return 1 ; }
线性表的顺序存储结构具有随机存储结构的特点,时间复杂度为O(1)
插入操作
思路:如果插入位置不合理, 抛出异常
如果线性表长度大于等于数组长度,则抛出异常或动态增加数组容量
从最后一个元素开始向前遍历到第i个位置,分别将它们向后移动一个位置
将要插入元素填入位置i
长度+1
Status ListInsert(SqList * L , int i ,ElemType e) { int k ; if (L-> length == MAXSIZE) return 0; if (i < 1 || i > L-> length+1) return 0; if (i <= L->length) { for(k = L-> length-1; k >= i - 1 ;k --) { L->data[k+1] = L -> data[k]; } } L-> data[i-1] = e; L->length++; return 1; }
删除操作
思路如果删除位置不合理,抛出异常
取出删除元素
从删除位置开始遍历到最后一个元素位置,分别将它们都向前移动一个位置
表长减1;
Status ListDelete(SqList * L , int i, ElemType *e) { int k ; if(L->length == 0) return 0; if( i<1 || i > L->length ) return 0; *e = L->data [i-1]; if(i<L->length) { for(k=i; k< L->Length ; k++) { L->data[k-1] = L->data[k]; } } L->length -- ; return 1; }
线性删除和插入的时间复杂度 都是O(n)
结论
线性表的顺序存储结构,在存、读数据是,不论在哪个位置,时间复杂度都是O(1 ) . 而在插入删除时,时间复杂度都是O(n)适合处理元素个数比较稳定,不经常插入和删除,而且更多操作是存取数据的应用
优点 :
无须为表示表中元素之间的逻辑关系而增加额外的存储空间。
可以快速地存取表中任意位置的元素
缺点:
插入和删除需要移动大量元素
当线性表长度较大时,难以确定存储空间的容量
容易造成存储空间的“碎片” 申请时都是一大块的内存,留下的小的就是碎片
为什么插入和删除时,就要移动大量的元素
相邻两元素的存储位置也具有邻居关系,它们在内存中的位置是紧挨着的,中间没有间隙,当然就无法快速插入和删除相关文章推荐
- 数据结构笔记:线性表顺序存储结构(C语言)
- 数据结构与算法之——线性表的顺序存储结构
- 数据结构学习笔记 --- 线性表 (一些常见的关于链表的算法和面试题)
- 数据结构笔记之线性表的顺序存储结构
- 数据结构学习笔记 --- 线性表 (一些常见的关于链表的算法和面试题)
- 数据结构和算法笔记 lesson4 线性表链式存储结构 单链表
- 张小五学算法与数据结构第三天:线性表的顺序存储结构
- 线性表8 - 数据结构和算法13
- 数据结构学习笔记 --- 线性表 (顺序表)
- 数据结构学习笔记 --- 线性表 (双向链表、循环链表)
- 线性表7 - 数据结构和算法12
- 算法与数据结构--实现线性表的删除操作--算法2.4
- 算法与数据结构--实现线性表的合并操作(合并后按非递减排列)--算法2.6
- 数据结构学习笔记一:简单排序与查询算法
- 线性表5 - 数据结构和算法10
- 线性表5 - 数据结构和算法10
- 《数据结构与算法C#语言描述》笔记10_散列和Hashtable类
- 数据结构和算法分析学习笔记(三)--二叉查找树的懒惰删除(lazy deletion)
- 严蔚敏版《数据结构》第二章线性表的算法C语言实现
- 数据结构学习笔记 --- 线性表 (单链表)