线性表
线性表 是具有n 个 相同类型元素 的有限 序列(n>=0)
线性表- a1是首节点, an尾节点
- a1是a2 的前驱, a2 是a1 的后继
常见 线性表
- 数组
- 链表
- 栈
- 队列
- 哈希表(散列表)
数组(Array)
数组是一种顺序存储的线性表, 所有元素的内存地址时连续的
存储结构缺点: 在很多的语言当中, 无法动态修改容量
实际开发中, 我们希望数组的容量可以动态改变
动态数组
接口设计
int size(); // 元素的数量
boolean isEmpty(); // 是否为空
boolean contains (E element); // 是否包含某个元素
void add (E element); // 添加元素到最后面
E get (int index); // 返回index位置对应的元素
E set (int index, E element); // 设置index位置的元素
void add (int index, E element); // 往index位置添加元素
E remove (int index); // 删除index位置对应的元素
int indexOf (E element); // 查看元素的位置
void clear (); // 清除所有元素
删除元素
删除元素最后一个元素不用处理, 删除之后size--, 调用get 方法访问不到最后一个元素
如果是泛型数据, 注意将元素置为null
元素以此从index+1 处向前移动
/**
* 删除index 的元素
* @param index
* @return
*/
public int remove(int index) {
rangeCheck(index);
int old = elements[index];
for (int i = index; i < size-1; i++) {
elements[i] = elements[i + 1];
}
size--;
return old;
}
添加元素
添加元素 /**
* index 位置插入一个元素
* @param index
* @param element
* @return
*/
public void add(int index, int element) {
rangeCheckForAdd(index);
// 插入数据在某本位置, 需要将该位置后续元素向后移动一位
for (int i = size-1; i >= index; i--) {
elements[i + 1] = elements[i];
}
elements[index] = element;
size++;
}
扩容
扩容注意其中的右移运算, 效率更高
private void ensureCapacity(int capacity) {
int oldCapacity = elements.length;
if (oldCapacity >= capacity) {
return;
}
int newCapacity = oldCapacity + (oldCapacity >> 1);
int[] newElements = new int[newCapacity];
for (int i = 0; i < size; i++) {
newElements[i] = elements[i];
}
elements = newElements;
System.out.println("size="+oldCapacity+", 扩容到了"+newCapacity);
}
泛型
使用泛型可以让动态数组更加通用, 可以存放任何数据类型
java 的泛型只能使用对象类型, 存放int 类型, 改为包装类Integer
java 中所有的类, 都最终继承java.lang.Object 类
public class ArrayList<E> {
public ArrayList(int capacity) {
capacity = (capacity < DEFAULT_CAPACITY) ? DEFAULT_CAPACITY : capacity;
elements = (E[]) new Object[capacity];
}
}
java 实现
@SuppressWarnings("unchecked")
public class ArrayList<E> {
private int size;
private E[] elements;
private static final int DEFAULT_CAPACITY = 10;
private static final int ELEMENT_NOT_FOUND = -1;
public ArrayList(int capacity) {
capacity = (capacity < DEFAULT_CAPACITY) ? DEFAULT_CAPACITY : capacity;
elements = (E[]) new Object[capacity];
}
public ArrayList() {
this(DEFAULT_CAPACITY);
}
/**
* 清除元素
*/
public void clear() {
for (int i = 0; i < size; i++) {
elements[i] = null;
}
size = 0;
}
/**
* 元素的数据
* @return
*/
public int size() {
return size;
}
/**
* 是否为空
* @return
*/
public boolean isEmpty() {
return size == 0;
}
/**
* 是否包含某个元素
* @return n
*/
public boolean contains(E element) {
return indexOf(element) != ELEMENT_NOT_FOUND;
}
/**
* 添加元素到尾部
* @param n
*/
public void add(E element) {
add(size, element);
}
/**
* 获取index 位置的元素
* @param index
* @return
*/
public E get(int index) {
rangeCheck(index);
return elements[index];
}
/**
* index位置插入一个元素
* @param index
* @param element
*/
public E set(int index, E element) {
rangeCheck(index);
E old = elements[index];
elements[index] = element;
return old;
}
/**
* index 位置插入一个元素
* @param index
* @param element
* @return
*/
public void add(int index, E element) {
// if (element == null) { return; }
rangeCheckForAdd(index);
ensureCapacity(size + 1);
// 插入数据在某本位置, 需要将该位置后续元素向后移动一位
for (int i = size; i > index; i--) {
elements[i] = elements[i - 1];
}
elements[index] = element;
size++;
}
/**
* 删除index 的元素
* @param index
* @return
*/
public E remove(int index) {
rangeCheck(index);
E old = elements[index];
for (int i = index; i < size - 1; i++) {
elements[i] = elements[i + 1];
}
elements[--size] = null;
return old;
}
/**
* 删除摸个元素
* @param element
*/
public void remove(E element) {
remove(indexOf(element));
}
/**
* 查看元素的索引
* @param element
* @return
*/
public int indexOf(E element) {
// 如果使用 == , 说明两者的内存地址是一样的
// 需要重写equals
if (element == null) {
for (int i = 0; i < size; i++) {
if (elements[i] == null) return i;
}
} else {
for (int i = 0; i < size; i++) {
if (element.equals(elements[i])) return i;
}
}
return ELEMENT_NOT_FOUND;
}
private void ensureCapacity(int capacity) {
int oldCapacity = elements.length;
if (oldCapacity >= capacity) {
return;
}
int newCapacity = oldCapacity + (oldCapacity >> 1);
E[] newElements = (E[]) new Object[newCapacity];
for (int i = 0; i < size; i++) {
newElements[i] = elements[i];
}
elements = newElements;
System.out.println("size="+oldCapacity+", 扩容到了"+newCapacity);
}
/****************封装好的功能函数*******************************/
// 下标越界抛出的异常
private void outOfBounds(int index) {
throw new IndexOutOfBoundsException("Index:" + index + ", Size:" + size);
}
// 检查下标越界(不可访问或删除size位置)
private void rangeCheck(int index) {
if (index < 0 || index >= size) {
outOfBounds(index);
}
}
// 检查add()的下标越界(可以在size位置添加)
private void rangeCheckForAdd(int index) {
if (index < 0 || index > size) {
outOfBounds(index);
}
}
/****************封装好的功能函数*******************************/
@Override
public String toString() {
// 打印形式为: size=5, [99, 88, 77, 66, 55]
StringBuilder string = new StringBuilder();
string.append("size=").append(size).append(", [");
for (int i = 0; i < size; i++) {
if (0 != i) string.append(", ");
string.append(elements[i]);
}
string.append("]");
return string.toString();
}
}
网友评论