• (java实现)顺序表-ArrayList


    什么是顺序表

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

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

    基本操作

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

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

    顺序表删除元素

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

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

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

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

    顺序表插入元素

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

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

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

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

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

    时间复杂度分析同删除元素一样,均为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;
        }
    
    }
    
    花五年时间成为某个领域的专家
  • 相关阅读:
    关于SDK-manager中我们需要下载哪些?
    不只是撸代码搞鸡汤,也有故事!
    [Selenium]如何通过Selenium实现Ctrl+click,即按住Ctrl的同时进行单击操作
    【设计模式】单例模式
    【Java多线程】线程池学习
    【leetcode】147 Insertion Sort List
    【webssh】shellinabox搭建
    【SpringMVC】一次处理项目中文乱码的经历
    【Java多线程】JUC包下的工具类CountDownLatch、CyclicBarrier和Semaphore
    【leetcode】3 SUM
  • 原文地址:https://www.cnblogs.com/sang-bit/p/11601482.html
Copyright © 2020-2023  润新知