线性结构的特点:在数据元素的非空有限集中,(1)存在唯一第一个被称作“第一个”的数据元素;(2)存在唯一的一个被称作“最后一个”的数据元素;(3)除第一个之外,集合中的每个数据元素均只有一个前去;(4)除最后一个之外,集合中每个数据元素均只有一个后继。
线性表是最常用且最简单的线性结构。
线性结构分为两种变现形式:顺序表示和链式表示
线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表中的数据元素。
顺序表示:便于随机存取,但是实现插入、删除操作时就要移动大量的元素
链式表示形式:逻辑上相邻的元素,其物理存储位置则不一定相邻。便于插入删除元素,但是在存取方面需要从头到位的遍历
顺序表示和链式表示的比较:
1.读写方式:顺序表可以顺序存取,也可以随机存取;链表只能从表头顺序存取元素;
2.逻辑结构与物理结构:顺序存储时,逻辑上相邻的元素其对应的物理存储位置也相邻;链式存储时,逻辑上相邻的元素,其物理存储位置则不一定相邻;
3.查找、插入和删除操作:
按值查找,当线性表在无序的情况下,两者的时间复杂度均为o(n);而当顺序表有序时,可采用折半查找,此时时间复杂度为o(log n);
按位查找,顺序表支持随机访问,时间复杂度为o(1);而链表的平均时间复杂度为o(n)。
顺序表的插入和删除操作平均需要移动半个表长的元素;链表的插入、删除操作时,只需修改相关节点的指针即可。
4.空间分配:顺序存储一般是基于静态存储分配,一单存储空间装满就不能扩充;链式存储的节点空间只有在需要的时候申请分配,只要内存有足够的空间即可分配。
Java实现线性表的顺序表示,写这点代码费了一个多小时,真心觉得对不起自己,数据结构这么多年一直是软肋 代码测试完成,要是有什么不对的,请各位大神赐教!
package linelist;
//线性表的顺序实现方式 泛型指的是该线性顺序表中存储的数据类型
public class ArrayList<T>
{
//设置线性表的默认长度
final int defaultSize =0;
//线性表的最大长度
int maxSize;
//线性表的当前长度
int length;
//存储线性表的数组
Object [] arryList;
/*
* 构造函数
* @param 构建顺序表的时候需要把线性表的长度作为参数传递进来
*/
public ArrayList (int size)
{
//初始化线性表
initList(size);
}
/*
* 初始化顺序表的方法
* @param size 指定需要建立的顺序表的长度
*/
public void initList(int size)
{
if (size<0) {
//当传递过来的线性表长度小于0的时候抛出异常
throw new RuntimeException("顺序表的长度不能小于0");
}else {
this.maxSize =size;
this.length =0;
this.arryList =new Object[size];
}
}
/*
* 获取表长的方法
*/
public int getLength()
{
int num=0;
for (int i = 0; i < maxSize; i++) {
if(arryList[i]!=null)
{
num++;
}
}
return num;
}
/*
* 按值查找
* 返回元素在顺序表中的下标
*/
public int getIndexByValue(Object e)
{
for (int i = 0; i < getLength(); i++) {
if(e==arryList[i])
{
return i;
}
}
//如果该元素不存在则返回-1
return -1;
}
/*
* 查找指定下标位置下的元素值
*/
public Object getValueByIndex(int i)
{
if(i<maxSize&&i>=0)
{
return arryList[i];
}else {
//如果输入下标小于0或者不小于线性表的最大长度则抛出异常
throw new RuntimeException("输入下标有误");
}
}
/*
* 在指定下标位置插入元素
*/
public void insertByIndex(int index,Object elem)
{
Object preTemp,reTemp;
if(index>=0&&index<this.getLength()+1)
{
if(this.getLength()+1<maxSize)
{
//要插入位置上原来的数据
preTemp =arryList[index];
//插入目标值
arryList[index]=elem;
//插入位置之后的值集体后移一位
for(int i=index+1;i<=this.getLength();i++)
{
//下面这三行实现前后两个位置数的交换
reTemp=arryList[i];
arryList[i]=preTemp;
preTemp =reTemp;
}
}else {
throw new RuntimeException("顺序表中元素已满,不能再进行插入!");
}
}else {
throw new RuntimeException("输入的顺序表下标不对");
}
}
/*
* 删除指定位置上数据
*
*/
public void deleteByIndex(int index) {
if(index>=0&&index<this.getLength())
{
for (int i = index; i < arryList.length-1; i++) {
arryList[i]=arryList[i+1];
}
}else {
throw new RuntimeException("输入的下标有误!");
}
}
/*
* 修改指定位置的元素为指定数据
*/
public void updateElemByIndex(int index,Object elem)
{
if (index>=0&&index<this.getLength())
{
arryList[index]=elem;
}else {
throw new RuntimeException("输入下标有误!");
}
}
/*
* 判空
*/
public boolean isEmpty()
{
return (getLength()==0)?true:false;
}
/*
* 删除顺序表
*/
public void destroyList()
{
this.length=0;
this.maxSize =0;
this.arryList =null;
}
//空表的简单初始化
public void init(Object...objects)
{
if(isEmpty())
{
for(int i=0;i<objects.length;i++)
{
arryList[i]=objects[i];
}
}else {
throw new RuntimeException("非空表不能使用这种初始化方法");
}
}
}