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

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

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

package com.phn.datestructure;
/**
 * @author 潘海南
 * @Email [email protected]
 * @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)。

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

优缺点分析:

优点:

  • 不用为表示表中数据元素之间的逻辑关系而增加额外的存储空间;
  • 可以快速的存取表中任意位置的元素。

    缺点:

  • 插入和删除操作需要移动大量元素;
  • 当线性表的长度变化较大的时候,很难确定存储空间的容量;
  • 容易造成存储空间的“碎片”。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-21 15:24:00

Java数据结构-线性表之顺序表ArrayList的相关文章

java数据结构与算法之顺序表与链表深入分析

转载请注明出处(万分感谢!): http://blog.csdn.net/javazejian/article/details/52953190 出自[zejian的博客] 关联文章: java数据结构与算法之顺序表与链表设计与实现分析 java数据结构与算法之双链表设计与实现 ??数据结构与算法这门学科虽然在大学期间就已学习过了,但是到现在确实也忘了不少,因此最近又重新看了本书-<数据结构与算法分析>加上之前看的<java数据结构>也算是对数据结构的进一步深入学习了,于是也就打算

数据结构Java实现02----线性表与顺序表

[正文] 本节内容: 线性结构 线性表抽象数据类型 顺序表 顺序表应用 一.线性结构: 如果一个数据元素序列满足: (1)除第一个和最后一个数据元素外,每个数据元素只有一个前驱数据元素和一个后继数据元素: (2)第一个数据元素没有前驱数据元素: (3)最后一个数据元素没有后继数据元素. 则称这样的数据结构为线性结构. 二.线性表抽象数据类型: 1.线性表抽象数据类型的概念: 线性表抽象数据类型主要包括两个方面:既数据集合和该数据集合上的操作集合. 数据集合: 可以表示为a0,a1,a2,...a

数据结构Java实现01----线性表与顺序表

一.线性结构: 如果一个数据元素序列满足: (1)除第一个和最后一个数据元素外,每个数据元素只有一个前驱数据元素和一个后继数据元素: (2)第一个数据元素没有前驱数据元素: (3)最后一个数据元素没有后继数据元素. 则称这样的数据结构为线性结构. 二.线性表抽象数据类型: 1.线性表抽象数据类型的概念: 线性表抽象数据类型主要包括两个方面:既数据集合和该数据集合上的操作集合. 数据集合: 可以表示为a0,a1,a2,...an-1,每个数据元素的数据类型可以是任意的类型. 操作集合包括如下: 1

《数据结构》复习之线性表(顺序表和链表)

线性表的概念 线性表的比较 线性表的数据结构 顺序表的算法操作 双链表的补充 总结 1.线性表的概念 线性表的存储结构有顺序存储结构和链式存储结构两种.前者成为顺序表,后者称为链表. 顺序表: 顺序表就是把线性表中的所有元素按照其逻辑顺序,一次存储到从指定的存储 位置开始的一块连续的存储空间中,如下图所示. 链表 在链表的存储中,每一个节点不仅包含所存元素本身的信息,还包含元素之间的逻辑关系的信息,即前驱节点包含后继节点的地址信息,这样就可以通过前驱节点中的地址信息方便地找到后继节点的位置,如下

[C++] 数据结构(C):线性表之顺序表

1 顺序表 ADT + Status InitList(SeqList &L) 初始化顺序表 + Status GetElement(SeqList L, int i, ElementType &e) (按位)取值  + int LocateElement(SeqList L, ElementType e) (按值)查找  + Status ListInsert(SeqList &L, int i, ElementType e) (按位)插入  + Status ListDelet

数据结构-线性表_顺序表

进入大学一年了,今日终于有勇气写写随笔并展示出来了. 如有不足之处,请大家指正. 今日我想写的就是我对数据结构-线性表_顺序表的理解. 不BB了,进入正题!!!!! 数据结构中的逻辑结构分为线性结构和非线性结构,而线性表就属于线性结构. 线性结构是 n 个数据元素的有序(次序)集合,它有下列几个特征: 集合中必存在唯一的一个 "第一个元素": 集合中必存在唯一的一个 "最后的元素": 除最后元素之外,其它数据元素均有唯一的 "后继": 除第一元素

数据结构-02 _用顺序表解决线性表的编程问题

看到这个标题,相必最先应该只到什么是顺序表,什么是线性表. 线性表(linear list):由n(n>=0)个相同的数据类型的数据元素(结点)a0,a1,a2,...an-1 组成的有限序列. 顺序表:把线性表的结构按照逻辑顺序存放在一组地址连续的存储单元里,用这种方式存储的线性表简称顺序表. 线性表的基本操作: 1.初始化操作 2.插入操作:InsertNode(T a,int i) 在线性表的第i个位置插入一个值为a的新元素,使得原序号为i,i+1,...,n 的数据元素的序号变成i+1,

【算法和数据结构】_17_小算法_线性结构:顺序表

/* 本程序用来测试数据结构中的线性结构:顺序表 */ #include <stdio.h> #include <stdlib.h> #define LINEAR_MAX_SIZE 64 struct LinearList { int* List; //顺序表指针 unsigned short int ListLen; //顺序表最大的元素个数 unsigned short int CurrentLen; //顺序表当前元素的个数 }; typedef struct LinearL

线性链表之顺序表

顺序表中数据元素的存储地址是其序号的线性函数,只要确定了存储顺序表的起始地址(即 基地址),计算任意一个元素的存储地址的时间是相等的,具有这一特点的存储结构称为[随机存储]. 使用的基本数据结构:数组 特点:顺序存取,随机访问. /* Name: SeqList Copyright: 1.0 Author: Johnny Zen Date: 04/06/17 21:51 Description: 线性链表之顺序表 *//* Chinese:顺序(线性)表 English:SeqList*/#in

数据结构C#版笔记--顺序表(SeqList)

线性结构(Linear Stucture)是数据结构(Data Structure)中最基本的结构,其特征用图形表示如下: 即:每个元素前面有且只有一个元素(称为"前驱"),同样后面有且只有一个元素(称为"后继")--注:起始元素的前驱认为是空,末尾元素的后继认为也是空,这样在概念上就不冲突了. 线性表(List)是线性结构的一种典型实现,它又可以分为:顺序表(SeqList)和链表(LinkList)二大类. 顺序表(SeqList)的基本特征为:元素在内部存储时