2

这篇文章是展示如何使用JAVA语言实现Array这种数据结构。

​1.整型数组的实现

public class Array {
    private int[] data;
    private int size;
    /**
     * 构造函数,传入数组的容量 capacity 构造 Array
     * @param capacity
     */
    public Array(int capacity){
        data = new int[capacity];
        size = 0;
    }
    /**
     * 无参数的构造函数,默认数组的容量 capacity = 10
     */
    public Array(){
        this(10);
    }
    /**
     * 获取数组大小
     * @return
     */
    public int getSize(){
        return size;
    }
    /**
     * 获取数组容量
     * @return
     */
    public int getCapacity(){
        return data.length;
    }
    /**
     * 返回数组是否为空
     * @return
     */
    public boolean isEmpty(){
        return size == 0;
    }
    /**
     * 向数组末尾添加元素
     * @param num
     */
    public void addLast(int num){
        addIndex(size,num);
    }
    /**
     * 向数组开头添加元素
     * @param num
     */
    public void addFirst(int num){
        addIndex(0,num);
    }
    /**
     * 向数组指定位置添加元素
     */
    public void addIndex(int index,int num){
        if(size == data.length || index > size || index < 0)
            throw new IllegalArgumentException("容量满了或索引位置超出范围");
        for(int i = size - 1;i >= index;i--){
            data[i+1] = data[i];
        }
        data[index] = num;
        size++;
    }
    /**
     * 获取数组中元素
     * @param index
     * @return
     */
    public int getIndex(int index){
        if(index < 0 || index > size - 1)
            throw new IllegalArgumentException("索引超出范围");
        return data[index];
    }
    /**
     * 判断数组中是否存在某个元素
     * @param num
     * @return
     */
    public boolean isset(int num){
        for (int i = 0;i < size;i++){
            if(data[i] == num)
                return true;
        }
        return false;
    }
    /**
     * 查找数组中某个值第一次出现的索引
     * @param num
     * @return
     */
    public int find(int num){
        for(int i = 0;i < size;i++){
            if(data[i] == num)
                return i;
        }
        return -1;
    }
    public void findAll(int num){
        int n = 0; //统计data 数组中的 num 的个数
        for (int i = 0;i < size;i++){
            if (data[i] == num)
                n++;
        }
        for (int k = 0;k < n;k++){
            int index = find(num);
           unset(index);
        }
    }
    /**
     * 删除指定位置的元素
     * @param index
     */
    public int unset(int index){
        if(index < 0 || index > size - 1){
            throw new IllegalArgumentException("索引超出范围");
        }
        int res = data[index];
        for(int i = index;i < size;i++){
            data[i] = data[i+1];
        }
        size--;
        return res;
    }
    /**
     * 删除数组中第一个元素
     * @return
     */
    public int unsetFirst(){
      return unset(0);
    }
    /**
     * 删除数组中最后一个元素
     * @return
     */
    public int unsetLast(){
        return unset(size-1);
    }
    /**
     * 删除数组中某个值
     * @param num
     */
    public void filterNum(int num){
        int index = find(num);
        unset(index);
    }
    public void filterAllNum(){
    }
    /**
     * 获取数组信息
     * @return
     */
    @Override
    public String toString(){
        StringBuilder res = new StringBuilder();
        res.append(String.format("Array:size = %d,capacity = %dn",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();
    }
}

2.泛型数组的实现

public class Array<genarr> {
    private genarr[] data;
    private int size;
    /**
     * 构造函数,传入数组的容量 capacity 构造 Arrayaa
     *
     * @param capacity
     */
    public Array(int capacity) {
        data = (genarr[]) new Object[capacity];
        size = 0;
    }
    /**
     * 无参数的构造函数,默认数组的容量 capacity = 10
     */
    public Array() {
        this(10);
    }
    /**
     * 获取数组大小
     *
     * @return
     */
    public int getSize() {
        return size;
    }
    /**
     * 获取数组容量
     *
     * @return
     */
    public int getCapacity() {
        return data.length;
    }
    /**
     * 返回数组是否为空
     *
     * @return
     */
    public boolean isEmpty() {
        return size == 0;
    }
    /**
     * 向数组末尾添加元素
     *
     * @param num
     */
    public void addLast(genarr num) {
        addIndex(size, num);
    }
    /**
     * 向数组开头添加元素
     *
     * @param num
     */
    public void addFirst(genarr num) {
        addIndex(0, num);
    }
    /**
     * 向数组指定位置添加元素
     */
    public void addIndex(int index, genarr num) {
        if (index > size || index < 0)
            throw new IllegalArgumentException("容量满了或索引位置超出范围");
        if (size == data.length)
            resize(2 * data.length);
        for (int i = size - 1; i >= index; i--) {
            data[i + 1] = data[i];
        }
        data[index] = num;
        size++;
    }
    private void resize(int newCapacity) {
        genarr[] newData = (genarr[]) new Object[newCapacity];
        for(int i=0;i < size;i++)
            newData[i] = data[i];
        data = newData;
    }
    /**
     * 获取数组中元素
     *
     * @param index
     * @return
     */
    public genarr getIndex(int index) {
        if (index < 0 || index > size - 1)
            throw new IllegalArgumentException("索引超出范围");
        return data[index];
    }
    public genarr getLast(){
        return getIndex(size - 1);
    }
    /**
     * 判断数组中是否存在某个元素
     *
     * @param num
     * @return
     */
    public boolean isset(genarr num) {
        for (int i = 0; i < size; i++) {
            if (data[i].equals(num))
                return true;
        }
        return false;
    }
    /**
     * 查找数组中某个值第一次出现的索引
     *
     * @param num
     * @return
     */
    public int find(genarr num) {
        for (int i = 0; i < size; i++) {
            if (data[i].equals(num))
                return i;
        }
        return -1;
    }
    public void findAll(genarr num) {
        int n = 0; //统计data 数组中的 num 的个数
        for (int i = 0; i < size; i++) {
            if (data[i].equals(num))
                n++;
        }
        for (int k = 0; k < n; k++) {
            int index = find(num);
            unset(index);
        }
    }
    /**
     * 删除指定位置的元素
     *
     * @param index
     */
    public genarr unset(int index) {
        if (index < 0 || index > size - 1) {
            throw new IllegalArgumentException("索引超出范围");
        }
        genarr res = data[index];
        for (int i = index; i < size - 1; i++) {
            data[i] = data[i + 1];
        }
        size--;
        data[size] = null;  //loitering objects ! =memory
        /** 若当前数组大小,小于容量的一半,则重新分配一半的数组空间大小 **/
        if(size <= data.length / 4 && data.length > 1){
            int leng;
            if(data.length % 2 == 0){
                resize(data.length / 2);
            }else{
                resize((data.length + 1) / 2);
            }
        }
        return res;
    }
    /**
     * 删除数组中第一个元素
     *
     * @return
     */
    public genarr unsetFirst() {
        return unset(0);
    }
    /**
     * 删除数组中最后一个元素
     *
     * @return
     */
    public genarr unsetLast() {
        return unset(size - 1);
    }
    /**
     * 删除数组中某个值
     *
     * @param num
     */
    public void filterNum(genarr num) {
        int index = find(num);
        unset(index);
    }
    public void filterAllNum() {
    }
    /**
     * 获取数组信息
     *
     * @return
     */
    @Override
    public String toString() {
        StringBuilder res = new StringBuilder();
        res.append(String.format("Arrayaa:size = %d,capacity = %dn", 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();
    }
}

3.Main

public class Main {
    public static void main(String[] args) {
        Array arrayStruct = new Array(10);
 arrayStruct.addLast(1);
 arrayStruct.addLast("aa");
 arrayStruct.addLast(1);
 arrayStruct.addLast("cc");
 arrayStruct.addFirst("cc");
 arrayStruct.addLast(100);
 arrayStruct.addLast("aa");
 arrayStruct.addLast("aa");
 arrayStruct.addLast("aa");
 arrayStruct.addLast("aa");
 arrayStruct.addLast("aa");
 arrayStruct.addLast("aa");
 arrayStruct.addLast("aa");
 arrayStruct.addFirst("ss");
 arrayStruct.addFirst("nn");
 arrayStruct.addFirst("mm");
 System.out.println(arrayStruct.toString());
 //打印结果 [mm,nn,ss,cc,1,aa,1,cc,100,aa,aa,aa,aa,aa,aa,aa] }
}

如下图所示:
image.png

4.简单的复杂度分析

4.1 添加操作

addLast(num)   O(1)
addFirst(num)  O(n)
addIndex(index,num)  O(n)   严格计算需要一些概率论知识
resize(size)  O(n)

4.2 删除操作

unsetLast(num)   O(1)
unsetFisrt()     O(n)
unset(index,num)   O(n/2) = O(n)
resize(size)  O(n)

4.3 查找操作

getIndex(index)    O(1)
isset(num)          O(n)
find(num)            O(n)

4.4 均摊复杂度

addLast(num)    O(1)
resize()   O(n)
上述两个组合在一起均摊在一起复杂度相当于 O(1)

4.5 防止复杂度的震荡

addLast(num)   O(1)
resize    O(n)
unsetLast(num)    O(1)
Tips:当容量满了的时候可能存在一直触发 resize() ,使得时间复杂度变为 O(n),这种情况称为复杂度震荡,解决办法是,当 size 小于等于 1/4 容量的时候才缩小容量。

代码仓库 :https://gitee.com/love-for-po...

扫码关注爱因诗贤


爱因诗贤
54 声望9 粉丝