Java学习苦旅(九)——原来顺序表可以这么简单呀

本篇博客将详细讲解顺序表的相关知识。

顺序表的概念

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。

顺序表一般分为两类:静态顺序表和动态顺序表。

静态顺序表:使用定长数组存储。

动态顺序表:使用动态开辟的数组存储。

为了让顺序表能更好地面向对象,需要创建一个类,来完成顺序表的各种功能。

顺序表的实现

变量创建

既然顺序表一般是用数组存储,因此需要一个数组。为了确定数组的长度(有效值的个数),因此还需要设置一个变量。代码如下:

public int[] elem;
public int usedSize;

为了在实例化对象的时候创建数组,因此需要一个构造方法。代码如下:

public MyArrayList(){
	this.elem = new int[10];
}

注:我所创建的类的类名为MyArrayList,初始创建的数组大小为10。

打印顺序表

我们在使用顺序表的时候,一般需要打印顺序表,查看顺序表里的内容。代码如下:

public void display() {
	for (int i = 0;i < this.usedSize;i++) { 
		System.out.print(this.elem[i] + " ");
	}
	System.out.println();
}

注:i<this.usedSize:表示顺序表中的有效数据的长度,而不是数组的长度。

获取顺序表的(有效)长度

我们在使用顺序表的时候,需要知道顺序表的有效长度。代码如下:

public void size() {
    return this.usedSize;
}

增加元素

在顺序表的使用过程中,我们难免需要增加元素。因此我们需要一个方法来完成这个功能。假设在pos位置增加元素,而在增加元素的过程中,需要分四步。

判断pos位置的合法性

pos不能为负数,同时pos不能大于usedSize,否则没有意义。

判断顺序表是否需要扩容

I在增加元素的时候,顺序表很有可能放满元素了,因此首先要判断顺序表是否已经放满元素,如果已经放满,则需要对顺序表进行扩容。

将顺序表中的已有数据进行移动

因为需要在pos位置增加元素,因此pos位置以后的数据需要向后移动,移动方向如下图:

顺序表1

数据插入后,usedSize++

当数据插入后,有效长度(usedSize)需要加1。

具体代码

public void add(int pos, int data) {
    if(pos < 0 || pos > usedSize) {
        System.out.println("pos位置不合法");
        return;
    }
    if(isFull()) {
        this.elem = Arrays.copyOf(this.elem,2 * this.elem.length);
    }
    for(int i = this.usedSize - 1; i >= pos; i--) {
        this.elem[i+1] = this.elem[i];
    }
    this.elem[pos] = data;
    this.useSize++;
}

public boolean isFull() {
    return this.useSize == this.elem.length;
}

判断顺序表中是否包含某个元素

在使用顺序表的时候,我们需要判断顺序表中是否包含某个数据,具体代码如下:

public boolean contains(int toFind) {
    for (int i = 0; i < this.usedSize; i++) {
        if(this.elem[i] == toFind) {
            return true;
        }
    }
    return false;
}

查找元素

顺序表的功能中应该包含查找功能,具体代码如下:

public int search(int toFind) {
    for (int i = 0; i < this.usedSize; i++) {
        if(this.elem[i] == toFind) {
            return i;
        }
    }
    return -1;
}

获取元素

假设需要获取pos位置的元素,代码如下:

public int getsPos(int pos) {
    if(pos < 0 || pos >= this.usedSize) {
        System.out.println("pos位置不合法");
        return -1;//这里的-1仅仅代表位置不合法,不考虑业务的处理。当然,也可以用异常去处理,后期会讲到。
    }
    return this.elem[pos];
}

更改元素

假设更改pos位置的元素,将其改为value,代码如下:

public void setPos(int pos, int value) {
    if(pos < 0 || pos >= this.usedSize) {
        System.out.println("pos位置不合法");
        return -1;
    }
    this.elem[pos] = value;
}

删除元素

删除元素的步骤如下:

1.判断顺序表是否为空

2.查找要删除的元素

3.删除元素

删除元素的本质是覆盖,假设删除下列顺序表中的85:

顺序表2

具体代码如下:

public void remove(int toRemove) {
    if(isEmpty()) {
        System.out.println("顺序表为空!");
        return -1;
    }
    int index = search(toRemove);
    if(index == -1) {
        System.out.println("没有你要删除的数字");
        return -1;
    }
    for(int i = index;i < this.usedSize-1;i++) {
        this.elem[i] = this.elem[i+1];
    }
    this.usedSize--;


public boolean isEmpty() {
    return this.usedSize == 0;
}

清空顺序表

假设顺序表中存放的是简单类型的数据,则清空顺序表的代码如下:

public void clear() {
    this.usedSize = 0;
}

顺序表的缺点

1.插入和删除元素时,必须移动元素。

2.需要考虑扩容的问题,容易造成内存没有充分的问题。

结尾

那么有没有其他的数据结构可以解决这些问题呢?

当然有。 至于是什么,且听下回分说。

上一篇博客:Java学习苦旅(八)——不复杂的复杂度

下一篇博客预告:Java学习苦旅(十)——链表的奥秘

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>