博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据结构学习笔记(3)_使用数组实现简单线性表功能
阅读量:6970 次
发布时间:2019-06-27

本文共 4896 字,大约阅读时间需要 16 分钟。

线性表(List):零个或多个数据元素的有限序列。

关键字有两个:

  “零个”也就是说线性表是可以为空的

  “有限序列”不管多长的线性表,总要有一个最大长度,并且元素与元素之间是一对一的关系,也即有一定的顺序

在Java中有一个很“神奇的”类,就是ArrayList。它神奇的地方在于它使用起来和数组一样简单,但却提供了更多更方便的方法。感觉上ArrayList是可以无限添加元素的!这一点太方便了,它是怎么做到的呢?

其实,ArrayList是底层就是用数组来实现的!但是上次不是才说数组的长度是不能变的吗?实际上,它可以实现“无限的”添加元素只是因为它的底层有一个机制,在数组空元素用完的时候会生成一个长度更长的数组,然后把之前的元素复制过去,这样就实现了扩容。但对于使用者来说,我们不需要关心这些细节。这就是Java基础类带来的方便啊!

我们自己来实现一个ArrayList,不过扩容的功能麻烦了点就不做了~~~但基本的一个线性表应该具有的功能应该是(假定要放入的元素都是int型的,当然改成范型也是可以的):

boolean add(int value)在表的末尾添加新元素;boolean insert(int index, int value)。

boolean remove(int index)移除指定位置的元素;void clear()清空整个表。

boolean update(int index, int value)将指定位置的元素修改成指定的值。

int select(int value)在线性表中查询指定的值,返回元素的位置。如果不存放,返回“-1”。

还有一些功能也是必须的:

长度:int size()返回线性表的长度。

判空boolean isEmpty()返回该线性表是否为空。

取值int getValue(int index)获取特定位置的值。

 

好的,现在我们开始写代码:

  首先当然是想一下怎样初始化的问题了。

  本质上,我们还是通过数组来实现,所以我们应该是先定义一个一定长度的的数组,并且,我们应该用一个变量来记录我们添加了多少个元素吧。我们把这个类叫MyArrayList:

public class MyArrayList {    // 这个线性表的最大长度    public static final int MAX_LEN = 100;    // 用来保存数据的数组    private int[] array = new int[MAX_LEN];    // 用定记录线性表的长度    private int len;}

  好的,下面就是重头戏了,我们来实现功能了,先从add开始。

思路如下:

