*文中内容来源于《数据结构 --Java语言描述》(第二版) 刘小晶 杜选 主编
*此系列文章作为学习记录,若文中内容有误,请大家指出,谢谢
线性表
线性表在计算机中能用顺序存储和链式存储两种存储结构表示。
线性表是由n(n >= 0)个数据元素所构成的有限序列,通常表示为(a0,a1,…,ai,…,an-1),其中下标i标识数据元素在线性表中的位序号,n表示线性表的表长,当n = 0时,此线性表为空表。
对于同一个线性表,其每一个数据元素的值虽然不同,但必须具有相同的数据类型;同时,数据元素之间具有一种线性的或“一对一”的逻辑关系,即:
- 第一个数据元素没有前驱,该数据元素也称为开始结点;
- 最后一个数据元素没有后继,该数据元素也称为终端结点;
- 除第一个后最后一个数据元素外,其他数据元素有且仅有一个前驱和一个后继。
线性表的抽象数据类型描述(Java实现):
public interface IList {
public void clear();
public boolean isEmpty();
public int length();
public Object get(int i) throws Exception;
public void insert(int i, Object x) throws Exception;
public void remove(int i) throws Exception;
public int indexOf(Object x);
public void display();
}
线性表的顺序存储及其实现:
- 定义
顺序存储是用一组地址连续的存储单元依次存放线性表汇中各个数据元素的存储结构。 - 地址计算公式
线性表中所有数据元素的类型是相同的,所以每一个数据元素在存储器中占用相同大小的空间。假设每一个数据元素占c个存储单元,且a0的存储地址为Loc(a0)(此地址也称为线性表的基地址),则第i个数据元素的地址可表示为:
Loc(ai) = Loc(a0) + i*c 其中,0 <= i < n-1 - 特点
(1)在线性表中逻辑上相邻的数据元素,在物理存储位置上也是相邻的。
(2)存储密度高,但需要预先分配“足够应用”的存储空间,这可能将会造成存储空间的浪费;其中,存储密度=(数据本身值所需的存储空间/该数据元素实际所占有的空间);
(3)便于随机存取;
(4)不便于插入和删除操作,因为在顺序表上进行插入和删除操作会引起大量数据元素的移动。
顺序表的实现:
package Book_U2;
public class SqList implements IList{
private Object[] listElem; //线性表存储空间
private int curLen;
//顺序表类的构造函数,构造一个存储空间容量为maxSize的线性表
public SqList(int maxSize){
curLen = 0; //置顺序表的当前长度为0
listElem = new Object[maxSize]; //为顺序表分配maxSize个存储单元
}
//将一个已经存在的线性表置为空表
public void clear(){
curLen = 0; //置顺序表的当前长度为0
}
//判断线性表中的数据元素是否为0,若为0,则返回true;否则返回false
public boolean isEmpty(){
return curLen == 0;
}
//求线性表中的数据元素个数并返回该值
public int length(){
return curLen; //返回顺序表当前长度
}
/**
* 读取到线性表中的第i个数据元素并由函数返回其值,其中i的取值范围为:0 <= i <= length()-1,
* 若i值不在此范围则抛出异常
*/
public Object get(int i) throws Exception{
if (i < 0 || i > curLen - 1) //i小于0或大于表长减1,数据长度不合法
throw new Exception("第" + i + "个元素不存在");
return listElem[i]; //返回顺序表中第i个数据元素
}
//在线性表的第i个数据元素之前插入一个值为x的数据元素
public void insert(int i, Object x) throws Exception{
if (curLen == listElem.length) //判断顺序表是否已满
throw new Exception("顺序表已满");
if (i < 0 || i > curLen )
throw new Exception("第" + i + "个元素不存在");
for (int j = curLen; j > i; j--)
listElem[j] = listElem[j - 1]; //插入位置及其以后的所有数据元素都后移一位
listElem[i] = x; //插入x
curLen++; //表长加1
}
//删除并返回线性表中第i个元素
public void remove(int i) throws Exception{
if (i < 0 || i > curLen - 1) //i不合法
throw new Exception("删除位置不合法"); //抛出异常
for (int j = i; j < curLen - 1; j++)
listElem[j] = listElem[j + 1]; //被删除元素后的所有数据元素左移一个存储位置
curLen--; //表长减1
}
//返回线性表中首次出现指定的数据元素的序号,若线性表中不包含此数据元素,则返回-1
public int indexOf(Object x){
int j = 0; //j指示顺序表中待比较的数据元素,其初始值指示顺序表中第0个数据元素
while (j < curLen && !listElem[j].equals(x)) //依次比较
j++;
if (j < curLen) //判断j的位置是否位于顺序表中
return j;
else
return -1; //值为x的数据元素在顺序表中不存在
}
public void display() {
for (int j = 0; j < curLen; j++)
System.out.print(listElem[j] + "");
System.out.println();
}
}