线性表及其实现(顺序存储方式)
---
Linear List
Definition
基本运算(操作)
值传递和引用传递
值传递相当于在函数test内部创建了x的副本,修改发生在新副本上而不影响原x的值
引用传递相当于给出对象的引用(内存地址),函数可以直接访问到地址指向的对象并对其操作
在java中,primitive(原始数据类型)均通过值进行传递,其余对象均通过引用传递
对应在C++里,通过指明引用标识符&表示此处使用引用传递
线性表小结
前面说到,线性表是一种ADT,定义了数据结构三要素中的逻辑结构和数据的运算(基本操作),即定义了数据结构,接下来讨论如何实现数据结构,即对线性表的存储结构(物理结构)进行实现
例如,下面谈到的顺序表就是用顺序存储的方式实现的线性表
顺序表(Sequence List)
静态分配
代码分析
---如果不对数据元素赋初值0会怎样?---
---如图,内存中可能存在未被flush掉的脏数据,但不影响实际操作,因此可以省略---
静态分配存在的问题
动态分配
代码分析
动态分配本质上是在内存中开辟了一段新的存储空间,通过临时指针p将原空间数据复制迁移到新空间中,最后更新原数组指针,原理类似 Java 中的 ArrayList
特点
顺序表小结
顺序表的操作(数据运算)
插入
---注意操作的有效性判断---
顺序表的物理结构采用顺序存储,每次插入需要将后面的数据整体向后平移一格,因此最坏的时间复杂度为O(n)
删除
---注意通过引用&拿到原操作数据而非副本---
删除操作同样需要对后续数据进行前移,因此时间复杂度为O(n)
查找
按位查找
指针在内存中的步长对程序员是透明的,底层会自动根据数据类型的大小知道指针每次应该移动的长度
随机存储:查找第i个数据的时间复杂度为O(1)
按值查找
注意结构体的比较不能直接使用 ==
上面的算法采用正向遍历比较,时间复杂度为O(n)