數據結構(1):使用面向對象模擬數組

數組是一種常用的數據結構,數組具有不可變性,創建後的數組的長度固定,通過索引訪問數組中的元素,訪問速度快,刪除添加效率低。

通過面向對象模擬數組,模擬的數組具有以下功能:

  1. 添加新元素
  2. 展示
  3. 查找元素所在位置
  4. 根據索引獲取元素
  5. 根據索引刪除元素
  6. 修改指定位置的元素

同時使用兩個算法對數組進行操作:

  1. 有序添加元素
  2. 二分查找法

1.創建數組類 MyArray.java

數據如何存儲呢?在類中添加一個數組類型的私有屬性用來保存數據,同時添加一個變量存儲有效數據的長度(也就是元素的個數)

創建數組的時候需要指定數組的長度,所以要添加兩個構造方法:

1.無參構造方法設置數組默認長度
2.有參構造方法指定數組長度

public class MyArray {
    //存儲元素
    private long[] arr;
    //表示有效數據的長度
    private int elements;

    //無參構造默認50個長度
    public MyArray() {
        arr=new long[50];
    }

    public MyArray(int maxsize) {
        arr=new long[maxsize];
    }
}

2.編寫添加數據的方法

elements 屬性的默認值是 0,第一次向對象中添加元素也是添加到索引爲0 的元素中,添加後將 elements 的長度加1,就能一直向數組中添加元素了,添加元素的個數取決於 arr 的長度。

public void insert(long value) {
    arr[elements]=value;
    elements++;
}

3.編寫展示數據的方法

簡單的展示數組中的元素即可,使用 for 循環遍歷

public void display() {
    System.out.print("[");
    for (int i = 0; i < elements; i++) {
        System.out.print(arr[i]+" ");
    }
    System.out.println("]");
}

4.編寫查找數據的方法

思路:使用循環遍歷數組 arr ,將要查找的數據和 arr 中每個元素進行比較。如果相等,則跳出循環。循環結束後,如果循環次數等於元素個數說明沒有找到數據,返回-1。否則返回循環次數(即找到的索引)。

public int search(long value) {
    int i ;
    for (i = 0; i < elements; i++) {
        if(value==arr[i]) {
            break;
        }
    }
    //遍歷到末尾說明沒有找到
    if (i==elements) {
        return -1;
    }else {
        return i;
    }
}

5.根據索引獲取元素

思路:這相對比較簡單了,直接給 arr 索引就能獲取到元素。但是要注意傳入的索引必須可用,不能用的索引可以拋出異常。

public long get(int index) {
    //如果索引大於可用,或索引小於0 都是無效的索引
    if (index>=elements||index<0) {
        //拋出數組越界異常
        throw new ArrayIndexOutOfBoundsException();
    }else {
        return arr[index];
    }
}

6.根據索引刪除元素

思路:和獲取元素時一樣,先檢查索引是否可用。如果可用,就從要刪除元素的位置開始向後遍歷,每次都將下一個元素的值賦值給當前元素。也就相當於要刪除的元素被下一個元素覆蓋,下一個元素被下下一個元素覆蓋,以此類推。元素移動完成後,將可用元素長度 elements 減1。

public void delete(int index) {
    //如果索引大於可用,或索引小於0 都是無效的索引
    if (index>=elements||index<0) {
        throw new ArrayIndexOutOfBoundsException();
    }else {
        for(int i=index;i<elements;i++) {
            arr[index]=arr[i+1];
        }
        elements--;
    }
}

7.修改指定位置的元素

思路:和獲取差不多,就是把獲取改爲修改

public void change(int index,int newValue) {
    //如果索引大於可用,或索引小於0 都是無效的索引
    if (index>=elements||index<0) {
        throw new ArrayIndexOutOfBoundsException();
    }else {
        arr[index]=newValue;
    }
}

8.完整代碼

public class MyArray {
    private long[] arr;
    //表示有效數據的長度
    private int elements;

    public MyArray() {
        arr=new long[50];
    }

    public MyArray(int maxsize) {
        arr=new long[maxsize];
    }

    /**
     * 添加數據
     * @param value
     */
    public void insert(long value) {
        arr[elements]=value;
        elements++;
    }

    /**
     * 顯示數據
     */
    public void display() {
        System.out.print("[");
        for (int i = 0; i < elements; i++) {
            System.out.print(arr[i]+" ");
        }
        System.out.println("]");
    }

    /**
     * 查找數據
     */
    public int search(long value) {
        int i ;
        for (i = 0; i < elements; i++) {
            if(value==arr[i]) {
                break;
            }
        }
        //遍歷到末尾說明沒有找到
        if (i==elements) {
            return -1;
        }else {
            return i;
        }
    }

    /**
     * 查找數據,根據索引來查
     */
    public long get(int index) {
        //如果索引大於可用,或索引小於0 都是無效的索引
        if (index>=elements||index<0) {
            throw new ArrayIndexOutOfBoundsException();
        }else {
            return arr[index];
        }
    }

    /**
     * 刪除數據 
     */
    public void delete(int index) {
        //如果索引大於可用,或索引小於0 都是無效的索引
        if (index>=elements||index<0) {
            throw new ArrayIndexOutOfBoundsException();
        }else {
            for(int i=index;i<elements;i++) {
                arr[index]=arr[i+1];
            }
            elements--;
        }
    }

    /**
     * 更新數據
     */
    public void change(int index,int newValue) {
        //如果索引大於可用,或索引小於0 都是無效的索引
        if (index>=elements||index<0) {
            throw new ArrayIndexOutOfBoundsException();
        }else {
            arr[index]=newValue;
        }
    }
}

9.有序添加元素

思路:修改 insert 方法,遍歷 arr 數組,如果當前元素大於添加的數據,當前的位置就要存入的位置。從最後一個元素開始,逐個將元素向後位移,空出要存入的位置。存入要添加的元素後,將有效數據長度加1。

public void insert(long value) {
    int i;
    for(i=0;i<elements;i++) {
        if(arr[i]>value) {
            break;
        }
    }
    for (int j = elements; j > i; j--) {
        arr[j]=arr[j-1];
    }
    arr[i]=value;
    
    elements++;
}

10.二分查找法

思路:數據必須是有序的,才能使用二分查找法!可以結合有序添加元素一塊使用,這裏的序列是升序(從小到大)。二分查找是每次和一組數中間的數進行比較,如果大於就再和右邊的數最中間的數比較,如果小於就和左邊的數最中間的數比較。直到中間的數和要查找的數相等,否則就是沒有這個數。

public int binarySearch(long value) {
    int mid=0;//中間值
    int low=0;
    int high = elements;
    
    while(true) {
        mid=(high+low)/2;
        if(arr[mid]==value) {
            return mid;
        }else if(low>high) {
            return -1;
        }else {
            if (value>arr[mid]) {
                high=mid+1;
            }else {
                high=mid-1;
            }
        }
    }
    
}

二分查找法圖示

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章