一、顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构。线性表采用顺序存储的方式存储就称之为顺序表。顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中。
二、顺序表特点:将表中元素一个接一个的存入一组连续的存储单元中,这种存储结构是顺序结构
java语言中的顺序存储结构
//类名后面加标名使用泛型
public class SequenceList<T> implements Iterable{
//存储元素的泛型数组
private T[] eles;
//记录当前顺序表中的元素个数
private int N;
}
(1)初始化数组
public SequenceList(int capacity){
//初始化数组
this.eles =(T []) new Object[capacity];
//初始化长度
this.N = 0;
}
(2)将一个线性表置为空表
public void clear(){
this.N=0;
}
只需要让元素个数等于0即可
(3)判断当先线性表是否为空表
public boolean isEmpty(){
return N==0;
}
若元素等于0即为空表
(4)火线线性表的长度
public int length(){
return N;
}
N的个数即为线性表的长度
(5)向线性表插入元素
public void insert(T t){
eles[N++] = t;
}
直接向把插入元素赋给N的下一个值,不过这种可能造成线性表容量不足,所以创建一个方法,使线性表可以在容量不足时,自动扩容
public void resize(int newSize){
//定义一个临时数组,指向元素组
T [] temp = eles;
//创建新数组
eles=(T[]) new Object[newSize];
//把原数组的数据拷贝到新数组即可
for (int i=0;i<N;i++){
eles[i]=temp[i];
}
}
于是,新的插入方法为
public void insert(T t){
if (N==eles.length){
resize(2* eles.length);
}
eles[N++] = t;
}
(6)向指定位置i处插入元素t
public void insert(int i,T t){
if (N==eles.length){
resize(2* eles.length);
}
//先把i索引处的元素及其后面的元素依次向后移动一位
for (int index=N;index>i;index--){
eles[index]=eles[index-1];
}
//再把t元素放到i索引处即可
eles[i]=t;
N++;
}
首先把i索引处的元素机器后面的元素依次向后移动一位,腾出t出入的位置,再把t元素放到i索引处即可
(7)删除指定位置i处的元素,并返回该元素
public T remove(int i){
//记录索引i处的值
T current = eles[i];
//索引i后面元素依次向前移动一位即可
for (int index=i;index<N-1;index++){
eles[index]=eles[index+1];
}
//元素个数减一
N--;
if (N<eles.length/4){
resize(eles.length/2);
}
return current;
}
记录i处的值,在返回时给出i的值,然后把i后面元素依次向前面移动一位即可,元素个数减一
(8)获取指定i处的值
public T get(int i ){
return eles[i];
}
(9)查询i元素第一次出现的位置
public int indexof(T t){
for (int i=0;i<N;i++){
if (eles[i].equals(t)){
return i;
}
}
return -1;
}
上面的已经可以使用了,测试代码如下
public class SequenceListTest {
public static void main(String[] args) {
//创建顺序表对象
SequenceList<String> s1 = new SequenceList<>(10);
//测试插入
s1.insert("姚明");
s1.insert("胡一菲");
s1.insert("刘亦菲");
s1.insert(1,"linlin");
System.out.println("===========");
//测试获取
String getResult = s1.get(1);
System.out.println("获取索引1处的结果为"+getResult);
//测试删除
String removeResult= s1.remove(0);
System.out.println("删除的元素是"+removeResult);
//测试获取
s1.clear();
System.out.println("清空后的线性表中的元素个数为"+s1.length());
}
}
基本的线性表已经创建好了,已经可以用于使用了,但是为了更好的去遍历它,我们需要继承一个Iterab接口implements Iterable
,并实现iterator方式,在实现这个方法时,不可以直接实现,因此我们,可以创建一个内部类SIteratour,继承Iterator,只有才有我们需要的两个方法,在return 里面返回这个类的对象即可
<1> 在(1)继承Iterable接口
public class SequenceList<T> implements Iterable
<2> 重写iterator方法
public Iterator iterator() {
return new SIterator();
}
这个返回的时 SIterator对象,在下面会创一个内部类来实现
<3>创建内部类SIteratour,并继承Iterator
刚创建好时这样的
private class SIteratour implements Iterator{
@Override
public boolean hasNext() {
return false;
}
@Override
public Object next() {
return null;
}
}
我们需要创建一个cusor指针,从头开始指向每个元素,在构造方法中,初始化它为0,从第一个开始
private class SIterator implements Iterator{
private int cusor;
public SIterator(){
this.cusor=0;
}
@Override
public boolean hasNext() {
return cusor<N;
}
@Override
public Object next() {
return eles[cusor++];
}
}
完整代码如下
package linear;
import java.util.Iterator;
//特点查询较快,增删较慢
public class SequenceList<T> implements Iterable {
//存储元素的数组
private T[] eles;
//记录当前顺序表中的元素个数
private int N;
//构造方法
public SequenceList(int capacity) {
//初始化数组
this.eles = (T[]) new Object[capacity];
//初始化长度
this.N = 0;
}
//将一个线性表置为空表
public void clear() {
this.N = 0;
}
//判断当前线性表是否为空表
public boolean isEmpty() {
return N == 0;
}
//获取线性表的长度
public int length() {
return N;
}
//获取指定位置的元素
public T get(int i) {
return eles[i];
}
//向线性表中添加元素t
public void insert(T t) {
if (N == eles.length) {
resize(2 * eles.length);
}
eles[N++] = t;
}
//在i元素处插入元素t
public void insert(int i, T t) {
if (N == eles.length) {
resize(2 * eles.length);
}
//先把i索引处的元素及其后面的元素依次向后移动一位
for (int index = N; index > i; index--) {
eles[index] = eles[index - 1];
}
//再把t元素放到i索引处即可
eles[i] = t;
N++;
}
//删除指定位置i处的元素,并返回该元素
public T remove(int i) {
//记录索引i处的值
T current = eles[i];
//索引i后面元素依次向前移动一位即可
for (int index = i; index < N - 1; index++) {
eles[index] = eles[index + 1];
}
//元素个数减一
N--;
if (N < eles.length / 4) {
resize(eles.length / 2);
}
return current;
}
//查找t元素第一次出现的位置
public int indexof(T t) {
for (int i = 0; i < N; i++) {
if (eles[i].equals(t)) {
return i;
}
}
return -1;
}
//根据参数newSize,重置eles的大小, 扩容
public void resize(int newSize) {
//定义一个临时数组,指向元素组
T[] temp = eles;
//创建新数组
eles = (T[]) new Object[newSize];
//把原数组的数据拷贝到新数组即可
for (int i = 0; i < N; i++) {
eles[i] = temp[i];
}
}
@Override
public Iterator iterator() {
return new SIterator();
}
private class SIterator implements Iterator {
private int cusor;
public SIterator() {
this.cusor = 0;
}
@Override
public boolean hasNext() {
return cusor < N;
}
@Override
public Object next() {
return eles[cusor++];
}
}
}
package test;
import linear.SequenceList;
public class SequenceListTest {
public static void main(String[] args) {
//创建顺序表对象
SequenceList<String> s1 = new SequenceList<>(10);
//测试插入
s1.insert("姚明");
s1.insert("胡一菲");
s1.insert("刘亦菲");
s1.insert(1,"linlin");
for (Object o : s1) {
System.out.println(o);
}
System.out.println("===========");
//测试获取
String getResult = s1.get(1);
System.out.println("获取索引1处的结果为"+getResult);
//测试删除
String removeResult= s1.remove(0);
System.out.println("删除的元素是"+removeResult);
//测试获取
s1.clear();
System.out.println("清空后的线性表中的元素个数为"+s1.length());
}
}