1.线性表中的顺序表
线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列...
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。
![](https://img-blog.csdnimg.cn/img_convert/a4ae2712fbff8621d4c2bb46dd961539.png)
2.顺序表
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
2.1接口的整体实现
public class SeqList {
// 打印顺序表
public void display() { }
// 新增元素,默认在数组最后新增
public void add(int data) { }
// 在 pos 位置新增元素
public void add(int pos, int data) { }
// 判定是否包含某个元素
public boolean contains(int toFind) { return true; }
// 查找某个元素对应的位置
public int indexOf(int toFind) { return -1; }
// 获取 pos 位置的元素
public int get(int pos) { return -1; }
// 给 pos 位置的元素设为 value
public void set(int pos, int value) { }
//删除第一次出现的关键字key
public void remove(int toRemove) { }
// 获取顺序表长度
public int size() { return 0; }
// 清空顺序表
public void clear() { }
}
2.2顺序表的定义
顺序表本质上是基于数组进行操作的, 所以顺序表成员中定义一个数组elem来存放数据, 这里的顺序表实现以整形为例, 顺序表中的元素可以是其他类型,实现方法类似。定义变量usedSize用来记录顺序表中的元素个数; 定义常量并给出构造方法以方便在创建顺序表时给数组分配默认空间。
public class MyArrayList {
private int[] elem;//数组
private int usedSize;//记录有效数据个数
private static final int SIZE = 10;
//构造方法
public MyArrayList() {
this.elem = new int[SIZE];
}
}
2.3新增元素,默认在数组最后新增
首先要判断该表如果为空符合条件吗,很显然是可以的。
判断该表是否满了,因为顺序表实际上是数组,是有大小的,如果超出,则需要进行扩容,这里我们进行的是手动二倍扩容(采用的是Arrays.copyOf,将扩容后的拷贝到当前的)。
确定该表满了的条件,当数组的长度等于当前表的长度时,进行判满扩容。
对下标为usedSize的数组进行赋值data操作
public void add(int data) {
if(isFull()){
System.out.println("满了");
this.elem = Arrays.copyOf(this.elem,2*this.elem.length);
}
this.elem[this.usedSize] = data;
this.usedSize++;
}
public boolean isFull(){
if (this.elem.length == this.size()){
return true;
}
return false;
}
2.4在 pos 位置新增元素
判断条件(此时的表是否已经满了,空的话不影响,然后就是pos位置是否合法,pos<0或者pos>size()不合法则抛出异常)。
从后往前开始遍历,依次往前覆盖(i-1)= i,例如从2号位置开始插入,则0 1 2 3 4 覆盖后为 0 1 2 2 3 4,再将2号位置改为需要插入元素的值。
public void add(int pos, int data) throws PosWrongfulException{
if(isFull()){
System.out.println("满了");
this.elem = Arrays.copyOf(this.elem,2*this.elem.length);
}
if(pos < 0 || pos > this.usedSize){
throw new PosWrongfulException("pos不合法");
}
//pos合法,从pos位置开始所有元素往后挪一次
for (int i = this.usedSize; i > pos; i--) {
this.elem[i] = this.elem[i-1];
}
//将pos位置更为插入数据
this.elem[pos] = data;
//更新新的数据个数
this.usedSize++;
}
public boolean isFull(){
if (this.elem.length == this.size()){
return true;
}
return false;
}
2.5判定是否包含某个元素
遍历该数组即可。
public boolean contains(int toFind) {
for (int i = 0; i < this.size(); i++) {
if (this.elem[i] == toFind){
return true;
}
}
return false;
}
2.6查找某个元素对应的位置
遍历该数组即可。
public int indexOf(int toFind) {
for (int i = 0; i < this.size(); i++) {
if (this.elem[i] == toFind){
return i;
}
}
return -1;
}
2.7获取 pos 位置的元素
1.如果顺序表中没有存放元素的话是不能去获取元素的, 这里同样可以去声明一个异常去解决问题。
2.同时要判断位置的合法性(注意这次pos位置的区间,和前面的区别)。
3.上面两个条件都没问题的话就可以通过下标去获取元素了。
public int get(int pos) throws PosWrongfulException,EmptyException{
if(isEmpty()){
throw new EmptyException("空异常了");
}
if(pos < 0 || pos >= this.usedSize){
throw new PosWrongfulException("pos不合法");
}
return this.elem[pos];
}
public boolean isEmpty(){
return this.size()==0;
}
2.8给 pos 位置的元素设为 value
同2.7。
public void set(int pos, int value) throws PosWrongfulException,EmptyException{
if(isEmpty()){
throw new EmptyException("空异常了");
}
if(pos < 0 || pos >= this.usedSize){
throw new PosWrongfulException("pos不合法");
}
this.elem[pos] = value;
}
2.9删除第一次出现的关键字key
1.判断顺序表是否为空。
2.不为空则先找到要删除元素的位置,可参考2.6。
3.将key之后的元素逐一往前覆盖, 将key覆盖便达到了删除的效果。
4.最后要记得元素的有效个数要减1。
5.需要注意的是,这里删除的基本数据类型的数据, 删除后相对于删除前数组的最后一个位置, 虽然那个位置还留有原来的值, 但这个值不置为0并不会有什么影响;而如果顺序表中放置的是引用类型, 此时这个位置必须置空(置为null), 否则会有内存泄漏的问题存在
public void remove(int toRemove) {
if(isEmpty()){
throw new EmptyException("空异常了");
}
//查找要删除元素的位置,参考2.6
int r = this.indexOf(toRemove);
if(r == -1) {
System.out.println("没有这个数字");
return;
}
//删除元素,从后往前进行覆盖
for (int i = r; i < this.usedSize-1; i++) {
this.elem[i] = this.elem[i+1];
}
//更新有效数据个数
this.usedSize--;
}
2.10获取顺序表长度
获取顺序表中记录数组中有效数据个数的成员即可。
public int size() {
return this.usedSize;
}
2.11清空顺序表
将数组的有效元素个数赋值为0即可;同样的, 要注意如果顺序表中的元素是引用类型的话, 要将数组中的每个元素都置为null。
public void clear() {
this.usedSize = 0;
System.out.println("顺序表也已经清空");
}
2.12打印顺序表
遍历数组打印即可。
public void display() {
for (int i = 0; i < this.size(); i++) {
System.out.print(this.elem[i]+" ");
}
System.out.println();
}
3.顺序表的全局实现
3.1 EmptyException.java(空指针异常)
public class EmptyException extends RuntimeException{
public EmptyException() {
}
public EmptyException(String message) {
super(message);
}
}
3.2 PosWrongfulException.java(越界异常)
public class PosWrongfulException extends RuntimeException{
public PosWrongfulException() {
}
public PosWrongfulException(String message) {
super(message);
}
}
3.3 MyArrayLisst.java
import java.util.Arrays;
/**
* Created with IntelliJ IDEA.
* Description:
* User:YY
* Date:2023-02-09
* Time:19:52
*/
public class MyArrayList {
public int[] elem;
public int usedSize;
private static final int SIZE = 10;
public MyArrayList() {
this.elem = new int[SIZE];
}
public void display() {
for (int i = 0; i < this.size(); i++) {
System.out.print(this.elem[i]+" ");
}
System.out.println();
}
// 新增元素,默认在数组最后新增
public void add(int data) {
if(isFull()){
System.out.println("满了");
this.elem = Arrays.copyOf(this.elem,2*this.elem.length);
}
this.elem[this.usedSize] = data;
this.usedSize++;
}
public boolean isFull(){
if (this.elem.length == this.size()){
return true;
}
return false;
}
// 在 pos 位置新增元素
public void add(int pos, int data) throws PosWrongfulException{
if(isFull()){
System.out.println("满了");
this.elem = Arrays.copyOf(this.elem,2*this.elem.length);
}
if(pos < 0 || pos > this.usedSize){
throw new PosWrongfulException("pos不合法");
}
//pos合法,从pos位置开始所有元素往后挪一次
for (int i = this.usedSize; i > pos; i--) {
this.elem[i] = this.elem[i-1];
}
//将pos位置更为插入数据
this.elem[pos] = data;
//更新新的数据个数
this.usedSize++;
}
// 判定是否包含某个元素
public boolean contains(int toFind) {
for (int i = 0; i < this.size(); i++) {
if (this.elem[i] == toFind){
return true;
}
}
return false;
}
// 查找某个元素对应的位置
public int indexOf(int toFind) {
for (int i = 0; i < this.size(); i++) {
if (this.elem[i] == toFind){
return i;
}
}
return -1;
}
// 获取 pos 位置的元素
public int get(int pos) throws PosWrongfulException,EmptyException{
if(isEmpty()){
throw new EmptyException("空异常了");
}
if(pos < 0 || pos >= this.usedSize){
throw new PosWrongfulException("pos不合法");
}
return this.elem[pos];
}
public boolean isEmpty(){
return this.size()==0;
}
// 给 pos 位置的元素设为 value
public void set(int pos, int value) throws PosWrongfulException,EmptyException{
if(isEmpty()){
throw new EmptyException("空异常了");
}
if(pos < 0 || pos >= this.usedSize){
throw new PosWrongfulException("pos不合法");
}
this.elem[pos] = value;
}
//删除第一次出现的关键字key
public void remove(int toRemove) {
if(isEmpty()){
throw new EmptyException("空异常了");
}
int r = this.indexOf(toRemove);
if(r == -1) {
System.out.println("没有这个数字");
return;
}
for (int i = r; i < this.usedSize-1; i++) {
this.elem[i] = this.elem[i+1];
}
this.usedSize--;
}
// 获取顺序表长度
public int size() {
return this.usedSize;
}
// 清空顺序表
public void clear() {
this.usedSize = 0;
System.out.println("顺序表也已经清空");
}
}
3.4 TestList.java(测试部分)
import javafx.geometry.Pos;
/**
* Created with IntelliJ IDEA.
* Description:
* User:YY
* Date:2023-02-09
* Time:19:51
*/
public class TestList {
public static void main(String[] args) {
MyArrayList myArrayList = new MyArrayList();
myArrayList.add(5);
myArrayList.add(3);
myArrayList.add(4);
myArrayList.add(1);
myArrayList.display();
System.out.println("-----------------------------");
try{
myArrayList.add(1,2);
}catch (PosWrongfulException e){
e.printStackTrace();
}
System.out.println(myArrayList.size());
myArrayList.display();
System.out.println("---------------------");
System.out.println(myArrayList.contains(2));
System.out.println(myArrayList.contains(10));
System.out.println(myArrayList.indexOf(3));
System.out.println(myArrayList.indexOf(100));
System.out.println("----------------------------");
try {
System.out.println(myArrayList.get(4));
}catch (PosWrongfulException e) {
e.printStackTrace();
}
myArrayList.set(4,99);
myArrayList.display();
System.out.println("==========================");
myArrayList.remove(3);
myArrayList.display();
System.out.println("==========================");
myArrayList.clear();
myArrayList.display();
myArrayList.add(4);
myArrayList.add(1);
myArrayList.display();
}
/** public static void main(String[] args) {
MyArrayList myArrayList = new MyArrayList();
myArrayList.add(1);
myArrayList.add(2);
myArrayList.add(3);
myArrayList.display();
try {
myArrayList.add(1,10);
}catch (PosWrongfulException e) {
e.printStackTrace();
}
myArrayList.display();
System.out.println("==========================");
System.out.println(myArrayList.contains(10));
System.out.println(myArrayList.contains(100));
System.out.println(myArrayList.indexOf(10));
System.out.println(myArrayList.indexOf(100));
System.out.println("==========================");
try {
System.out.println(myArrayList.get(1));
}catch (PosWrongfulException e) {
e.printStackTrace();
}
myArrayList.set(0,99);
myArrayList.display();
System.out.println("==========================");
myArrayList.remove(10);
myArrayList.display();
System.out.println("==========================");
myArrayList.clear();
myArrayList.display();
myArrayList.add(19999);
myArrayList.display();
}*/
}
3.5 测试结果
![](https://img-blog.csdnimg.cn/img_convert/aab5f5dd1721d8f77992bd6307a09b0e.png)