java數據結構——1數組

一、數組

數組是應用最廣泛的數據存儲結構,它被植入到大部分編程語言中。由於數組十分易懂,所以它被用來介紹數據結構的起點。 數組分爲2種:無序數組與有序數組。有序數組就是無序數組經過排序後結果。另外數組需要有以下這些要求:

1. 我們通常假設數組中是沒有空洞的。

當我們想在數組查找某個元素時,當所有元素都查過了之後,依然沒有查到,就說明數組中不包含此元素。那麼我們如何知道所有的元素都已經查過了呢?按照規則1,只要我們保證數組所有非空元素,都排在數組的前面,那麼當我們遇到第一個空元素時,就說明所有的元素都查找完了。

2. 當刪除數組中一個元素時,這個數組中之後所有的元素位置都會前移一個位置。

例如我們刪除了第二個元素,在java中,就是移除數組對這個對象的引用,只要將對應位置設爲null即可,但是在這裏我們卻不能這樣做,因爲根據規則1,我們查找的時候,遇到第一個爲null的元素的時候,就認爲所有的元素都查找完了,例如現在查找5,那麼就會查不到,因此刪除必須將後面所有的元素都前移一個位置。

3. 如果是無序數組的話,添加一個元素時,總是添加到數組的最後位置。

插入操作同樣要滿足,插入後,數組中依然不能存在空洞,否則查找依然會出現問題,例如現在還有2個位置可以插入,如果我們插入在最後一個位置上,根據規則1,之後在查找的時候又找不到這個元素了。

4. 如果是有序數組的話,添加元素到某個位置時,當前位置的元素與之後的元素都要往後移動一個位置。

在查找的時候,如果有相同的元素,那麼可能會有多個匹配值,那麼到底返回哪個呢?還是全部都返回?爲了方便,我們通常假設數組中沒有相同的元素,因此只需要返回第一個匹配上的值即可。

下面是代碼實現:

public class Array<V> {
    private Object[] elements;
    private int size = 0;//數組元素的數量
    private int capacity;//數組的容量
    /**
     * 數組容量
     */
    public Array(int capacity){
        this.capacity = capacity;
        if (capacity <= 0) {
            throw new IllegalArgumentException("數組容量必須大於0");
        }
        elements = new Object[capacity];
    }
    /**
     * 插入元素
     */
    public void insert(V v){
        if (size == capacity -1) {//達到容量限制
            throw new IndexOutOfBoundsException("數組已達到最大容量");
        }
        elements[size++] = v;
    }
    /**
     * 刪除元素
     */
    public boolean remove(V v){
        for (int i = 0; i < size; i++){
            if (elements[i].equals(v)) {
                elements[i] = null;//刪除
                moveUp(i);
                size--;//元素數量-1
                return true;
            }
        }
        return false;
    }
    /**
     * 查找元素
     */
    public V find(V v){
        for (int i = 0; i < size; i++){
            if (elements[i].equals(v)) {
                return (V)elements[i];
            }
        }
        return null;
    }
    /**
     * 返回指定index的元素
     */
    public V get(int index){
        if (index > capacity - 1) {
            throw new IndexOutOfBoundsException("指定的索引超過數組容量");
        }
        return (V)elements[index];//null能強轉嗎
    }
    /**
     * 返回數組元素個數
     */
    public int size(){
        return size;
    }
    /**
     * 顯示所有元素
     */
    public void showAll(){
        for (int i = 0; i< elements.length; i++){
            if (i < size) {
                System.out.print(elements[i] + "  ");
            }else {
                System.out.print("null" + "  ");
            }
        }
        System.out.println();
    }

    /** 
     * 刪除元素後將所有元素都向前移動一位 
     */ 
    private void moveUp(int i) {
        while (i < size -1) {
            elements[i] = elements[++i];
        }
        elements[size -1] = null;
    }
}

在數據結構與算法中,衡量算法的效率是通過時間複雜度和空間複雜度來進行的,下面是一個簡單的介紹:

  • 操作 ———————— 時間複雜度
  • 插入 ———————— O(1)
  • 刪除 ———————— O(n)
  • 查找 ———————— O(n)

其中:

O(1)表示,此操作不受數組元素個數的影響,不論數組中現有多少元素,插入操作總是1步就可以完成。

O(N)表示此操作受到數據元素個數的影響,最直觀的感受是,我們可以看到刪除和查找操作,裏面都有一個for循環來迭代數組中的所有元素,假設數組中有N個元素,我們隨機查找或者刪除一個數字,運氣好的情況下,可能1次就查找了,運氣不好,可能所有的N個元素迭代完了,還是沒有找到,根據概率,平均可能需要進行N/2次循環,由於時間複雜度是忽略常數的,因此刪除和查找操作的平均時間複雜度是O(N)。

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