73

(java实现)顺序表-ArrayList

 4 years ago
source link: https://www.tuicool.com/articles/f6Rj6fm
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

什么是顺序表

顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构。

在使用顺序表存储数据前,会先申请一段连续的内存空间(即数组),然后把数组依次存入内存,中间没有一点空隙。

YZN7niZ.gif

基本操作

每个数据结构都有集合对数据处理的方法,这能让我们更方便的使用保存在数据结构中的数据。顺序表的基本操作有:增(add),删(remove),改(set),查(find),插(insert)等。

在这里我们只详细讲解remove 和 insert 操作,其他实现可看下面的源码。

顺序表删除元素

从顺序表中删除指定元素,实现起来非常简单,只需找到目标元素,并将其后续所有元素整体前移 1 个位置即可。

后续元素整体前移一个位置,会直接将目标元素删除,可间接实现删除元素的目的。

例如:从顺序表{1,2,3,4,5}中删除元素3的过程如下

ZjIfmaR.gif

时间复杂度分析:从顺序表中删除元素,最好的情况是删除的元素刚好是最后一个元素,这时候不需要移动元素,只需要把顺序表的size-1即可,时间复杂度是O(1)。最坏的情况是删除的元素刚好是第一个元素,这个时候就需要后面的元素全部向前移动一位,同时size-1,时间复杂度是O(N)。我们分析时间复杂度的原则是分析最坏情况,这样才有意义。因此删除操作的时间复杂度为O(N)。

顺序表插入元素

向已有顺序表中插入数据元素,根据插入位置的不同,可分为以下 3 种情况:

  1. 插入到顺序表的表头;
  2. 在表的中间位置插入元素;
  3. 尾随顺序表中已有元素,作为顺序表中的最后一个元素;

虽然数据元素插入顺序表中的位置有所不同,但是都使用的是同一种方式去解决,即:通过遍历,找到数据元素要插入的位置,然后做如下两步工作:

  • 将要插入位置元素以及后续的元素整体向后移动一个位置;
  • 将元素放到腾出来的位置上;

例如,在 {1,2,3,4,5} 的第 3 个位置上插入元素 6,实现过程如下:

BR3EbqV.gif

qyaiu2M.gif

AFb6rmj.gif

时间复杂度分析同删除元素一样,均为O(N).

顺序表的优劣和应用情形

优势

  • 因为数据在数组中按顺序存储,可以通过数组下标直接访问,因此顺序表查找定位元素很快

劣势

  • 插入和删除元素需要大量的操作
  • 因为数组在声明时需要确定长度,因此顺序表的长度是确定的。若需要扩大顺序表长度,有需要大量的操作,不够灵活。(将该数组copy到另外一个数组)
  • 由于数据大小的不可测性,有时会浪费掉大量的空间

应用情形

  • 总而言之,顺序表适用于那些不需要对数据进行大量改动的结构

源码实现(java)

public class MyArrayList<AnyType> {
    public int AMOUNT=10;//初始长度
    public static int index;//表位置
    AnyType[] myList;
    public MyArrayList(){
        initList();
    }
    
    //初始化顺序表
    public void initList(){
        myList=(AnyType[])new Object[AMOUNT];
        index=0;
    }
    
    //判断顺序表是否为空
    public boolean listEmpty(){
        if(index==0){
            return true;
        }
        return true;
    }
    
    //清空顺序表
    public boolean clearList(){
        myList=null;
        index=0;
        return true;
    }
    
    //返回i位置的元素
    public AnyType get(int i){
        if(i<0||i>=index){
            throw  new ArrayIndexOutOfBoundsException();
        }
        return myList[i];
    }
    
    //在i位置加入元素,即插入操作,这里我没有用insert命名
    public void add(int i,AnyType a){
        if(i<0||i>index){
            throw new ArrayIndexOutOfBoundsException();
        }
        if (i==index){
            largeList();
        }
        for(int k=index;k>i;k--){
            myList[k]=myList[k-1];
        }
        myList[i]=a;
        index++;
    }
    
    //在结尾增添元素a
    public void add(AnyType a){
        add(index,a);
    }
    
    //为i位置元素重新赋值
    public AnyType set(AnyType a,int i){
        if(i<0||i>=index){
            throw new ArrayIndexOutOfBoundsException();
        }
        AnyType old=myList[i];
        myList[i]=a;
        return old;
    }
    
    //打印遍历顺序表
    public void print(){
        String s="[";
        for(int i=0;i<index;i++){
            s=s+myList[i];
            s=s+" ,";
        }
        System.out.println(s);
    }
    
    //查找a元素是否在表中,返回位置,没有返回0
    public int locateElem(AnyType a){
        for(int i=0;i<index;i++){
            if(a==myList[i]){
                return i+1;
            }
        }
        return 0;
    }
    
    //返回表长
    public int length(){
        return index;
    }
    
    //删除i位置元素
    public AnyType delete(int i){
        if(i<0||i>=index){
            throw new ArrayIndexOutOfBoundsException();
        }
        AnyType old=myList[i];
        for(int k=i;k<index;k++){
            myList[k]=myList[k+1];
        }
        index--;
        return old;
    }
    
    //扩大表的最大长度
    public void largeList(){
        AnyType[] newList=(AnyType[])new Object[2*length()+1];
        for(int i=0;i<index;i++){
            newList[i]=myList[i];
        }
        myList=newList;
    }

}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK