线性表:n个具有相同特性的数据元素的有限队列
常见线性表包括:
线性表在逻辑上是线性结构,但在物理结构上不一定是连续的,线性表在物理存储时,通常以数组或链式结构进行存储
一.顺序表
顺序表:用数组存储数据的物理地址连续的线性结构,在数组上完成数据的增删改查
接口实现:
//在pos位置插入val
boolean add(int pos,Object data);
//查找关键字key 找到返回key的下标,没有返回null;
int search(Object key);
//查找是否包含关键字key是否在顺序表当中(这个和search有点冲突)
boolean contains(Object key);
//得到pos位置的值
Object getPos(int pos);
//删除第一次出现的关键字key
Object remove(Object key);
//得到顺序表的长度
int size();
//打印顺序表
void display();
//清空顺序表以防内存泄漏
void clear();
总结:
- 中间/尾部插入的时间复杂度为O(n)
- 增容需要申请空间,拷贝数据,释放旧空间,会与不小的消耗
- 增容一般呈2倍增长,会浪费一定的空间
二.链表
链表:物理存储结构上非连续,非顺序的存储结构,数据元素的逻辑顺序是通过链表的引用链接次序实现的
常用的的三种结构:
- 无头单向非循环链表:哈希桶,图的邻接表的子结构
- 带头循环单链表
- 不带头双向循环链表:LinkedList底层实现的就是这种结构
接口实现:
无头单向废循环链表实现
// 1、无头单向非循环链表实现
public interface ILinked {
//头插法
void addFirst(int data);
//尾插法
void addLast(int data);
//任意位置插入,第一个数据节点为0号下标
boolean addindex(int index,int data);
//查找是否包含关键字key是否在单链表当中
boolean contains(int key);
//删除第一次出现关键字为key的节点
int remove(int key);
//删除所有值为key的节点
void removeAllKey(int key);
//得到单链表的长度
int getLength();
void display();
void clear();
}
带头循环链表实现
//2、带头循环单链表实现
public interface ICLinked {
//头插法
void addFirst(int data);
//尾插法
void addLast(int data);
//任意位置插入,第一个数据节点为0号下标
boolean addindex(int index,int data);
//查找是否包含关键字key是否在单链表当中
boolean contains(int key);
//删除第一次出现关键字为key的节点
int remove(int key);
//删除所有值为key的节点
void removeAllKey(int key);
//得到单链表的长度
int getLength();
void display();
void clear();
}
不带头双向链表实现
// 3、不带头双向链表实现
public interface IDoubleLinked {
//头插法
void addFirst(int data);
//尾插法
void addLast(int data);
//任意位置插入,第一个数据节点为0号下标
boolean addindex(int index,int data);
//查找是否包含关键字key是否在单链表当中
boolean contains(int key);
//删除第一次出现关键字为key的节点
int remove(int key);
//删除所有值为key的节点
void removeAllKey(int key);
//得到单链表的长度
int getLength();
void display();
void clear();
}
三.顺序表和链表的区别与联系
顺序表:一白遮全丑
白:空间连续,支持随机访问
丑:中间或前面部分的插入删除的时间复杂度为O(n),增容的代价大
链表一胖毁所有
胖:以结点为单位存储,不支持随机访问
所有:任意位置插入或删除的时间复杂度为O(1),没有增容问题,插入一个开辟一个空间
顺序表随机访问元素快,链表添加删除元素快
四.栈
栈:一种特殊的线性表,只允许在表的一端进行插入和删除操作,进行数据插入和删除操作的一端叫栈顶,另一端叫栈底(先进后出)
栈的实现:一般用数组或者链表实现,相对而言数组的结构更优一些,因为数组在尾插的代价比较小
接口实现:
interface MyStack {
// 判断这个栈是否为空栈
boolean empty();
// 返回栈顶元素,但不出栈
int peek();
// 返回栈顶元素,并且出栈
int pop();
// 将 item 压入栈中
void push(int item);
// 返回元素个数
int size();
}
五.队列
队列:一种特殊的线性表,只允许在一端进行数据的插入操作,另一端进行数据的删除操作,进行插入操作的一端叫队尾,进行删除操作的一端叫对头,(先进先出)
队列的实现:队列也可以用数组或链表实现,使用链表的结构更优一些,因为如果使用数组结构,出队列在数组头上出数据,效率会比较低
插入操作
删除操作
接口实现:
interface IMyQueue {
// 判断这个队列是否为空
boolean empty();
// 返回队首元素,但不出队列
int peek();
// 返回队首元素,并且出队列
int poll();
// 将 item 放入队列中
void add(int item);
// 返回元素个数
int size();
}