线性表:零个或多个数据元素的有限序列。有直接前驱,有直接后继。所以移除或插入元素后,相应的元素要进行位置变动,以保证没有空白项,并且数据元素的类型要相同。
线性表的抽象数据类型:
ADT 线性表(List)
Data
线性表的数据对象集合为{ a1, a2, … , an },每个元素的类型均为DataType。其中,除第一个元素a1外,每一个元素有且仅有一个直接前驱元素;除了最后一个元素an外,每一个元素有且只有一个直接后继元素。
数据之间的关系是一对一的关系。
Operation
InitList(*L) 初始化操作,建立一个空的线性表
IsListEmpty(L) 判断线性表是否为空,若为空,返回true,否则false
ClearList(*L) 清空线性表
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的长度,即元素个数.
一、顺序表
顺序表元素的存储空间是连续的。在内存中是以顺序存储,内存划分的区域是连续的。顺序存储内存结构示意图:
线性表的顺序存储结构需要三个属性:
1.储存空间的起始位置:数组data,它的存储位置就是存储空间的存储位置。
2.线性表的最大存储容量:数组长度MaxSize。
3.线性表的当前长度:length。
新建一个线性表接口定义常用的操作:
public interface LinearList {
public boolean isEmpty();
public int size();
public void clear();
// 根据索引号得到元素
public Object get(int index);
// 判断线性表中是否包含此元素
public boolean contains(Object o);
// 向线性表添加元素至末尾
public void add(Object o);
// 向线性表指定位置插入元素
public void insert(Object o, int index);
// 修改指定索引的元素
public void set(Object o, int index);
// 根据索引移除元素
public Object remove(int index);
// 直接移除元素
public boolean remove(Object o);
// 得到元素首次出现的索引
public int indexof(Object o);
// 得到元素最后一次出现的索引
public int lastindexof(Object o);
}
新建一个类MyList实现接口:
public class MyList implements LinearList {
public Object[] data;
private int len;// 线性表的长度
private int maxsize;// 数组的最大长度
// 默认数组大小为10
public MyList() {
this(10);
}
public MyList(int size) {
if (size < 0) {
System.out.println("数组大小错误");
} else {
this.data = new Object[size];
this.len = 0;
this.maxsize = size;
}
}
public boolean isEmpty() {
if (len == 0)
return true;
else
return false;
}
public int size() {
return len;
}
public void clear() {
data = new Object[10];
this.len = 0;
}
public Object get(int index) {
if (index > 0 && index <= len)
return data[index - 1];
else
return null;
}
public boolean contains(Object o) {
for (int i = 0; i < len; i++) {
if (o.equals(data[i]))
return true;
}
return false;
}
// 当超出数组边界时,扩充数组
private void expand() {
maxsize = 2 * maxsize;
Object newdata[] = new Object[maxsize];
for (int i = 0; i < len; i++) {
newdata[i] = data[i];
}
data = newdata;
}
public void add(Object o) {
if (len >= maxsize) {
expand();
data[len] = o;
len++;
} else {
data[len] = o;
len++;
}
}
public void insert(Object o, int index) {
if (index > len && len < maxsize) {
data[len] = o;
len++;
} else if (index > len && len == maxsize) {
expand();
data[len] = o;
len++;
} else {
for (int i = len; i >= index; i--) {
data[i] = data[i - 1];
}
data[index - 1] = o;
len++;
}
}
public void set(Object o, int index) {
data[index - 1] = o;
}
public Object remove(int index) {
Object o = data[index - 1];
for (int i = index - 1; i < len; i++) {
data[i] = data[i + 1];
}
len--;
return o;
}
public boolean remove(Object o) {
if (indexof(o) > 0) {
remove(indexof(o));
return true;
} else
return false;
}
public int indexof(Object o) {
int index = 0;
for (int i = 0; i < len; i++) {
if (o.equals(data[i]))
index = i + 1;
}
if (index > 0 && index <= len)
return index;
else
return -1;
}
public int lastindexof(Object o) {
int i = len - 1;
while (i >= 0 && !data[i].equals(o)) {
i--;
}
if (i == 0) {
if (data[0].equals(o))
return 1;
else
return -1;
} else if (i > 0)
return i + 1;
else
return -1;
}
}