我们知道线性表结构一般分为三种:顺序线性表、单链表、双链表。下面将会使用
java语言实现顺序表。使用数组作为容器。
基于线性表的三种结构的操作都是一样的我们设计一个线性表接口。
package comkiritor.linear_table;
/**
* 线性表接口
* @author Kiritor
* */
public interface LinearTable <T>{
//判空
public boolean isEmpty();
//获取长度
public int getLength();
//返回某个位置的元素
public T getData(int index);
//设置index位置的元素,并返回先前的元素
public T setData(int index,T element);
//插入一个元素,位置没有限定(插入链表尾部)
public boolean addData(T element);
//在指定的位置插入一个元素
public boolean addData(int index,T element);
//删除某个位置的元素,并返回该元素
public T removeData(int index);
//清空线性表
public void clearData();
}
下面对顺序表进行实现
package comkiritor.linear_table;
/**
* 线性表的顺序实现
*
* @author Kiritor
* @param <T>
*/
public class SequenceTable<T> implements LinearTable<T> {
private T[] se_table;// 使用数组作为容器
private int length;// 表示线性表长度,元素的个数
// 通过构造函数初始化顺序表
public SequenceTable(int size) {
if (size <= 0) {
System.out.println("不能为负");
} else {
this.se_table = (T[]) new Object[size];
this.length = 0;
}
}
public SequenceTable() {
this(20);// 默认线性表空间为20
}
@Override
public boolean isEmpty() {
return length == 0;
}
@Override
public int getLength() {
return length;
}
// 下标从0开始的
@Override
public T getData(int index) {
if (index >= 0 && index < this.length) {
return (T) this.se_table[index];
}
return null;
}
// 下表从0开始的
public T setData(int index, T element) {
if (index >= 0 && index < this.length && element != null) {
T oldElement = (T) this.se_table[index];
this.se_table[index] = element;
return oldElement;
}
return null;
}
@Override
public boolean addData(T element) {
return addData(this.length, element);// 加到末尾
}
@Override
public boolean addData(int index, T element) {
if (element == null)
return false;
if (this.length == this.se_table.length) {
T[] tmp = this.se_table;
// 以2倍的方式进行扩容
this.se_table = (T[]) new Object[tmp.length * 2];
for (int i = 0; i < tmp.length; i++) {
this.se_table[i] = tmp[i];
}
}
if (index <= 0)
index = 0;// 小于0默认插入到第1个位置
if (index > this.length) {
index = this.length;// 大于线性表长度,则默认插入末尾的位置
}
// index<length时,后面的元素依次后移
for (int j = this.length - 1; j >= index; j--) {
this.se_table[j + 1] = this.se_table[j];
}
this.se_table[index] = element;
this.length++;
return true;
}
@Override
public T removeData(int index) {
if (this.length != 0 && index >= 0 && index < this.length) {
T old = this.se_table[index];
for (int i = index; i < this.length - 1; i++) {
// 依次前移
this.se_table[i] = this.se_table[i++];
}
this.se_table[this.length - 1] = null;// 最后一个元素占用的内容释放(JVM做)
this.length--;
return old;
}
return null;
}
@Override
public void clearData() {
if (this.length != 0) {
for (Object t : this.se_table) {
t = null;
}
}
}
public static void main(String[] args) {
SequenceTable sequenceTable = new SequenceTable(10);
sequenceTable.addData("java");
sequenceTable.addData("c");
sequenceTable.addData("c++");
System.out.println(sequenceTable.getLength());
System.out.println(sequenceTable.getData(3));
System.out.println(sequenceTable.getData(2));
sequenceTable.setData(3, "kkk");
System.out.println(sequenceTable.getData(2));
}
}
上面的实现中顺序表的插入和删除的操作是实现的重点。
关键点就是找到"插入点“,后面的元素依次前移或后移就成了,以一个头部插入为例。
根据上述的代码插入点为索引为0的位置。