本文将讨论线性结构中的线性表。线性结构的特点是:在数据元素的非空有限集中:
- 存在唯一的一个被称做“第一个”的数据元素;
- 存在唯一的一个被称做“最后一个”的数据元素;
- 除第一个之外,集合中的每个数据元素均只有一个前驱;
- 除最后一个之外,集合中的每个数据元素均只有一个后继。
线性表则是最常用且最简单的一种线性结构,一个线性表示 n 个数据元素的有限序列。在稍复杂的线性表中,一个数据元素可以由若干个数据项组成,此时,数据元素常被称为记录,含有大量记录的线性表又称为文件。
从上表就是一个典型的线性表,表中每个学生的情况为一个记录,它由学号,姓名,性别,出生年月,家庭住址等5个数据项组成。从例子中可以看出,线性表中的数据元素可以是各种各样的,但是同一线性表中的元素必定具有相同特性,即属于同一数据对象,相邻数据元素之间存在着序偶关系。
若将线性表记为
线性表中元素的个数
n(n⩾0)
定义为线性表的长度,
n(n=0)
时称为空表。在非空表中的每个数据元素都有一个确定的位置,称
ai
是第
i
个数据元素,称
抽象数据类型线性表的定义如下:
下面则是线性表结构的Java实现(测试结果大致没问题,由于时间关系,一些细枝末节的问题可能没有考虑充分,望见谅!):
/**
* 线性表接口LinearList,泛型参数T表示数据元素的数据类型
*/
public interface LinearList<T> {
/**
* 构造一个空的线性表
*/
void InitList();
/**
* 销毁线性表
*/
void DestoryList();
/**
* 将线性表重置为空表
*/
void ClearList();
/**
* 判断线性表是否为空
* @return
*/
Boolean ListEmpty();
/**
* 获取线性表的数据元素个数
* @return
*/
int ListLength();
/**
* 返回线性表中第i个数据元素的值
* @param i
* @return
*/
T GetElem(int i);
/**
* 返回线性表中第1个与e满足compare()的数据元素的位序,若这样的数据不存在,则返回值为0
* @param e
* @return
*/
int LocateElem(T e);
/**
* 判断e1与e2是否满足指定的关系
* @param e1
* @param e2
* @return
*/
boolean compare(T e1, T e2);
/**
* 若cur_e是线性表的数据元素,且不是第一个,则返回它的前驱,否则操作失败
* @param cur_e
* @return
*/
T PriorELem(T cur_e);
/**
* 若cur_e是线性表的数据元素,且不是最后一个,则返回它的后继,否则操作失败
* @param cur_e
* @return
*/
T NextElem(T cur_e);
/**
* 在线性表中第i个位置之前插入新的数据元素e,线性表的长度加1
* @param i
* @param e
*/
void ListInsert(int i, T e);
/**
* 删除线性表的第i个元素,并返回其值,线性表的长度减1
* @param i
*/
T ListDelete(int i);
/**
* 依次对线性表的每个元素调用函数visit()。一旦visit()失败,则操作失败
*/
void ListTraverse();
/**
* visit函数
* @param e
*/
T visit(T e);
}
/**
* 线性表接口的实现类
*/
public class LinearListImpl<T> implements LinearList<T> {
/**
* 线性表对象
*/
protected Object[] list;
/**
* 线性表长度
*/
protected int len;
/**
* 构造一个空的线性表
*/
public void InitList() {
this.list = new Object[this.len];
}
/**
* 销毁线性表
*/
public void DestoryList() {
if (this.list != null) {//如果线性表已存在
this.len = 0;
this.list = null;
} else {
throw new IllegalArgumentException("线性表不存在");
}
}
/**
* 将线性表重置为空表
*/
public void ClearList() {
if (this.list != null) {//如果线性表已存在
this.len = 0;
this.list = new Object[this.len];
} else {
throw new IllegalArgumentException("线性表不存在");
}
}
/**
* 判断线性表是否为空
* @return
*/
public Boolean ListEmpty() {
if (this.list != null) {
if (this.len == 0)
return true;
else
return false;
} else {
throw new IllegalArgumentException("线性表不存在");
}
}
/**
* 获取线性表的数据元素个数
* @return
*/
public int ListLength() {
if (this.list != null)
return this.len;
else
throw new IllegalArgumentException("线性表不存在");
}
/**
* 用e返回线性表中第i个数据元素的值
* @param i
* @return
*/
public T GetElem(int i) {
if (this.list != null && i >= 1 && i <= ListLength()) {
return (T) this.list[i-1];
} else
throw new IllegalArgumentException("线性表不存在或者索引值不合理");
}
/**
* 返回线性表中第1个与e满足compare()的数据元素的位序,若这样的数据不存在,则返回值为0
* @param e
* @return
*/
public int LocateElem(T e) {
if (this.list != null) {
if (this.len == 0)//如果线性表为空,则直接返回0
return 0;
else {
for(int i = 0;i < this.len;i++){
if(compare((T) this.list[i],e))
return i+1;
}
return 0;
}
} else
throw new IllegalArgumentException("线性表不存在或者索引值不合理");
}
/**
* 判断e1与e2是否满足指定的关系
*
* @param e1
* @param e2
* @return
*/
public boolean compare(T e1, T e2) {
if(e1.equals(e2))
return true;
else
return false;
}
/**
* 若cur_e是线性表的数据元素,且不是第一个,则用pre_e返回它的前驱,否则操作失败
* @param cur_e
* @return
*/
public T PriorELem(T cur_e){
if (this.list != null) {
for(int i = 0;i < this.len;i++){
if(this.list[i] == cur_e && i != 0){
return (T) this.list[i-1];
}
}
throw new IllegalArgumentException("操作失败");
} else
throw new IllegalArgumentException("线性表不存在或者索引值不合理");
}
/**
* 若cur_e是线性表的数据元素,且不是最后一个,则返回它的后继,否则操作失败
* @param cur_e
* @return
*/
public T NextElem(T cur_e){
if (this.list != null) {
for(int i = 0;i < this.len;i++){
if(this.list[i] == cur_e && i != this.len){
return (T) this.list[i+1];
}
}
throw new IllegalArgumentException("操作失败");
} else
throw new IllegalArgumentException("线性表不存在或者索引值不合理");
}
/**
* 在线性表中第i个位置之前插入新的数据元素e,线性表的长度加1
* @param i
* @param e
*/
public void ListInsert(int i, T e){
if(this.list != null && i >= 1 && i <= ListLength() + 1){
Object[] newList = new Object[this.len+1];
if(this.len == 0){//如果线性表为空
this.len++;
this.list = new Object[this.len];
this.list[0] = e;
}else{
for(int k = 0;k < newList.length;k++){
if(k < i)
newList[k] = this.list[k];
else if(k == i)
newList[k] = e;
else
newList[k] = list[k-1];
}
this.list = newList;
this.len = newList.length;
}
}else
throw new IllegalArgumentException("线性表不存在或者索引值不合理");
}
/**
* 删除线性表的第i个元素,并返回其值,线性表的长度减1
* @param i
*/
public T ListDelete(int i){
T value = null;
Object[] newList = new Object[this.len-1];
if(this.list != null && i >= 1 && i <= ListLength() && this.len != 0){
if(this.len == 1){
this.len--;
value = (T) this.list[0];
ClearList();
}else{
if(i == 1){
for(int k = 1;k < this.len;k++) {
value = (T) this.list[0];
newList[k-1] = this.list[k];
}
}else if(i == ListLength()){
for(int k = 0;k < this.len-1;k++){
value = (T) this.list[len-1];
newList[k] = this.list[k];
}
}else {
for (int k = 0; k < this.len; k++) {
if (k < i - 1)
newList[k] = this.list[k];
else if(k == i-1)
value = (T) this.list[k];
else
newList[k-1] = this.list[k];
}
}
}
}else
throw new IllegalArgumentException("线性表不存在或者索引值不合理");
this.list = newList;
this.len = newList.length;
return value;
}
/**
* 依次对线性表的每个元素调用函数visit()。一旦visit()失败,则操作失败
*/
public void ListTraverse(){
Object[] newList = new Object[this.len];
for(int i = 0;i < this.len;i++)
newList[i] = visit((T) list[i]);
this.list = newList;
}
/**
* visit函数
* @param e
*/
public T visit(T e){
return (T) e.toString();
}
public static void main(String[] args) {
LinearList<Integer> linearList = new LinearListImpl<Integer>();
linearList.InitList();//初始化线性表
//linearList.DestoryList();//销毁线性表
//linearList.ClearList();//清空线性表
linearList.ListInsert(1,3);//添加值
linearList.ListInsert(1,4);
linearList.ListInsert(2,5);
linearList.ListInsert(2,6);
Boolean flag = linearList.ListEmpty();//判断线性表是否为空
int len = linearList.ListLength();//返回线性表的长度
int index = linearList.LocateElem(4);//返回线性表中第一个与e+1满足等于关系的元素的位序
int result1 = linearList.GetElem(2);//返回线性表中的第i个元素
int cur_e = 4;
int result2 = linearList.PriorELem(cur_e);//若cur_e是线性表的数据元素,且不是第一个,则返回它的前驱,否则操作失败
int result3 = linearList.NextElem(cur_e);//若cur_e是线性表的数据元素,且不是最后一个,则返回它的后继,否则操作失败
int result4 = linearList.ListDelete(4);//删除元素
linearList.ListTraverse();//依次对线性表的每个元素调用函数visit()
}
}