6.1、顺序表
顺序表在计算机内存中以数组的形式储存
6.1.1顺序表的实现
顺序表的API
类名 | SequenceList |
---|---|
构造方法 | test01(int capacity) 容量 |
成员方法 | 1、public void clear()线性表置空 2、public boolean isEmpty()判断线性表是否为空 3、public int length()判断线性表的长度 4、public T get(int i)获取指定位置元素的个数 5、public void insert(T t)线性表中添加元素 6、public void insert(int i,T t)线性表的i位置处添加元素 7、public void insert(T t)线性表随便位置添加元素 8、public T remove(int i)线性表元素删除 9、public int indexOf(T t)线性表元素出现的位置 10、public void resize(int newSize)线性表容量变化函数 |
成员变量 | 1、private T[] eles:存储元素的数组 2、private int N:当前线性表的长度 |
package mhd.lzgy.linearTable;
import javax.sound.midi.Sequence;
import java.util.Arrays;
//顺序表代码,使用泛型,可以适用于多种类型
public class test01<T> {
//储存元素的数组
private T[] eles;
// 记录当前顺序表中元素的个数,也就是长度
private int n;
// 构造方法,确定这个对象的容量和数组长度
public test01(int capacity){
//强转成T类型
eles = (T[])new Object[capacity];
n=0;
}
// 将一个线性表作为空的,空的话意思就是长度为0
public void clear(){
n=0;
}
// 判断线性表是否为空,看数组长度这个值
public boolean isEmpty(){
return n==0;
}
// 获取线性表的长度,线性表的长度也就是数组的长度
public int length(){
return n;
}
// 获取指定位置的元素
public T get(int i){
//安全判断,查看索引是否越界
if (i<0 ||i>=n){
throw new RuntimeException("当前元素不存在");
}
return eles[i];
}
// 线性表中插入元素
public void insert(T t){
//首先判断表,如果线性表中的元素个数等于线性表的长度,那么此时线性表已经满了,
if (n==eles.length){
//第一种方法直接抛异常
throw new RuntimeException("当前表满了");
}
eles[n++]=t;
}
// 在线性表的指定位置插入元素
public void insert(int i,T t){
if (i== eles.length){
//第一种方法直接抛异常
throw new RuntimeException("当前表满了");
}
// 安全判断,如果插入位置刚好是线性表的长度,那么此时无法插入
if (i<0 ||i>n){
throw new RuntimeException("插入位置违法");
}
// 将I的位置空出来,I一级I后边的元素依次后移.这个索引是从线性表的后边开始的
for (int index=n;index>i;index--){
eles[index]=eles[index-1];
}
// 将插入的元素放到I位置
eles[i]=t;
//线性表的长度加一
n++;
}
// 删除指定位置元素,并返回这个元素
public T remove(int i){
// 安全判断
if (i<0|| i>n-1){
throw new RuntimeException("当前元素不存在");
}
T result = eles[i];
// 移除元素后需要将I元素后边的元素向前移动
for (int index=i;index<n-1;index++){
eles[index]=eles[index+1];
}
n--;
return result;
}
// 查找指定元素第一次出现的位置
public int indexof(T t){
if (t==null)
throw new RuntimeException("查找的元素不合法");
for (int i=0;i<n;i++){
if (eles[i].equals(t)){
return i;
}
}
return -1;
}
public static void main(String[] args) {
test01<String> s1 = new test01<>(10);
s1.insert("libai");
s1.insert("zhangsan");
s1.insert(1,"dufu");
s1.insert("lisi");s1.insert("wangwu");
String s = s1.get(1);
System.out.println(s);
int n = s1.n;
System.out.println(n);
System.out.println();
}
}
6.1.2顺序表的遍历
1.让SequenceList实现Iterable接口,重写iterator方法;
2.在SequenceList内部提供一个内部类SIterator,实现Iterator接口,重写hasNext方法和next方法;
//查看当前线性表的元素
public void show(){
for (int i=0;i<n;i++){
System.out.println(eles[i]+" ");
}
System.out.println();
}
6.1.3顺序表的容量变化问题
情况
1、添加元素
添加元素时,应该检查当前数组的大小是否能容纳新的元素,如果不能容纳,则需要创建新的容量更大的数组,我 们这里创建一个是原数组两倍容量的新数组存储元素。
2、移除元素
移除元素时,应该检查当前数组的大小是否太大,比如正在用100个容量的数组存储10个元素,这样就会造成内存 空间的浪费,应该创建一个容量更小的数组存储元素。如果我们发现数据元素的数量不足数组容量的1/4,则创建 一个是原数组容量的1/2的新数组存储元素。
//这几个成员方法时在前边代码的基础上进行改进的,可以看方法名判断
// 改变容量
private void resize(int newSize){
// 临时数据记录旧数组
T[] temp = this.eles;
// 创建新数组
T[] eles = (T[]) new Object[newSize];
// 就数组的元素拷贝到新数组
for (int i=0;i<n;i++){
eles[i] = temp[i];
}
}
public int capacity(){
return eles.length;
}
//在改变容量之后,需要在添加元素和删除元素时候进行判断
// 线性表中插入元素
public void insert(T t){
//首先判断表,如果线性表中的元素个数等于线性表的长度,那么此时线性表已经满了,
if (n==eles.length){
resize(eles.length*2);
}
eles[n++]=t;
}
// 在线性表的指定位置插入元素
public void insert(int i,T t){
// 安全判断,如果插入位置刚好是线性表的长度,那么此时无法插入
if (i<0 ||i>n){
throw new RuntimeException("插入位置微法");
}
if (n== eles.length){
resize(eles.length*2);
}
// j将I的位置空出来,I一级I后边的元素依次后移.这个索引是从线性表的后边开始的
for (int index=n;index>i;index--){
eles[index]=eles[index-1];
}
// 将插入的元素放到I位置
eles[i]=t;
n++;
}
// 删除指定位置元素,并返回这个元素
public T remove(int i){
// 安全判断
if (i<0|| i>n-1){
throw new RuntimeException("当前元素不存在");
}
T result = eles[i];
// 移除元素后需要将元素向前移动
for (int index=i;index<n-1;index++){
eles[index]=eles[index+1];
}
n--;
if (n>0 && n<eles.length/4){
resize(eles.length/2);
}
return result;
}