概念:线性表是由n个元素所构成的有限序列。
对于同一个线性表,其每一个数据元素的值虽然不同,但必须具有相同的数据类型;同时,数据元素之间具有一种线性的“一对一”的逻辑关系,即:
(1)第一个数据元素没有前驱,这个数据元素被称为开始节点
(2)最后一个数据元素没有后继,这个数据元素被称为终端节点。
(3)除了第一个元素与最后一个元素以外,其他元素有且仅有一个前驱和一个后继。
线性表的抽象数据类型描述:
线性表结构简单,其长度允许动态的增长或者收缩;可以对线性表中的任何数据元素进行访问和查找;数据元素的插入和删除操作可以在线性表的任何位置上进行;求线性表中指定数据元素的前驱和后继;可以将两个线性表合成为一个线性表,或将一个线性表拆分为多个线性子表。下面说明几种主要的基本操作:
(1)线性表的置空操作 clear(); 将一个已经存在的线性表置为空表。
(2)线性表判断空操作isEmpty()
(3)求线性表长度操作 length()
(4)取元素操作 get(i)
(5)插入元素操作insert(i,x)。在线性表的第i个数据元素之前插入一个值为x的数据元素。
(6)删除操作 remove(i) 删除并返回线性表中第i个数据元素。
(7)查找操作 indexOf(x) 返回线性表中首次出现的指定的数据元素的位序号,若线性表中不包含此元素,则返回-1。
(8)输出操作display() 输出线性表中 的各个数据元素的值。
线性表的抽象数据类型用java接口描述如下:
public interface List
{
public void clear();
public boolean isEmpty();
public int length();
public Object get(int i);
public void insert(int i,Object x);
public void remove(int i);
public int indexOf(Object x);
public void display();
}
要使用线性表的java接口,还需要具体的类来实现接口,下面该处线性表的java接口的两种实现方法,一种是基于顺序存储的实现,一种是基于链式存储的实现。
线性表的顺序存储及其实现:
1.顺序表的定义:
所谓顺序表就是顺式存储的线性表。顺式存储是用一组地址连续的存储单元依次存放线性表中各个数据元素的存储结构。
2.顺序表的特点:
—在线性表中逻辑上相邻的数据元素,在物理存储位置上也是相邻的。
—存储密度高,但是要预先分配“足够够用”的存储空间,这可能会造成存储空间的浪费。
–便于随机存取
—不便于插入和删除操作,这是因为在顺序表上进行的插入和删除操作会引起大量的数据元素的移动。
——————————————————
顺序表的java语言描述:
package com.test1;
public class SqList implements List
{
private Object[] listElem; //线性表的存储空间
private int curLen; //线性表的当前长度
//顺序表类的构造函数,构造一个存储空间容量为maxSize的线性表
//构造函数完成对顺序表的初始化工作
public SqList(int maxSize)
{
curLen = 0; //置顺序表的当前长度为0
listElem = new Object[maxSize];// 为线性表分配maxSize个存储单元
}
//将一个已经存在的线性表置为空表
@Override
public void clear()
{
curLen = 0; //置顺序表的当前长度为0
}
//判断线性表中的数据元素的个数是否为0,若为0,则返回true,否则返回false
@Override
public boolean isEmpty()
{
return curLen ==0;
}
//求线性表中的数据元素的个数并返回值
@Override
public int length()
{
return curLen; //返回线性表的当前长度
}
@Override
public Object get(int i) throws Exception
{
if(i<0 || i>curLen-1)
throw new Exception("元素不存在");
return listElem[i];
}
//在线性表的第i个元素之前插入一个值为x的数据元素
@Override
public void insert(int i, Object x)
{
// .....
}
//删除并返回线性表中的第i个数据元素
@Override
public void remove(int i)
{
// ...
}
//返回线性表中首次出现的指定的数据元素的位序号,若线性表中不包含此元素,则返回-1
@Override
public int indexOf(Object x)
{
// ...
}
//输出操作display() 输出线性表中 的各个数据元素的值
@Override
public void display()
{
for (int i = 0; i < curLen; i++)
{
System.out.println(listElem[i]+"");
System.out.println(""); //换行
}
}
}
—————————————
顺序表上基本操作的实现:对线性表的清空,判断空,求长度和取元素操作都容易实现。因此,以下介绍顺序表的插入,删除和查找操作的实现方法。
- 顺序表上的插入操作:
顺序表上进行插入操作的基本要求是在已知顺序表上第i个数据元素的ai之前插入一个值为x的数据元素,其中0<= i <=n,n为顺序表的当前长度,当 i=0时,在表头插入x,当i=时,在表尾插入x.
根据顺序表的存储特点,逻辑上相邻的数据元素在物理上也是相邻的,要在数据元素ai之前插入一个新的数据元素,则需要将低i个元素ai及其之后的元素后移一个存储位置,再将待插入的数据元素插入到腾出的存储位置上。主要步骤如下:
—判断当前顺序表的存储空间是否已满,若满则抛出异常。
—判断参数i的合法性,若i不合法将抛出异常。
—确定插入位置。
—将插入位置及其之后的所有元素后移一个存储位置。
—表长加1.
算法:
public void insert(int i, Object x) throws Exception
{
if(curLen == listElem.length) //判断顺序表是否已满
{
throw new Exception(“顺序表已满”); //抛出异常
}
if(i<0 || i>curLen) //i不合法
{
throw new Exception("插入位置不合法"); //抛出异常
}
for(int j = curLen;j>i;j--)
{
listElem[j] = listElem[j-1]; // 插入位置及其之后的元素后移一位
}
listElem[i] = x; //插入x
curLen ++; //表长加1
}
2.顺序表上的删除操作:
顺序表上的删除操作的基本要求是将已知顺序表上的第i个数据元素ai从顺序表中删除。
删除操作后为保持逻辑上相邻的数据元素在存储位置上也相邻,就要将第i个数据元素ai之后的所有元素都向前移动一个存储位置。主要步骤如下:
—判断参数i的合法性,若i不合法则抛出异常
—将第i个数据元素之后的所有数据元素向前移动一个存储位置。
—表长减1.
@Override
public void remove(int i) throws Exception
{
if(i <0 || i> curLen -1) //i不合法
{
throw new Exception(“i不合法”);
}
for(int j=i;j<curLen;j++)
{
listElem[j] = listElem[j+1]; //删除元素之后的元素向前移动一位
}
curLen--; //表长减1
}
3.顺序表上的查找操作:
public int indexOf(Object x)
{
int j=0;//j指示顺序表中待比较的数据元素,其初始值指示顺序表中第0个数据元素
while(j
package com.test1;
public class SqList implements List
{
private Object[] listElem; //线性表的存储空间
private int curLen; //线性表的当前实际长度
//顺序表类的构造函数,构造一个存储空间容量为maxSize的线性表
//构造函数完成对顺序表的初始化工作
public SqList(int maxSize)
{
curLen = 0; //置顺序表的当前长度为0
listElem = new Object[maxSize];// 为线性表分配maxSize个存储单元
}
//将一个已经存在的线性表置为空表
@Override
public void clear()
{
curLen = 0; //置顺序表的当前长度为0
}
//判断线性表中的数据元素的个数是否为0,若为0,则返回true,否则返回false
@Override
public boolean isEmpty()
{
return curLen ==0;
}
//求线性表中的数据元素的个数并返回值
@Override
public int length()
{
return curLen; //返回线性表的当前长度
}
@Override
public Object get(int i) throws Exception
{
if(i<0 || i>curLen-1)
throw new Exception("元素不存在");
return listElem[i];
}
//在线性表的第i个元素之前插入一个值为x的数据元素
@Override
public void insert(int i, Object x) throws Exception
{
if(curLen == listElem.length) //判断顺序表是否已满
{
throw new Exception("顺序表已满"); //抛出异常
}
if(i<0 || i>curLen) //i不合法
{
throw new Exception("插入位置不合法"); //抛出异常
}
for(int j = curLen;j>i;j--)
{
listElem[j] = listElem[j-1]; // 插入位置及其之后的元素后移一位
}
listElem[i] = x; //插入x
curLen ++; //表长加1
}
//删除并返回线性表中的第i个数据元素
@Override
public void remove(int i) throws Exception
{
if(i <0 || i> curLen -1) //i不合法
{
throw new Exception("i不合法");
}
for(int j=i;j<curLen;j++)
{
listElem[j] = listElem[j+1]; //删除元素之后的元素向前移动一位
}
curLen--; //表长减1
}
//返回线性表中首次出现的指定的数据元素的位序号,若线性表中不包含此元素,则返回-1
@Override
public int indexOf(Object x)
{
int j=0;//j指示顺序表中待比较的数据元素,其初始值指示顺序表中第0个数据元素
while(j<curLen && ! listElem[j].equals(x)) //依次比较
j++;
if(j<curLen)
return j; //返回x在顺序表中的存储位置
return -1; //在顺序表中不存在
}
//输出操作display() 输出线性表中 的各个数据元素的值
@Override
public void display()
{
for (int i = 0; i < curLen; i++)
{
System.out.println(listElem[i]+"");
System.out.println(""); //换行
}
}
}