虽然在大二学过一遍数据结构,当时拿c写过一遍。但是现在除了线性表之外好多的都忘得差不多了,利用假期再重温一下,特别是树的内容要好好再学一遍。一是复习一遍加深一下印象,二是借此机会也加强一下敲代码功底。
这次写的是线性表——顺序表的实现。
它的存储结构是一个数组:
特点: 再内存中分配连续空间,只存储数据,不需要存储地址信息,位置就隐含着地址。
优点: 节省储存空间,查找效率高。
本次主要实现了增删改查等等,是对ArrayList的模拟。
主要结构:
List是定义的顺序表的接口,ArrayList是List的实现类。
ArrayList中的变量:
private Object[] elementDate;
private int size;//元素个数
要到的问题:
在写add()方法的时候总是出现索引不合法的警告,我自己想明明数组不够会扩容,为什莫会出现数组容量不够?然后测试一下,此行代码有问题:
elementDate = Arrays.copyOf(elementDate, (elementDate.length + elementDate.length>>1));
然后恍然大悟,>>比+的优先级低加括号即可。
elementDate = Arrays.copyOf(elementDate, (elementDate.length + (elementDate.length>>1)));
附上代码:
package cn.liu.shun_xu_biao;
/**
* 线性表a接口
* 和存储结构无关
* @author Administrator
*
*/
public interface List {
//返回线性表大小,数据元素的个数
public int size();
//返回线性表中序列为i的数据元素
public Object get(int i);
//如果线性表为空返回true,否则返回false.
public boolean isEmpty();
//判断线性表是否包含数据元素e
public boolean contains(Object e);
//返回数据元素e在线性表中的序列
public int indexOf(Object e);
//将数据元素e插入到线性表中i号位置
public void add(int i,Object e);
//将数据元素e插入到线性表末尾
public void add(Object e);
//将数据元素e插入到元素obj之前(找到的第一个)
public void addBefore(Object obj,Object e);
//将数据元素e插入到元素obj之后(找到的第一个)
public void addAfter(Object obj,Object e);
//删除线性表中序号为i的元素,并返回
public Object remove(int i);
//删除线性表中第一个与e相同的元素
public void remove(Object e);
//替换线性表中序号为i的数据元素为e,返回原数据元素
public Object replace(int i,Object e);
}
package cn.liu.shun_xu_biao;
import java.util.Arrays;
/**
* 实现接口List的实现类ArrayList
* 拿数组实现顺序表
* @author Administrator
*
*/
public class ArrayList implements List{
private Object[] elementDate;
private int size;//元素个数
public ArrayList() {
this.elementDate = new Object[4];
this.size = 0;
}
public ArrayList(int initialCapacity) {
this.elementDate = new Object[initialCapacity] ;
this.size = 0;//没有装数据为零
}
@Override
public int size() {
return size;
}
@Override
public Object get(int i) {
detection2(i);
return elementDate[i];
}
@Override
public boolean isEmpty() {
return size == 0;
}
@Override
public boolean contains(Object e) {
return indexOfRange(e,0,size)>=0;
}
@Override
public int indexOf(Object e) {
return indexOfRange(e,0,size);
}
@Override
public void add(int i, Object e) {
//检测索引是否合格
detection1(i);
//扩容
if(size==elementDate.length)
{
//elementDate = Arrays.copyOf(elementDate, (elementDate.length + elementDate.length>>1));//>>比+的优先级低
elementDate = Arrays.copyOf(elementDate, (elementDate.length + (elementDate.length>>1)));
}
//存入新的数据元素
for(int j = size; j > i; j--)
{
elementDate[j] = elementDate[j-1];
}
elementDate[i] = e;
size++;
}
@Override
public void add(Object e) {
this.add(size,e);
}
@Override
public void addBefore(Object obj, Object e) {
if(contains(obj)) {
add(indexOf(obj),e);
}else {
System.out.println("此数组没有包含"+obj);
}
size++;
}
@Override
public void addAfter(Object obj, Object e) {
if(contains(obj)) {
add(indexOf(obj)+1,e);
}else {
System.out.println("此数组没有包含"+obj);
}
size++;
}
@Override
public Object remove(int i) {
Object m = get(i);//对i进行了检测,并且保存了i所在的元素
for(int j = i; j < size-1; j++)
{
elementDate[j] = elementDate[j+1];
}
size--;
return m;
}
@Override
public void remove(Object e) {
remove(indexOf(e));
}
@Override
public Object replace(int i, Object e) {
detection2(i);
Object m = get(i);
elementDate[i] = e;
return m;
}
//检测索引是否合法
public void detection1(int i) {
if(i<0 || i>size) {
throw new RuntimeException("数组索引越界异常:"+i);
}
}
public void detection2(int i) {
if(i<0 || i>=size) {
throw new RuntimeException("数组索引越界异常:"+i);
}
}
//查找数组中是不是有此数据元素,并返回位置
public int indexOfRange(Object o, int start, int end) {
//新建一个数组,有则返回在数组中的位置,没有则返回-1
Object[] ee = elementDate;
if(o == null) {
for(int i =start ; i<end;i++) {
if(ee[i]==null) {
return i;
}
}
}else{
for(int i =start ; i<end;i++) {
if(o.equals(ee[i])) {
return i;
}
}
}
return -1;
}
//改写toString方法
@Override
public String toString() {
StringBuilder sb = new StringBuilder("[");
for(int i =0 ;i < size; i++) {
sb.append(elementDate[i]+",");
}
sb.setCharAt(sb.length()-1, ']');
return sb.toString();
}
}