数据结构之线性表
- 线性表
线性表是零个或者多个元素组成的有限序列,每个元素最多只有一个前驱/后驱,且元素的数据类型相同。主要分为两种结构,顺序存储结构,链表结构
-
- 顺序存储结构
- 特点
使用连续的存储结构进行存储,通过数组的拷贝来不断扩容。
- 优缺点
优点:对于小线性表或长度固定的线性表,具有简单、运算方便等优点;同时随机访问速度快,O(1)。
缺点:插入删除时间复杂度为O(n),同时会造成空间浪费的情况
-
- 链表存储结构
- 特点
存储空间不连续,每一个元素都包含数据域以及指针域(用于执行上一个/下一个节点的位置)

- 优缺点
随机访问速度慢;插入删除速率高,同时节省内存资源
- 单链表结构

- 双链表结构

- 队列:先进先出
如,排队;从队尾插入,从对头取出。
-
- 顺序队列:ArrayList
- 属性:Object[] date,int size
Object[] date:存储空间的起始位置
int size:当前线性表的长度
int default_capicaty:默认初始化长度,10

- 初始化
设置size=0,同时使用设定或者 default_capicaty初始化数组date
- 插入
如排队购票中,某个人插入队中,如果序列长度不足需增加队列长度,随后逐个移动元素。
- 待插入的下标位置是否在当前序列合法位置内:rangeCheckForAdd(index);
- 如果Size+1 > 数组长度,则数组扩容,newCapacity = oldCapacity + (oldCapacity >> 1);
使用的方法:elementData = Arrays.copyOf(elementData, newCapacity)
- 逐个后移: System.arraycopy(elementData, index, elementData, index + 1, size - index)
- 插入元素到特定位置并增加序列的长度:elementData[index] = element;size++;
- 删除特定下标元素
下标校验并移动数组System.arraycopy(elementData, index+1, elementData, index,size - index - 1)
- 便利,获取特定下标元素
数组便利
- 长度获取,为空判断,置空
通过size进行长度以及为空操作;置空时设置size=0,date=null
- 优缺点
适合于长度固定或者比较小的队列,其便利速度快,但是插入删除操作速率慢
-
- 链队列:LinkedList
- 属性
LinkedList<E>{int size = 0;//序列长度 Node<E> first;//头节点 Node<E> last;//尾节点}

- 节点定义
Node<E> { Node<E> prev;//前继节点 E item;//数据域 Node<E> next;//后继节点 }
- 插入add(E e),addLast(E e)
- 封装数据元素为尾节点:newNode = new Node<>(l, e, null);
- 如果last == null即链表为空,设置first,last为当前节点;否则设置尾节点的next指向该节点;size++。
- 插入addFirst(E e)
- 封装数据元素为头节点:newNode = new Node<>(null, e, f);
- 如果first== null即链表为空,设置first,last为当前节点;否则设置头节点的first指向该节点;size++。
- 插入add(int index, E element)

- Index下标检查:index >= 0 && index <= size (以插入完成后的序列进行校验)
- 插入节点:原位置节点succ=node(index),原位置的前继节点pred = succ.prev
设置新的当前位置节点:newNode = new Node<>(pred, e, succ);
设置succ节点的前继节点为当前节点 succ.prev = newNode;
设置pred 的后继节点为当前节点(如果pred ==null 则设置first = newNode):
Size++;
- 便利 node(int index)
使用二分法,如果节点在前半截,则使用first便利;否则使用last便利
- 删除 removeFirst(),removeLast(),remove(Object o),remove(int index)
分为删除头节点,尾节点,中间节点三种情

- 优缺点
适合于长度变化比较大的队列,但是插入删除操作速率快,便利速率慢
- 栈:后进先出
如中缀表达式转化为后缀表达式,后缀表达式计算,浏览器回退功能,十进制转化二进制等。插入删除操作的都是头部
-
- 顺序栈:Stack,Vector

- 属性
Object[] elementData;
int elementCount; //序列长度,同时用于标记栈顶位置(elementCount-1)
- 初始化,置空,长度获取
- 入栈 push(E item)
- 数组扩容判断
- 入栈:elementData[elementCount++] = obj;
- 弹出 pop()
- elementData(elementCount-1) 并重置原位置元素为null
- 弹出 peek()
elementData(elementCount-1),不删除
- 便利 search(Object o)
返回元素在栈中的位置,从栈顶开始为1
- 优缺点
顺序栈需要事先确定一个固定的长度,可能会存在内存空间浪费的问题;适合于长度固定或者比较小的栈
-
- 链栈

- 属性
int size = 0;//序列长度 Node<E> first;//头节点
- 节点定义
Node<E> { E item;//数据域 Node<E> next;//后继节点 }
- 入栈
新的节点的next指向原top节点,使用top=新的节点
- 优缺点
链栈则要求每个元素都有指针域,这也会增加了一些内存开销,但栈的长度就可以无限制。