[Java] 数据结构---顺序表
1.什么是线性表?
- 线性表(linear list) 是 n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列…
- 线性表在逻辑上是线性结构 ,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。
2.什么是顺序表?
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
3.java中是如何实现顺序表?
首先我们先来对顺序表的基本原理加以介绍:
3.1 顺序表接口的实现
public class SeqList {
private int[] array;
private int usedSize;
public static final int DEFAULT_SIZE = 10;
public SeqList(){
this.array = new int[DEFAULT_SIZE];
//这里我们是只实现了一个大小为10个元素的数组,而在java的顺序表中会实现扩容
}
// 新增元素,默认在数组最后新增
public void add(int data) {}
// 在 pos 位置新增元素
public void add(int pos, int data) {}
// 判定是否包含某个元素
public boolean contains(int toFind) {}
// 查找某个元素对应的位置
public int indexOf(int toFind) {}
// 获取 pos 位置的元素
public int get(int pos) {}
// 给 pos 位置的元素设为 value
public void set(int pos, int value) {}
//删除第一次出现的关键字key
public boolean remove(int toRemove) {}
// 获取顺序表长度
public int size() {}
// 清空顺序表
public void clear() {}
// 打印顺序表,注意:该方法并不是java顺序表中的方法,仅仅是方便看测试结果给出的
public void display() {}
}
3.1.1 新增操作的实现
// 新增元素,默认在数组最后新增
public void add(int data) {
if(usedSize == array.length){
resize();
}
this.array[usedSize] = data;
this.usedSize++;
}
//进行数组扩容
private void resize() {
this.array = Arrays.copyOf(this.array, 2*this.array.length);
}
3.1.2 插入操作的实现
// 在 pos 位置新增元素
public void add(int pos, int data) {
if(pos<0||pos>array.length){
throw new IndexOutOfException("你需要加入数据的位置不合法");
}
if(this.usedSize==array.length){
resize();
}
for (int i = this.usedSize-1; i>=pos ; i--) {
this.array[i+1] = this.array[i];
}
this.array[pos] = data;
this.usedSize++;
}
//定义一个异常,用来判断插入的位置是否合法
public class IndexOutOfException extends RuntimeException{
public IndexOutOfException() {
}
public IndexOutOfException(String message) {
super(message);
}
}
3.1.3 删除操作的实现
//删除第一次出现的关键字key
public boolean remove(int toRemove) {
int index = indexOf(toRemove);
if(index == -1) {
System.out.println("没有这个数据");
return false;
}
for (int i = index;i < usedSize-1;i++) {
this.array[i] = this.array[i+1];
}
usedSize --;
//elem[usedSize] = null;
// 如果里面是引用类型 那么此时就需要手动置空
this.array[usedSize] = 0;
return true;
}
3.1.4 查找操作的实现
3.1.4.1 查找某个元素的位置
// 判定是否包含某个元素
public boolean contains(int toFind) {
for (int i = 0; i < this.usedSize; i++) {
if (array[i]==toFind){
return true;//如果是判断引用类型 就要换equals方法()
}
}
return false;
}
3.4.1.2 查找指定位置的元素
// 获取 pos 位置的元素
public int get(int pos) {
if(pos<0||pos>array.length){
throw new IndexOutOfException("查找的数据位置不合法");
}
return array[pos];
}
3.1.5 获取顺序表长度的实现
// 获取顺序表长度
public int size() {
return this.usedSize;
}
3.1.6 清空顺序表的实现
// 清空顺序表
public void clear() {
for (int i = 0; i < this.usedSize; i++) {
array[i]=0;
//如果是引用类型 就要置为null
}
}
3.1.7 在指定位置设置元素的操作
// 给 pos 位置的元素设为 value
public void set(int pos, int value) {
if(pos<0||pos>array.length){
throw new IndexOutOfException("查找的数据位置不合法");
}
this.array[pos-1]=value;
}
4.java中如果利用顺序表?
4.1 ArrayList简介
在集合框架中,ArrayList是一个普通的类,实现了List接口,具体框架图如下:
【说明】
-
- ArrayList是以泛型方式实现的,使用时必须要先实例化
-
- ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问
-
- ArrayList实现了Cloneable接口,表明ArrayList是可以clone的
-
- ArrayList实现了Serializable接口,表明ArrayList是支持序列化的
-
- 和Vector不同,ArrayList不是线程安全的,在单线程下可以使用,在多线程中可以选择Vector或者
CopyOnWriteArrayList
- 和Vector不同,ArrayList不是线程安全的,在单线程下可以使用,在多线程中可以选择Vector或者
-
- ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表
4.2 ArrayList使用
4.2.1 ArrayList的构造方法
- 1.ArrayList()------> 无参构造
- 2.ArrayList(Collection<? extends E> c)----->利用其他 Collection 构建 ArrayList
- 3.ArrayList(int initialCapacity)----->指定顺序表初始容量
4.3 ArrayList的常见操作
方法 | 解释 |
---|---|
boolean add(E e) | 尾插 e |
void add(int index, E element) | 将 e 插入到 index 位置 |
boolean addAll(Collection<? extends E> c) | 尾插 c 中的元素 |
E remove(int index) | 删除 index 位置元素 |
boolean remove(Object o) | 删除遇到的第一个 o |
E get(int index) | 获取下标 index 位置元素 |
E set(int index, E element) | 将下标 index 位置元素设置为 element |
void clear() | void clear() |
boolean contains(Object o) | 判断 o 是否在线性表中 |
int indexOf(Object o) | 返回第一个 o 所在下标 |
int lastIndexOf(Object o) | 返回最后一个o 所在下标 |
List< E > subList(int fromIndex, int toIndex) | 截取部分 list |
4.4 ArrayList的遍历
ArrayList可以使用 三种方式遍历:for循环+下标、foreach、使用迭代器
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
// 使用下标+for遍历
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i) + " ");
}
System.out.println();
// 借助foreach遍历
for (Integer integer : list) {
System.out.print(integer + " ");
}
System.out.println();
Iterator<Integer> it = list.listIterator();
while(it.hasNext()){
System.out.print(it.next() + " ");
}
System.out.println();
}