【Java】動態數組(順序表)

Java實現一個可動態增長的數組

線性表

線性表 linear list 是n個具有相同特性的數據元素的有限序列。 線性表是一種在實際中廣泛使用的數據結構,常見的線性表:順序表、鏈表、棧、隊列、字符串…
線性表在邏輯上是線性結構,也就說是連續的一條直線。但是在物理結構上並不一定是連續的,線性表在物理上存儲時,通常以數組和鏈式結構的形式存儲。

順序表

概念及結構

順序表是用一段物理地址連續的存儲單元依次存儲數據元素的線性結構,一般情況下采用數組存儲。在數組上完成數 據的增刪查改。
順序表一般可以分爲:

靜態順序表:使用定長數組存儲。 動態順序表:使用動態開闢的數組存儲。
靜態順序表適用於確定知道需要存多少數據的場景.

靜態順序表的定長數組導致N定大了,空間開多了浪費,開少了不夠用.

接口實現

我們來實現一個動態順序表. 以下是需要支持的接口.

public class SeqList { // 打印順序表
	public void display() { }
	// 在 pos 位置新增元素
	public void add(int pos, int data) { }
	// 判定是否包含某個元素
	public boolean contains(int toFind) { return true; } // 查找某個元素對應的位置
	public int search(int toFind) { return -1; }
	// 獲取 pos 位置的元素
	public int getPos(int pos) { return -1; }
	// 給 pos 位置的元素設爲 value
	public void setPos(int pos, int value) { } //刪除第一次出現的關鍵字key
	public void remove(int toRemove) { }
	// 獲取順序表長度
	public int size() { return 0; }
	// 清空順序表
	public void clear() { }
}

實現動態數組的源碼

public class MyArray {
    int num[];
    int size;

    public MyArray(int length) {
        this.num = new int[length];
    }
    /**
     * 向動態數組中添加元素,默認向數組末尾添加
     * @param data
     */
    public void add(int data) {
        if (size == num.length) {
            num = Arrays.copyOf(num,num.length << 1);
        }
        num[size] = data;
        size ++;
    }

    /**
     * 向動態數組的任意位置插入元素
     * @param index 插入的目標索引
     * @param data
     */
    public void add(int index,int data) {
        // 判斷index是否合法
        if (index < 0 || index > size) {
            // 只要index > size 都是非法的,因爲數組無法取到數組長度的下標
            System.out.println("索引非法!");
            return;
        }
        // 數組尾插
        if (index == size) {
            add(data);
        }else {// 數組中間位置插入
            // 判斷內部數組是否滿載
            if (size == num.length) {
                //擴容
                grow();
                //num = Arrays.copyOf(num,num.length << 1);
            }
            // 將index以及之後元素向後搬移
            System.arraycopy(num,index,num,index + 1,size - index);
            num[index] = data;
            size ++;
        }
    }

    //獲取數組指定位置的值
    public int get(int index) {
        if(rangeCheck(index)) {
            return num[index];
        }
        return -1;
    }


    //修改數組指定位置的值
    public boolean set(int index,int data) {
        if(rangeCheck(index)) {
            num[index] = data;
            return true;
        }
        return false;
    }

    //刪除指定位置的值
    public boolean remove(int data) {
        for (int i = 0; i < size; i++) {
            if(num[i] == data) {
                //將找到的data值的index後的值向前移動,覆蓋data值所在位置
                System.arraycopy(num,i+1,num,i,size-i-1);
                num[size] = 0;
                size--;
                return true;
            }
        }
        return false;
    }

    //清空數組
    public void clear() {
        //將數組中的值都賦值爲0
        Arrays.fill(num,0,size,0);
    }

    // 返回動態數組長度
    public int size() {
        return size;
    }

    // 打印動態數組內容
    public void print() {
        // 數組永遠無法取到數組長度下標,因此不能等於size
        for (int i = 0; i < size; i++) {
            System.out.print(num[i] + "、");
        }
        System.out.println();
    }

    //需要有一個方法來檢驗index下標的合法性
    //由於該方法只屬於MyArray的內部調用,因此將其封裝
    private boolean rangeCheck(int index) {
        if(index < 0 || index >= size) {
            return false;
        }
        return true;
    }

    //內部數組的擴容方法
    private void grow() {
        num = Arrays.copyOf(num,num.length << 1);
    }
}

測試代碼

package MyArray;

public class Test {
    public static void main(String[] args) {
        MyArray myArray = new MyArray(3);
        //在數組末尾插入元素
        myArray.add(1);
        myArray.add(3);
        myArray.add(5);
        //在數組任意位置插入元素
        myArray.add(3,7);
        myArray.add(4,8);
        //獲取數組任意位置的值
        myArray.get(4);
        //修改數組任意位置的值
        myArray.set(3,10);

        myArray.print();
        //刪除數組某個指定位置的值
        myArray.remove(3);
        myArray.print();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章