  先判断线性表的长度是否等于最大的长度,如果相等,就说明表已满。不能插入返回false;否则,插入到末尾处,表的长度加1,返回true。代码实现如下:

public boolean add(int value) {    // 判断线性表是否已满    if (len == MAX_LEN) {        return false;    }    else {        array[len] = value;        len++;        return true;    }}

  在指定的位置插入数据比较麻烦一点。想象一下,你在饭堂打饭,有前面有一个人插队。那应该是最后的人先退后一步吧,这样前面的人,每个都退后一个就能够腾出位置。所以在指定位置插入的话,要先做这样一步工作。

  同理,删除一个元素的话,那也就是把这个元素之后的数据依次往前移到一位咯~~~

  其他方法也是差不多这个样,就不说了,自己看代码快点~~~

public class MyArrayList {    // 这个线性表的最大长度    public static final int MAX_LEN = 100;    // 用来保存数据的数组    private int[] array = new int[MAX_LEN];    // 用定记录线性表的长度    private int len;        /**     * 添加数据到线性表末尾     * @param value 要添加的值     * @return 添加成功为true,添加失败为false     */    public boolean add(int value) {        // 判断线性表是否已满        if (len == MAX_LEN) {            return false;        }        else {            array[len] = value;            len++;            return true;        }    }        /**     * 在指定的位置添加数据     * @param index 添加的位置     * @param value 添加的数据     * @return 添加成功为true,添加失败为false     */    public boolean insert(int index, int value) {        if (len == MAX_LEN) {            return false;        }        // 如果插入的位置不合理        if (index < 0 || index > len) {            return false;        }        else {            // 在index之后的元素都应该向后移            for (int i = len; i > index; i--) {                array[i] = array[i - 1];            }            array[index] = value;            len++;            return true;        }    }    /**     * 清空线性表     */    public void clear() {        len = 0;    }        /**     * 移除指定位置的元素     * @param index 要移除的元素的位置     * @return 移除成功为true,添加失败为false     */    public boolean remove(int index) {        if (index < 0 || index > len - 1) {            return false;        }        else {            // 相当于把index后面的元素向前移一位            for (int i = index; i < len - 1; i++) {                array[i] = array[i + 1];            }            len--;            return true;        }    }        /**     * 更新指定位置的元素的值     * @param index 要更新的元素的位置     * @param value 新的值     * @return 更新成功为true,添加失败为false     */    public boolean update(int index, int value) {        if (index < 0 || index > len - 1) {            return false;        }        else {            array[index] = value;            return true;        }    }        /**     * 查询指定的数值是否在线性表中     * @param value 要查询的数值     * @return 如果找到的话为第一个匹配的位置,找不到的话,返回-1     */    public int select(int value) {        int index = 0;        for (; index < len; index++) {            if (array[index] == value) {                break;            }        }        if (index == len) {            return -1;        }        else {            return index;        }    }        /**     * 获得线性表的长度     * @return 线性表的长度     */    public int size() {        return len;    }        /**     * 判断线性表是否为空     * @return 如果为空,返回true,否则为false     */    public boolean isEmpty() {        if (len == 0) {            return true;        }        else {            return false;        }    }        /**     * 获取某一位置的值     * @param index 指定的元素位置     * @return 该位置的值,如果指定的位置不合理,抛出异常     */    public int getValue(int index) {        if (index < 0 || index > len - 1) {            // 我们这里就不自己定义异常了,让系统去抛出~~~            return array[MAX_LEN];        }        else {            return array[index];        }    }}

  其实这样下来,Java自带的ArrayList能够实现的功能我们已经实现了大半了~~~,从上面的代码不难看出,如果在ArrayList进行大量的数据插入和删除操作,效率是比较低的。但它的读取性能是相当高的。

总的来说,ArrayList主要有两个缺点:

  第一是插入和删除操作带来的大量的数据移动。比如每次都往第0个位置插入或删除,当数据元素很多时,这样的操作也是很费时的。

  第二是,默认数组分配的大小问题。默认的数组分配得小,那么一下子就不够用了,就要进行数组的“扩容”;如果分配得过大的话,那么就很可能浪费大量的空间。所以,如果我们在事前已经大概知道有多少个元素时,最好是使用ArrayList的:public ArrayList(int initialCapacity)这个构造方法。(默认的数组长度是10)

转载于:https://www.cnblogs.com/yjiyjige/p/3179145.html

你可能感兴趣的文章
微信开发(一)基于Wx-java的微信分享功能
查看>>
线程池的原理及实现(转)
查看>>
Scrapy学习(二)、安装及项目结构
查看>>
ListView控件的基本属性
查看>>
Java中String、StringBuffer、StringBuilder的区别
查看>>
F#与数学(III) – 自定义数字类型(PartI)
查看>>
转载 解析nginx负载均衡
查看>>
关闭进程的--数据库
查看>>
VC++6.0 Win32 C2065:SM_XVIRTUALSCREEN
查看>>
Oracle 事务 锁
查看>>
SQLite Expert表分离和解决SQLite Expert删除表后大小不变的问题
查看>>
Spark- 使用第三方依赖解析IP地址
查看>>
删除排序数组中的重复数字
查看>>
trim()方法
查看>>
No.2 R语言在生物信息中的应用—模式匹配
查看>>
权限管理设计二
查看>>
Python 面向对象 --- 异常
查看>>
回调函数c++
查看>>
【Python】opencv显示图像
查看>>
c# datetime用法总结
查看>>