• Java数据结构-线性表之顺序表ArrayList


    线性表的顺序存储结构。也称为顺序表。指用一段连续的存储单元依次存储线性表中的数据元素。

    依据顺序表的特性,我们用数组来实现顺序表,以下是我通过数组实现的Java版本号的顺序表。

    package com.phn.datestructure;
    /**
     * @author 潘海南
     * @Email 1016593477@qq.com
     * @TODO 顺序表
     * @date 2015年7月16日
     */
    public class FOArrayList<E> {
        // 顺序表长度
        private int size;
        // 顺序表默认数组为null
        private Object[] data = null;
        // 顺序表中数组的初始化长度
        private int capacity;
        // 顺序表默认初始化长度
        private static final int DEFUALT_INITIAL_SIZE = 0;
        /**
         * 默认无參构造函数
         */
        public FOArrayList() {
            this(DEFUALT_INITIAL_SIZE);
        }
        /**
         * @TODO 带參构造函数
         * @param initialSize 初始化顺序表长度
         */
        public FOArrayList(int initialSize) {
            if (initialSize < 0) {
                throw new RuntimeException("数组大小错误:" + initialSize);
            }
            this.data = new Object[initialSize];
            this.capacity = initialSize;
            this.setSize();
        }
        /**
         * @TODO 设置顺序表的长度
         */
        private void setSize() {
            this.size = 0;
        }
        /**
         * @TODO 获取顺序表的长度
         * @return size 顺序表的长度
         */
        public int size() {
            return this.size;
        }
        /**
         * @TODO 顺序表加入元素
         * @param e 数据元素类型
         * @return true
         */
        public boolean add(E e) {
            ensureSize(size);
            this.data[size] = e;
            this.size++;
            return true;
        }
        /**
         * @TODO 顺序表插入元素
         * @param index 插入位置
         * @param e 数据元素类型
         * @return true
         */
        public boolean insert(int index, E e) {
            if (index >= 0 && index <= size) {
                ensureSize(size);
                E temp = (E) this.data[index - 1];
                this.data[index - 1] = e;
                this.size++;
                for (int i = index; i <= size; i++) {
                    E temp2 = (E) this.data[i];
                    this.data[i] = temp;
                    temp = temp2;
                }
            } else {
                throw new RuntimeException("数组下标错误:" + index);
            }
            return true;
        }
        /**
         * @TODO 顺序表删除元素
         * @param index 将要删除的元素的索引位置
         * @return E 删除的元素
         */
        public E remove(int index) {
            validateIndex(index);
            E e = (E) this.data[index];
            for (int i = index; i < size - 1; i++) {
                this.data[i] = this.data[i + 1];
            }
            this.size--;
            return e;
        }
        /**
         * @TODO 依据元素索引位置获取元素
         * @param index 元素的索引位置
         * @return E 元素e
         */
        public E get(int index) {
            validateIndex(index);
            return (E) this.data[index];
        }
        /**
         * @TODO 将顺序表中索引位置为i的元素改动为元素e
         * @param index 元素的索引位置
         * @param e 须要改动成的元素
         * @return true 改动成功标志
         */
        public boolean set(int index, E e) {
            validateIndex(index);
            this.data[index] = e;
            return true;
        }
        @Override
        public String toString() {
            return this.arrayToString(data);
        }
        /**
         * @TODO 获取字符串形式的顺序表中的数组序列
         * @param a 顺序表中的数组
         * @return String 字符串形式的顺序表中的数组序列
         */
        private String arrayToString(Object[] a) {
            if (a == null)
                return "null";
            int iMax = this.size - 1;
            if (iMax == -1)
                return "[]";
            StringBuilder b = new StringBuilder();
            b.append('[');
            for (int i = 0;; i++) {
                b.append(String.valueOf(a[i]));
                if (i == iMax)
                    return b.append(']').toString();
                b.append(", ");
            }
        }
        /**
         * @TODO 验证所给索引位置是否合法
         * @param index 给出的索引位置
         */
        private void validateIndex(int index) {
            if (index >= this.size || index <= 0) {
                throw new RuntimeException("数组下标错误:" + index);
            }
        }
        /**
         * @TODO 推断是否须要扩充顺序表容量
         * @param currentSize 当前顺序表的大小
         */
        private void ensureSize(int currentSize) {
            if (currentSize == capacity) {
                this.capacity = (this.capacity * 3) / 2 + 1;
                Object[] newData = new Object[this.capacity];
                for (int i = 0; i < currentSize; i++) {
                    newData[i] = this.data[i];
                }
                this.data = newData;
            }
        }
    }
    

    主要注意上述3个私有成员变量。例如以下:

    // 顺序表长度
    private int size;
    // 顺序表中数组的初始化长度
    private int capacity;
    // 顺序表默认数组为null
    private Object[] data = null; 
    

    如同凝视解释的那样,size用来表示顺序表的长度。data用来表示数组,而capacity用来表示数组的长度.
    相信data应该比較好理解,而相应的两个长度变量相对难理解一些,以下解释一下:

    • size指的是对外界訪问这个顺序表的长度时展示的值,是顺序表中数据元素的个数,随顺序表插入和删除操作而会进行改变;
    • capacity表示的是data数组的长度,实际上也是整个顺序表的容量。在顺序表初始化的时候能够赋值。或者之后能够调用顺序表的扩容来进行改变;
    • size是小于等于capacity的。

    这里主要讲讲顺序表的插入和删除:
    顺序表的插入演示如图所看到的:

    依据图片能够看出插入一个元素后,插入位置之后的元素都须要向后移动一个位置。
    删除操作则是插入操作的逆过程,删除位置之后的元素都须要向前移动一个位置。

    时间复杂度分析:

    • 在顺序表进行存入,查找和改动时,平均时间复杂度都是O(1);
    • 而在进行插入和删除操作时。最快时为O(1),最慢时为O(n),所以平均时间复杂度为O(n)。

    解释:上述的存入和插入有差别,存入表示存储在数组末尾,而插入表示插入在任何位置。

    优缺点分析:
    长处:

    • 不用为表示表中数据元素之间的逻辑关系而添加额外的存储空间;
    • 能够高速的存取表中任何位置的元素。
      缺点:

    • 插入和删除操作须要移动大量元素;

    • 当线性表的长度变化较大的时候,非常难确定存储空间的容量;
    • easy造成存储空间的“碎片”。
  • 相关阅读:
    Scrapy框架-scrapy框架快速入门
    Scrapy框架-scrapy框架架构详解
    linux常用命令大全
    Redis常用命令大全
    centos7安装keepalived问题
    redis集群部署那点事
    centos7安装python3.6后导致防火墙功能无法正常工作的解决办法
    MySQL/Oracle视图的创建与使用
    通过sqoop将hdfs数据导入MySQL
    股票交易日定时爬取上交所/深交所所有股票行情数据存储到数据库
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/7256132.html
Copyright © 2020-2023  润新知