<数据结构基础学习>(一)数组

一.数组基础

        1.数组,即把数据码成一排存放。

        数组优点:快速查询。

        数组最好应用于“索引有语意”的情况,但并非所有有语意的索引都适用于数组,数组也可以处理“索引没有语意”的情况。

  2.增、删、改、查,是研究数据结构的基本脉络。

  设二次封装的数组的类Array<E>(类型为E,泛型),E[ ] data 基本参数有capacity和size。

  capacity为数组空间最多装的元素个数,即data.length。

  size为数组实际装的元素个数。

  有些方法需要对size进行维护。

二. 动态数组常见方法

1.基础方法

  1)方法1:有参构造函数设置动态数组的capacity

  java不支持data = new E[capacity],需写为data=(E[])new Object[capacity]

  2)方法2:无参构造函数默认数组的capacity为10

  3)方法3:获取数组元素个数  即size 

  4)方法4:获取数组的容量      即capacity,data.length

   5)方法5:返回数组是否为空 即判断size是否为0

    
public class Array<E> {

private E[] data; private int size; //构造函数,传入数组的容量capacity构造Array public Array(int capacity){ data = (E[]) new Object[capacity]; size = 0; } //无参数的构造函数,默认的数组容量capacity=10 public Array(){ this(10); } //获取数组中的元素个数 public int getSize(){ return size; } //获取数组的容量 public int getCapacity(){ return data.length; } //返回数组是否为空 public boolean isEmpty(){ return size == 0; }
}

2.增(插入元素)

1)方法1:在index位置插入元素

add(int index, E e)

a.先判断index是否合法,若index<0||index>size,则抛出异常

b.若index == data.length,此时需要调用resize()方法对数组进行扩容(扩容为2*capacity)

   private void resize(int newCapacity){
        E[] newData = (E[]) new Object[newCapacity];
        for(int i = 0 ; i < size ; i ++){
            newData[i] = data[i];
        }
        data = newData;
    }

resize()方法思想即创建一个容量为newCapacity的新数组newData,通过将data中的每个元素依次赋值给newData,最后令data=newData。

c.在指定位置插入元素的思想,即为从最后一位(size-1)开始,开始循环将元素向后挪一位(data[i+1]=data[i]),直到index的位置。

然后令data[index]=e,

最后,维护size,即size++

2)方法2:向所有元素后添加元素   

addLast(E e)  即add(size, e)

3)方法3:向首位值添加元素

addFirst(E e)  即add(0, e)

   //向所有元素后添加元素
    public void addLast(E e){
        add(size, e);
    }
    //向首位指添加元素
    public void addFirst(E e){
        add(0,e);
    }

    // important  index位置插入元素e
    public void add(int index, E e){


        if( index < 0 || index > size){
            throw new IllegalArgumentException("AddLast failed. Require index < 0 || index > size");
        }

        if(size == data.length){
            resize(2 * data.length);
        }

        for(int i = size - 1 ; i >= index ; i -- ){
            data[ i + 1 ] = data[i];
        }

        data[index] = e;
        size ++;
    }

3.查(查询元素)

1)方法1:获取index索引位置的元素

get(int index)

a.先判断index是否合法,若index<0||index>=size,则抛出异常

b.返回data[index]

2)方法2:查找数组中是否有元素e

contains(E e)

循环查找,若有data[i].equals(e),则返回true,否则返回false。(java中判断类对象的值是否相等采用.equals()方法)

3)方法3:查找元素e所在的索引index,若元素不存在,则返回-1

find(E e)

循环查找,若有data[i].equals(e),则返回i,否则返回-1

//获取index索引位置的元素
    E get(int index){
        if(index < 0 || index >= size){
            throw new IllegalArgumentException("Get failed. Index is illegal");
        }
        return data[index];
    }
//查找数组中是否有元素e
    public boolean contains(E e){
        for(int i = 0 ; i < size; i ++){
            if(data[i].equals(e))
                return true;
        }
        return false;
    }

    //查找数组中元素e所在的索引,如果不存在元素e,则返回-1
    public int find(E e){
        for(int i = 0 ; i < size ; i ++){
            if(data[i].equals(e)){
                return i;
            }
        }
        return -1;
    }

4.删(删除元素)

1)方法1:从数组中删除index位置的元素,并返回删除的元素

remove(int index)

a.先判断index是否合法,若index<0||index>=size,则抛出异常。

b.定义ret=data[index],作为返回值。

c.开始删除操作,即从i=index位置开始,循环地使data[i]=data[i+1],即将下一位元素覆盖到当前元素中,直到size-1。

d.维护size,即 size --。

e.(非必需)但此时data[size]还是存在用不到的数的,可以进行data[size]=null的操作来避免空间浪费。

f.判断当前size==data.length/2,如果为true,则进行缩容,调用resize()方法,使capacity=data.length/2,避免空间浪费。

g.返回ret,即删除的元素。

2)方法2:删除首个位置的元素并返回该元素 

remove(0)

3)方法3:删除末尾位置的元素并返回该元素 

remove(size)

4)方法4:直接从数组中删除元素e

emoveElement(E e)方法

先通过find()方法寻找e的index,若存在则返回e的index,不存在则返回-1,当index不为-1时,remove(index)

    //从数组中删除index位置的元素,并返回删除的元素
    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 ; i < size - 1 ; i ++){
            data[i] = data[i + 1];
        }
        size --;
        data[size] = null;  //loitering objects != memory leak is Better

        if(size == data.length/2 )
            resize(data.length/2);
        return ret;
    }

    //删除首个位置的元素
    public E removeFirst(){
        return remove(0);
    }

    //删除最后一个元素
    public  E removeLast(){
        return remove(size - 1);
    }

    //从数组中删除元素e
    public void removeElement(E e){
        int index = find(e);
        if(index != -1)
            remove(index);
    }

5.改(重置数组中的元素)

set(int index, E e)

a.先判断index是否合法,若index<0||index>=size,则抛出异常。

b.令data[index] = e

   //修改index索引位置的元素e
    void set(int index, E e){
        if(index < 0 || index >=size){
            throw new IllegalArgumentException("Set failed. Index is illegal");
        }

        data[index] = e;
    }

6.重写toString()方法,让输出更具有可读性

    @Override
    public String toString() {
        StringBuilder res = new StringBuilder();
        res.append(String.format("Array: size = %d , capacity = %d
", 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();
    }

 

原文地址:https://www.cnblogs.com/HarSong13/p/10651668.html