您的位置:首页 > 理论基础 > 数据结构算法

JAVA数据结构-----顺序存储

2018-01-22 16:05 218 查看
线性表的顺序存储结构是指:用一组连续的存储单元依次存储线性表中的每个数据元素。即中间不允许有空,所以插入、删除时需要移动大量元素。

    


在JAVA中实现顺序存储结构---顺序表

首先,由于JAVA隶属于面向对象编程,所以这里大多数操作都是先定义(接口),然后实现相对于的接口也就实现了对“顺序表”的操作了。在这里,我们先定义一个myList

/**
* Created by Troshin on 2018/1/13.
*/
public interface myList {
//返回线性表大小
public int getSize();

//判断线性表是否为空
public boolean isEmpty();

//判断线性表是否包含元素e
public boolean contains(Object e);

//返回数据元素e在线性表中的序号
public int indexOf(Object e);

//将数据元素e插入到线性表i号位置
public void insert(int i, Object e) throws OutOfBoundaryException;

//将数据元素e插入到元素p之前
public boolean insertBefore(Object obj, Object e);

//将数据元素e插入到元素p之后
public boolean insertAfter(Object obj, Object e);

//删除线性表中序号为i的元素
public Object remove(int i)throws OutOfBoundaryException;;

//删除线性表中第一个与e相同的元素
public boolean remove(Object e);

//替换线性表中序号i的数据元素为e
public Object replace(int i, Object e)throws OutOfBoundaryException;;

//返回线性表中为i的数据元素
public Object get(int i)throws OutOfBoundaryException;;
}


myList接口中,我们把数据类型定义为Object,这样提高了复用性,关于JAVA基础知识不多解释,可以查阅相关书籍。
其中的异常,为序号越界时定义的异常。

/**
* Created by Troshin on 2018/1/13.
*/
public class OutOfBoundaryException extends RuntimeException{
public  OutOfBoundaryException(String err){
super(err);
}
}

由于定义的数据类型为Object,所以关于每个元素的比较都有着不一样的方法,这里我们自定义一个比较方法,其优点在于,一旦不想继续使用原先的比较策略对象,随时可以使用另一个比较策略对象将其替换,而不同修改抽象数据类型的具体实现。

/**
* Created by Troshin on 2018/1/13.
*/
public interface Strategy {
//判断两个数据元素是否相等
public boolean equal(Object obj1,Object obj2);

/**
* 比较两个数据元素的大小
* 如果 obj1 < obj2 返回-1
* 如果 obj1 = obj2 返回 0
* 如果 obj1 > obj2 返回 1
*/
public int compare(Object obj1,Object obj2);
}


前面说过,由于顺序存储结构在计算机内的存储位置是连续的,所以它的插入、删除等操作如图:





每次在第i个位置插入、删除都需要移动大量数据,所以时间复杂度为O(n)。具体实现:

/**
* Created by Troshin on 2018/1/13.
*/
public class ListArray implements myList {
private final int LEN=8;    //数组的默认大小
private Strategy strategy;  //数据元素比较策略
private int size;           //线性表中数据元素的个数
private Object[] elements;  //数据元素数组

//构造方法
public ListArray() {
this(new DefaultStrategy());
}

public ListArray(Strategy strategy){
this.strategy=strategy;
size=0;
elements=new Object[LEN];
}

/**
* 返回线性表的大小,即数据元素的个数
* @return
*/
@Override
public int getSize() {
return size;
}

/**
* 如果线性表为空返回true,否则返回false
* @return
*/
@Override
public boolean isEmpty() {
return size==0;
}

/**
* 判断线性表是否包含数据元素e,在就返回True,否则返回false
* @param e
* @return
*/
@Override
public boolean contains(Object e){
for(int i=0;i<size;i++)
if(strategy.equal(e,elements[i]))
return true;

return false;
}

/**
* 返回数据元素e在线性表中的序号
* @param e
* @return
*/
@Override
public int indexOf(Object e) {
for(int i=0;i<size;i++)
if(strategy.equal(e,elements[i]))
return 1;
return -1;

}

/**
* 将数据元素 e 插入到线性表中 i 号位置
* @param i
* @param e
* @throws OutOfBoundaryException
*/
@Override
public void insert(int i, Object e) throws OutOfBoundaryException {
if (i<0 || i>size)
throw  new OutOfBoundaryException("错误,指定插入的序号越界");
if(size>=elements.length)
expandSpace();
for (int j=size;j>i;j--)
elements[j]=elements[j-1];
elements[i]=e;
size++;
return;
}

private void expandSpace(){
Object[] a=new Object[elements.length*2];
for(int i=0;i<elements.length;i++)
a[i]=elements[i];
elements=a;
}

/**
* 将数据元素 e 插入到元素 obj 之前
* @param p
* @param e
* @return
*/
@Override
public boolean insertBefore(Object p, Object e) {
int i=indexOf(p);
if (i<0) return false;
insert(i,e);
return true;
}

/**
* 将数据元素 e 插入到元素 obj 之后
* @param p
* @param e
* @return
*/
@Override
public boolean insertAfter(Object p, Object e) {
int i=indexOf(p);
if (i<0) return false;
insert(i+1,e);
return true;
}

/**
* 删除线性表中序号为 i 的元素,并返回之
* @param i
* @return
* @throws OutOfBoundaryException
*/
@Override
public Object remove(int i) throws OutOfBoundaryException {
if (i<0 || i>= size)
throw new OutOfBoundaryException("错误,指定删除的序号越界");
Object obj=elements [i];
for (int j=i;j<size;j++){
elements[j]=elements[j+1];
}
elements[--size] =null;
return obj;
}

/**
* 删除线性表中第一个与 e 相同的元素
* @param e
* @return
*/
@Override
public boolean remove(Object e) {
int i=indexOf
4000
(e);
if (i<0) return false;
remove(i);
return true;
}

/**
* 替换线性表中序号为 i 的数据元素为 e,返回原数据元素
* @param i
* @param e
* @return
* @throws OutOfBoundaryException
*/
@Override
public Object replace(int i, Object e) throws OutOfBoundaryException {
if(i<0 || i>=size)
throw  new OutOfBoundaryException("错误,指定的序号越界");
Object obj=elements[i];
elements[i]=e;
return obj;
}

/**
* 返回线性表中序号为 i 的数据元素
* @param i
* @return
* @throws OutOfBoundaryException
*/
@Override
public Object get(int i) throws OutOfBoundaryException {
if(i<0 || i>= size)
return new OutOfBoundaryException("错误,指定的序号越界");
return elements[i];
}
}

其中 getSize()、isEmpty()、replace(int i, Object e)、get(int i) 方法的时间复杂度均为Θ(1)。

contains(Object e)、indexOf(Object e) 方法的运行时间为:T(n)= ((n+1)+1)/2 ≈ n/2。

insert(int i, Object e)、remove(int i) 方法的运行时间为:T(n)≈n/2。

insertBefore(Object obj, Object e)、insertAfter(Object obj, Object e)、remove(Object e) 方法的运行时间为: T(n)
≈ n。

初入数据结构,以学习总结为主,如果写的不详细或者有什么其它错误的地方希望各位dalao们指点指点。

参考的书籍:《数据结构-JAVA版》《数据结构与算法》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构 JAVA