数组动态
Java内置数组的特点
- 数组长度一旦确定则不可更改
- 数组只能存储同一类型的数据
- 数组中每个存储空间大小一致且地址连续
- 数组提供角标的方式访问元素
线性表的顺序存储结构
线性表的定义:零个或多个数据元素的有限序列。
第一个元素只有后继,没有前驱。
最后一个元素只有前驱,没有后继。
因此线性表的个数n(n >= 0)定义为线性表的长度,当n = 0 时,则称为空表。
线性表接口的定义
其代码表示为:
package 数据结构与算法;
/**
* <E>是这个范型
* List是线性表的最终父接口
*/
public interface List<E>{
/**
* 获取线性表中元素的个数(线性的个数)
* @return 线性表中有效元素的个数
*/
public int getSize();
/**
* 判断线性表是否为空
* @return 受否为空的布尔类型值
*/
public boolean isEmpty();
/**
* 在线性表指定的index处添加元素e
* @param index 指定的角标 0 <= index <= size
* @param e 要插入的元素
*/
public void add(int index ,E e);
/**
* 在线性表的表头位置插入一个元素
* @param e 要插入的位置在角标0处
*/
public void addFirst(E e);
/**
* 在线性表的表尾处插入一个元素
* @param e 指定在角标size处
*/
public void addLast(E e);
/**
* 在线性表中获取指定index角标处的元素
* @param index 指定的角标 0 <= index < size
*/
public E get (int index);
/**
* 获取线性表中表头的元素
* @return 表头的元素 index = 0
*/
public E getFirst();
/**
* 获取线性表中表尾的元素
* @return 表尾元素 index = size - 1
*/
public E getLast();
/**
* 修改线性表中指定index处的元素为新元素e
* @param index 指定的角标
* @param e 新元素
*/
public void set(int index ,E e);
/**
* 判断线性表中是否包含指定元素e
* @param e 要判断是否存在的元素
* @return 元素的存在性
*/
public boolean contains(E e);
/**
* 在线性表中获取指定元素e的角标 默认从前往后找
* @param e 要查询的数据
* @return 数据在线性表中的角标
*/
public int find(E e);
/**
* 在线性表中删除指定角标处的元素并返回
* @param index 指定的角标 0 <= index < size
* @return 删除掉的老元素
*/
public E remove (int index);
/**
* 删除线性表中的表头元素
* @return 表头元素
*/
public E removeFirst();
/**
* 删除线性表中的表尾元素
* @return 表尾元素
*/
public E removeLast();
/**
* 在线性表中删除指定元素
* @param e 要删除的元素
*/
public void removeElement(E e);
/**
* 清空线性表
*/
public void clear();
线性表顺序存储结构ArrayList的定义
- 指的是用一段地址连续的存储单元依次存储线性表的数据元素
其代码表示为:
package 数据结构与算法;
/**
* 用顺序存储结构实现的List-顺序线性表-顺序表
*/
public class ArrayList<E> implements List<E>{
private static final int DEFUALT_SIZE = 0;
private static int DEFAULT_SIZE = 10;
private E[] data;//存储数据元素的数据
private int size;//线性表的有效元素的个数
//data.length 表示线性表的最大容量 Capacity
/**
* 创建一个容量默认为10的一个线性表
*/
public ArrayList() {
this(DEFAULT_SIZE);//是上面的调用下面的,上面的只是下面的参数之一而已
}
/**
* 创建一个容量为capacity的线性表
*/
public ArrayList(int capcity) {
int capacity;
this.data=(E[]) new Object[capcity];
this.size=0;
}
/**
* 将一个数组封装成线性表
* @param arr
*/
public ArrayList(E[] arr) {
//TODO
}
@Override
public int getSize() {
// TODO Auto-generated method stub
return size;
}
@Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return size==0;
}
@Override
public void add(int index, E e) {
if(index < 0||index > size) {
throw new ArrayIndexOutOfBoundsException("add角标越界");
}
//判断是否已满
if(size==data.length) {
resize(2*data.length);
}
for(int i = size - 1;i >= index;i--) {
data[i + 1] = data[i];
}
data[index]=e;
size++;
}
/**
* 改变data的长度(扩容,缩容)
* @param newLen (新数组的长度)
*/
private void resize(int newLen) {
E[] newData=(E[]) new Object[newLen];
for(int i = 0;i <size;i++) {
newData[i]=data[i];
}
data=newData;
}
@Override
public void addFirst(E e) {
add(0,e);
}
@Override
public void addLast(E e) {
add(size,e);//size刚好就是最后一个元素所要进的位置
}
@Override
public E get(int index) {
if(index < 0||index>size-1) {
throw new ArrayIndexOutOfBoundsException("get函数角标越界");
}
return data[index];
}
@Override
public E getFirst() {
return get(0);
}
@Override
public E getLast() {
return get(size - 1);
}
@Override
public void set(int index, E e) {
if(index<0||index>size-1) {
throw new ArrayIndexOutOfBoundsException("set角标越界");
}
data[index]=e;
}
@Override
public boolean contains(E e) {
if(isEmpty()) {
return false;
}
for(int i = 0;i < size;i++) {
if(data[i]==e) {
return true;
}
}
return false;
}
@Override
public int find(E e) {//根据元素找角标
if(isEmpty()) {
return -1;
}
for(int i = 0;i <size;i++) {
if(data[i]==e) {
return i;
}
}
return -1;
}
@Override
public E remove(int index) {
if(index < 0||index > size - 1) {
throw new ArrayIndexOutOfBoundsException("删除(remove)函数角标越界");
}
E e = get(index);
for(int i = index + 1 ;i <= size - 1;i++) {
data[i-1]=data[i];
}
size--;
E[] newData;
//判断是否缩容
//1.最短不能缩过默认容量
//有效元素的个数小于等于容量的1/4处
if(data.length>DEFUALT_SIZE&&size<=data.length/4) {
resize(data.length/2);
}
return e;
}
@Override
public E removeFirst() {
return remove(0) ;
}
@Override
public E removeLast() {
return remove(size-1);
}
@Override
public void removeElement(E e) {
int index = find(e);
if (index == -1) {
throw new IllegalArgumentException("删除元素不存在");
}
remove(index);
}
@Override
public void clear() {
size= 0;
}
//toString返回对象的字符串形式
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("ArrayList: size = "+ size+",capacity="+data.length+"\n");
if(isEmpty()) {
sb.append("[]");
}else {
sb.append('[');
for(int i = 0;i <size;i++) {
sb.append(data[i]);
if(i == size - 1) {
sb.append(']');
}else {
sb.append(',');
}
}
}
return sb.toString();
}
public int getCapcity() {
return data.length;
}
public void swap(int i ,int j) {
//i ,j 判断
E temp = data[i];
data[i]=data[j];
data[j]=temp;
}
@Override
public boolean equals(Object obj) {
if(obj ==null) {
return false;
}
if(obj == this) {
return true;
}
if(obj instanceof ArrayList) {
ArrayList l = (ArrayList)obj;
if(getSize()==l.getSize()) {
for(int i = 0;i < getSize();i++) {
if(get(i)!=l.get(i)) {
return false;
}
}
return true;
}
}
return false;
}
}
他的主函数为:
package 数据结构与算法;
public class Main {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
System.out.println(list);
for(int i = 1;i <= 5;i++) {
list.addFirst(i);
}
System.out.println(list);
for(int i = 6;i <= 10;i++) {
list.addLast(i);
}
System.out.println(list);
list.add(5, 0);
System.out.println(list);
for(int i = 11;i <= 30;i++) {
list.addLast(i);
}
System.out.println(list);
for(int i = 1;i <= 21;i++) {
System.out.println(list.removeFirst());
}
System.out.println(list);
list.removeElement(23);
System.out.println(list);
for(int i = 1;i<= 4;i++) {
list.removeFirst();
}
System.out.println(list);
//list.swap(-1, 10);
ArrayList<Integer>list2= new ArrayList<Integer>();
list2.addFirst(20);
System.out.println(list2);
System.out.println(list.equals(list2));//equals 比的是内容不是地址
}
}
栈的定义
栈是限定仅在表尾进行插入和删除操作的线性表。
- 我们把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom)
- 不含任何元素的栈称为空栈
- 栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构
- 栈本身是一个线性表。其数据元素具有线性关系,只不过它是一种特殊的线性表而已
- 定义中说的是在线性表的表尾进行插入和删除操作,这里表尾是指栈顶,而不是栈底
- 栈的插入操作,叫做进栈,也称压栈、入栈
- 栈的删除操作,叫做出栈,也称弹栈。