zoukankan      html  css  js  c++  java
  • 数据结构学习笔记(3)_使用数组实现简单线性表功能

    线性表(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)

  • 相关阅读:
    A Node Influence Based Label Propagation Algorithm for Community detection in networks 文章算法实现的疑问
    Fast Newman-FN算法以及模块度定义介绍
    Label Propagation Algorithm LPA 标签传播算法解析及matlab代码实现
    设计一个smartnic
    Intel GEN11 GPU
    Intel GEN9 GPU
    Shared Virtual Memory (SVM) Functions
    connect via ssh to virtualbox guest vm without knowing ip address
    smartnic
    技术精品翻译
  • 原文地址:https://www.cnblogs.com/yjiyjige/p/3179145.html
Copyright © 2011-2022 走看看