04算法与数据结构体系课之动态数组

1. 二次封装自己的数组

基于Java的数组,二次封装属于我们自己的数组类,可以对数组进行增删改查操作。

public class Array {
    private int[] data;
    private int size;
    public Array(int capacity){
        data=new int[capacity];
        size=0;
    }
    public Array(){
        this(10);
    }
    public int getSize(){
        return size;
    }
    public int getCapacity(){
        return data.length;
    }
    public boolean isEmpty(){
        return size==0;
    }
}

2. 向数组中添加元素

实现向数组指定位置插入元素

    public void addLast(int e){
        add(size,e);
        
    }
    public void addFirst(int e){
        add(0,e);
    }
    public void add(int index,int e){
        if(size==data.length){
            throw new IllegalArgumentException("add filed,Array if full");
        }
        if(index<0||index>size){
            throw new IllegalArgumentException("add filed,Require index>=0 and index<=size");
        }
        for(int i=size;i>index;i--){
            data[i]=data[i-1];
        }
        data[index]=e;
        size++;
    }

3.查询和修改数组元素

查询数组指定位置元素和修改指定位置元素

   public int get(int index){
        if(index<0||index>=size){
            throw new IllegalArgumentException("get failed,index is illegal");
        }
        return data[index];
    }
    public void set(int index,int e){
        if(index<0||index>=size){
            throw new IllegalArgumentException("get failed,index is illegal");
        }
        data[index]=e;
    }
   


4. 搜索和删除数组元素

搜索数组是否包含某个元素,删除数组中指定位置元素或者删除数组中某个元素

    public boolean contains(int e){
        for(int i=0;i<size;i++){
            if(data[i]==e){
                return true;
            }
        }
        return false;
    }
    public int find(int e){
        for(int i=0;i<size;i++){
            if(data[i]==e){
                return i;
            }
        }
        return -1;

    }
    public int remove(int index){
        if(index<0||index>=size){
            throw new IllegalArgumentException("remove failed,index is illegal");
        }
        int ret=data[index];
        for(int i=index+1;i<size;i++ ){
            data[i-1]=data[i];
        }
        size--;
        return ret;
    }
    public int removeFirst(){
        return remove(0);
    }
    public int removeLast(){
        return remove(size-1);
    }
    public void removeElement(int e){
        int index=find(e);
        remove(index);
    }

5. 使用泛型

为了使我们封装的数组能支持更多的数据类型,这里我们使用泛型,具体修改后的代码如下:

public class Array<E> {
    private E[] data;
    private int size;
    public Array(int capacity){
        data=(E[]) new Object[capacity];
        size=0;
    }
    public Array(){
        this(10);
    }
    public int getSize(){
        return size;
    }
    public int getCapacity(){
        return data.length;
    }
    public boolean isEmpty(){
        return size==0;
    }
    public void addLast(E e){
        add(size,e);

    }
    public void addFirst(E e){
        add(0,e);
    }
    public void add(int index,E e){
        if(size==data.length){
            throw new IllegalArgumentException("add filed,Array if full");
        }
        if(index<0||index>size){
            throw new IllegalArgumentException("add filed,Require index>=0 and index<=size");
        }
        for(int i=size;i>index;i--){
            data[i]=data[i-1];
        }
        data[index]=e;
        size++;
    }
    public E get(int index){
        if(index<0||index>=size){
            throw new IllegalArgumentException("get failed,index is illegal");
        }
        return data[index];
    }
    public void set(int index,E e){
        if(index<0||index>=size){
            throw new IllegalArgumentException("get failed,index is illegal");
        }
        data[index]=e;
    }
    public boolean contains(E e){
        for(int i=0;i<size;i++){
            if(data[i].equals(e)){
                return true;
            }
        }
        return false;
    }
    public int find(E e){
        for(int i=0;i<size;i++){
            if(data[i].equals(e)){
                return i;
            }
        }
        return -1;

    }
    public E remove(int index){
        if(index<0||index>=size){
            throw new IllegalArgumentException("remove failed,index is illegal");
        }
        E ret=data[index];
        for(int i=index+1;i<size;i++ ){
            data[i-1]=data[i];
        }
        size--;
        data[size]=null;
        return ret;
    }
    public E removeFirst(){
        return remove(0);
    }
    public E removeLast(){
        return remove(size-1);
    }
    public void removeElement(E e){
        int index=find(e);
        remove(index);
    }
    @Override
    public String toString(){
        StringBuffer res=new StringBuffer();
        res.append(String.format("Array: szie = %d ,capacity = %d\n",size,data.length));
        res.append('[');
        for(int i=0;i<size;i++){
            res.append(data[i]);
            if(i!=size-1){
                res.append(',');
            }
        }
        res.append(']');
        return res.toString();
    }
}


5. 动态数组

我们封装的数组是基于Java的数组,所以数组的容量是不可变的,为此我们要实现一个动态数组,使得数组的容量可以动态改变,当数组满的时候,我们可以进行扩容,当数组中所存储的数据远小于数组容量时,我们可以进行缩容,具体代码如下:

    public void add(int index,E e){
        if(index<0||index>size){
            throw new IllegalArgumentException("add filed,Require index>=0 and index<=size");
        }
        if(size==data.length){
            resize(2*data.length);
        }
        for(int i=size;i>index;i--){
            data[i]=data[i-1];
        }
        data[index]=e;
        size++;
    }
    public E remove(int index){
        if(index<0||index>=size){
            throw new IllegalArgumentException("remove failed,index is illegal");
        }
        E ret=data[index];
        for(int i=index+1;i<size;i++ ){
            data[i-1]=data[i];
        }
        size--;
        data[size]=null;
        if(size==data.length/4&&data.length/2!=0){
            resize(data.length/2);
        }
        return ret;
    }
    private void resize(int newCapacity){
        E[] newData= (E[]) new Object[newCapacity];
        for(int i=0;i<size;i++){
            newData[i]=data[i];
        }
        data=newData;
    }

6. 分析动态数组的时间复杂度

  • 添加操作

    addLast(e)		O(1)
    addFirst(e)		O(n)       
    add(index,e)	O(n)
    

    总体而言动态数组的添加操作时间复杂度是O(n)

  • 删除操作

    removeLast()		O(1)
    removeFirst()		O(n)       
    remove(index,e)		O(n)
    

    总体而言动态数组的删除操作时间复杂度是O(n)

  • 修改操作

    set(index,e)		O(1)
    

    动态数组的修改操作时间复杂度是O(1)

  • 查找操作

    get(index)		O(1)
    contains(e)		O(n)       
    find(e)			O(n)
    

    总体而言动态数组的查找操作时间复杂度是O(n)

因此对于动态数组来说:添加操作和删除操作时间复杂度都是O(n),而修改操作和查找操作,在索引已知情况下时间复杂度为O(1),未知索引情况下是O(n)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值