线性表
定义
线性表是具有相同类型的 n (n>=0) 个元素的有限序列,其中 n 为表长,当 n=0 时,该表为空表。
L = ( a 1 , a 2 , . . . a i , a i + 1 . . . , a n ) L=(a_{1},a_{2},...a_{i},a_{i+1}...,a_{n}) L=(a1,a2,...ai,ai+1...,an)
分类
线性表数据存储的方式分为两种,顺序存储和链式存储,按照数据存储方式不同,线性表分为顺序表和链表
顺序表
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储;即通过数据元素物理存储的连续性来反应元素之间逻辑上的相邻关系。
… | 1 | 2 | 3 | 4 | … | n |
---|
1.顺序表特点
- 空间连续
- 支持随机访问复杂度为O(1)
- 在中间或前面部分的插入删除时间复杂度为O(n),扩容的代价比较大
- 不会造成内存碎片化
2.存储结构图
3.顺序表实现
基本操作
初始化
插入元素
指定位置插入元素
设置指定位置元素值
删除指定位置的元素
检测是否为空
返回顺序表元素个数
返回顺序表中第一个与指定值相同的元素的位置
遍历顺序表
顺序表接口 IList.java
public interface IList<T> {
/**
* 顺序表表尾插入元素
*
* @param t
*/
void insert(T t);
/**
* 顺序表指定位置插入元素
*
* @param t
*/
void insert(T t, int i);
/**
* 设置指定位置元素值
*
* @param t
* @param i
*/
void set(T t, int i);
/**
* 删除指定位置元素
*
* @param i
* @return
*/
T remove(int i);
/**
* 返回顺序表中第一个与指定值相同的元素的位置
*
* @param t
* @return
*/
int indexOf(T t);
/**
* 检测是否为空
*
* @return
*/
boolean isEmpty();
/**
* 返回顺序表元素个数
*
* @return
*/
int length();
/**
* 遍历顺序表
*
* @return
*/
String traversal();
}
顺序表实现类 MyList.java
public class MyList<T> implements IList<T> {
/**
* 顺序表默认初始化容量大小
*/
private final static int DEFAULT_CAPACITY = 8;
/**
* 数组扩容倍数
*/
private final int N = 1;
/**
* 存储顺序表元素数组
*/
private T[] elementData;
/**
* 当前顺序表元素个数 size不一定等于 elementData.length
*/
private int size;
/**
* 初始化顺序表
*/
public MyList() {
elementData = (T[]) new Object[DEFAULT_CAPACITY];
size = 0;
}
public MyList(int capacity) {
elementData = (T[]) new Object[capacity];
size = 0;
}
public void insert(T t) {
if (size == elementData.length) {
dilatation();
}
elementData[size++] = t;
}
public void insert(T t, int i) {
if (i < 0) {
throw new RuntimeException("i value is Illegal");
}
//扩容
if (size == elementData.length) {
dilatation();
}
//i位置空出,i后面元素依次往后移动一位
for (int j = size; j > i; j--) {
elementData[j] = elementData[j - 1];
}
elementData[i] = t;
size++;
}
public void set(T t, int i) {
if (i < 0 || i > size) {
throw new RuntimeException("i value is Illegal");
}
elementData[i] = t;
}
public T remove(int i) {
if (i < 0 || i > size) {
throw new RuntimeException("i value is Illegal");
}
T result = elementData[i];
//i 后面元素往前移动一位
for (int j = i; j < size - 1; j++) {
elementData[j] = elementData[j + 1];
}
size--;
return result;
}
public int indexOf(T t) {
for (int i = 0; i < size; i++) {
if (elementData[i].equals(t)) {
return i;
}
}
return -1;
}
public boolean isEmpty() {
return size == 0;
}
public int length() {
return size;
}
public String traversal() {
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < size; i++) {
stringBuffer.append(elementData[i] + " ");
}
return stringBuffer.toString();
}
/**
* 扩容数组
*
* @return
*/
private void dilatation() {
//数组满,需扩容
T[] tempElementData = (T[]) new Object[DEFAULT_CAPACITY + N * DEFAULT_CAPACITY];
for (int i = 0; i < elementData.length; i++) {
tempElementData[i] = elementData[i];
}
elementData = tempElementData;
}
}
测试
public class MyListTest {
public static void main(String[] args) {
MyList<String> myList = new MyList<String>();
myList.insert("a");
myList.insert("b");
myList.insert("c");
myList.insert("d");
myList.insert("e");
System.out.println(myList.traversal());
int index = myList.indexOf("e");
System.out.println("元素e在位置" + index);
System.out.println("顺序表大小为" + myList.length());
myList.insert("nb", 1);
System.out.println(myList.traversal());
myList.remove(3);
System.out.println(myList.traversal());
}
}
a b c d e
元素e在位置4
顺序表大小为5
a nb b c d e
a nb b d e