ADT 介绍
1.数据结构
- 使用泛型数组,扩大顺序表的存储数据类型
- 动态分配空间,通过动态扩容数组,使得不用为顺序表的空间问题发愁
2.操作集合
- getSize() :获得顺序表中的元素个数;return类型为int
- getCapacity() :获得顺序表的容量;return类型为int
- isEmpty() :判断顺序表是否为空;若空,return true,否则,return false
- add(int idx, AnyType element) :添加元素;添加元素式,如果顺序表已满,则自动扩容为原来的2倍
- addFirst(AnyType element) :在表头插入元素
- addLast(AnyType element) :在表尾插入元素
- remove(int idx) :移除表中元素;调用isEmpty()判断表是否为空,如果size为capacity一半,则会进行自动缩容为1/2
- removeFirst() :移除表头元素
- removeLast() :移除表尾元素,移除表尾元素和其他元素有所不同,具体在remove() 方法中实现
- contains(AnyType element) :表中是否包含某个元素
- find(AnyType element) :查找表中元素位置
- get(int idx) :获得表中元素
- delete(AnyType element) :删除指定元素
- ensureCapacity(int newCapacity) :动态容量管理,扩容和缩容的基础实现
ensureCapacity实现原理
思路:将指向顺序表的引用指向新分配大小的数组,然后将顺序表中的元素复制到新的数组中,完成容量调整。
扩容和缩容发生的时机:扩容发生在插入元素之前;缩容发生在移除元素之后。
Tips:旧的数组,会被垃圾回收机制自动回收
实现代码
public class Array<AnyType> {
private static final int DEFAULTCAPACITY = 10;
private int size;
private AnyType[] data;
/*
* 无参构造方法初始化顺序表
*/
public Array() {
size = 0;
ensureCapacity(DEFAULTCAPACITY);
}
/*
* 获得顺序表中的元素个数
*/
public int getSize() {
return size;
}
/*
* 获得顺序表的容量
*/
public int getCapacity() {
return data.length;
}
/*
* 判断顺序表是否为空
*/
public boolean isEmpty() {
return size == 0;
}
/*
* 在表头插入元素
*/
public void addFirst(AnyType element) {
add(0,element);
}
/*
* 在表尾插入元素
*/
public void addLast(AnyType element) {
add(size,element);
}
/*
* 添加元素
*/
public void add(int idx, AnyType element) {
if(size == getCapacity()) {
ensureCapacity(getCapacity() * 2);
}
for(int i = size; i > idx; i--) {
data[i] = data[i-1];
}
data[idx] = element;
size++;
}
/*
* 移除表头元素
*/
public AnyType removeFirst() {
return remove(0);
}
/*
* 移除表尾元素
*/
public AnyType removeLast() {
return remove(size - 1);
}
/*
* 移除表中元素
*/
public AnyType remove(int idx) {
if(isEmpty() || idx >= size)
throw new IllegalArgumentException("index 不合法");
AnyType ret = data[idx];
if(idx != size - 1) {
for(int i = idx; i < size; i++) {
data[i] = data[i+1];
}
}
size--;
if(size == getCapacity()/4 && getCapacity()/2 != 0) {
ensureCapacity(getCapacity()/2);
}
return ret;
}
/*
* 表中是否包含某个元素
*/
public boolean contains(AnyType element) {
for(int i = 0; i < size; i++) {
if(data[i] == element)
return true;
}
return false;
}
/*
* 查找表中元素位置
*/
public int find(AnyType element) {
for(int i = 0; i < size; i++) {
if(data[i] == element)
return i;
}
return -1;
}
/*
* 查询表中元素
*/
public AnyType get(int idx) {
return data[idx];
}
/*
* 删除指定元素
*/
public void delete(AnyType element) {
int idx = find(element);
if(idx == -1)
return;
remove(idx);
}
@Override
public String toString() {
String s = new String();
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("size:"+size+'\n');
stringBuilder.append("capacity:"+getCapacity()+'\n');
stringBuilder.append('[');
for(int i = 0; i < size; i++) {
stringBuilder.append(data[i]);
if(i != size - 1)
stringBuilder.append(',');
}
stringBuilder.append(']');
s = stringBuilder.toString();
return s;
}
/*
* 动态容量管理
*/
private void ensureCapacity(int newCapacity) {
if(newCapacity < size)
return;
AnyType[] old = data;
data = (AnyType[])new Object[newCapacity];
for(int i = 0; i < size; i++) {
data[i] = old[i];
}
}
}