线性表(数组实现)
功能列表
标准功能
int size();
boolean isEmpty();
根据节点值:增删改查
boolean add(T value);
boolean remove(T value);
boolean set(T value);
boolean contains(T value)
根据下标:增删改查
boolean add(int index,T value);
boolean remove(int index,T value);
T set(int index,T newValue);
T get(int index)
实现代码:
- 重点:add()方法中的数组扩容
package linearlist;
import java.util.Objects;
/**
* 使用数组实现一个线性表
*
* 使用者: 数据容器
* 数据结构: 线性表
* 底层结构: 数组
* 功能:按照节点值增删改查;按照节点下标增删改查
*/
public class ArrayLinerList<T> {
// 线性表初始默认大小
private static final int INIT_CAPACITY = 10;
// 线性表长度最大值
private static final int MAX_CAPACITY = Integer.MAX_VALUE - 8;
// 底层数组
private Object[] objs;
// 线性表大小
private int size;
public ArrayLinerList() {
objs = new Objects[INIT_CAPACITY];
}
// 数组可以创建为0长度
// int [] a= new int[0];
// System.out.println(a.length);
// System.out.println(a[0]);
public ArrayLinerList(int initCpacity) {
if (initCpacity < 1 || initCpacity > MAX_CAPACITY){
throw new IllegalArgumentException("parame is Illegal");
}
objs = new Objects[initCpacity];
}
// 根据构造方法 线性表可能为空,但底层数组一定不空,长度至少是1
/**
* 添加节点
* @param value 添加节点的节点值
* @return 添加是否成功
*/
public boolean add(T value){
// 如果数组已满 则需要扩容
if(size == objs.length){
int newLen = genLen();
grow(newLen);
}
objs[size] = value;
size++;
return true;
}
/**
* 删除节点
* @param value 要删除的节点值
* @return 删除结果
*/
public boolean remove(T value){
if(isEmpty()){
throw new RuntimeException("list is empty");
}
for (int i = 0; i < size; i++) {
// 注意应该使用equals方法
if(Objects.equals(objs[i],value)){
// 可以不用进行以下判断
// 因为如果找到size一定会减1
// if(i == size - 1){
// size--;
// return true;
// }
// 将i之后的节点前移一位
for (int j = i; j < size - 1; j++) {
objs[j] = objs[j+1];
}
size--;
return true;
}
}
// 没找到
return false;
}
/**
* 判断是否含有指定节点值
* @param value 需要查找的节点值
* @return 查找结果
*/
public boolean contains(T value){
if(isEmpty()){
throw new RuntimeException("list is empty");
}
for (int i = 0; i < size; i++) {
if(Objects.equals(objs[i],value)){
return true;
}
}
return false;
}
/**
* 修改目标节点值
* @param oldValue:需要修改的节点值
* @param newValue:修改后的新值
* @return:修改是否成功
*/
public boolean set(T oldValue,T newValue){
if(isEmpty()){
throw new RuntimeException("list is empty");
}
for (int i = 0; i < size; i++) {
if(Objects.equals(objs[i],oldValue)){
objs[i] = newValue;
return true;
}
}
return false;
}
/**
* 根据下标添加元素值
* @param index 目的下标
* @param value 添加的节点值
* @return 添加结果
*/
public boolean add(int index,T value){
// 添加范围0~size
if(index < 0 || index > size){
throw new IllegalArgumentException("param is illegal");
}
// 如果数组满
if(size == objs.length){
int newLen = genLen();
grow(newLen);
}
if(index == size){
objs[size] = value;
}
// 倒着后移 防止元素覆盖
for (int j = size-1; j >= index ; j--) {
objs[j+1] = objs[j];
}
objs[index] = value;
size++;
return true;
}
/**
* 根据下标删除元素
* @param index 目标下标
* @return 删除的节点值
*/
public T remove(int index){
if(isEmpty()){
throw new RuntimeException("list is empty");
}
if(index < 0 || index > size - 1){
throw new IllegalArgumentException("param is illegal");
}
T res = (T) objs[index];
// if(index == size -1){
// size--;
// return res;
// }
// index 之后元素前移
for (int i = index; i < size-1; i++) {
objs[i] = objs[i+1];
}
size--;
return res;
}
/**
* 根据下标获取节点值
* @param index 目标下标
* @return 目标下标节点值
*/
public T get(int index){
if(isEmpty()){
throw new RuntimeException("list is empty");
}
if(index < 0 || index > size - 1){
throw new IllegalArgumentException("param is illegal");
}
return ((T) objs[index]);
}
/**
* 根据下标修改节点值
* @param index 目标下标
* @return 修改前的节点值
*/
public T set(int index,T newValue){
if(isEmpty()){
throw new RuntimeException("list is empty");
}
if(index < 0 || index > size - 1){
throw new IllegalArgumentException("param is illegal");
}
T res = (T) objs[index];
objs[index] = newValue;
return res;
}
private int genLen() {
int oldLen = objs.length;
int newLen = oldLen << 2;
if(newLen < 0 || newLen > MAX_CAPACITY){
newLen = MAX_CAPACITY;
}
if(newLen == oldLen){
throw new RuntimeException("stack is full");
}
return newLen;
}
private void grow(int newLen) {
Object[] newObjs = new Object[newLen];
for (int i = 0; i < objs.length; i++) {
newObjs[i] = objs[i];
}
objs = newObjs;
}
private boolean isEmpty() {
return size == 0;
}
}