1. 程式人生 > >資料結構(二)——線性結構之陣列

資料結構(二)——線性結構之陣列

一.陣列

1.陣列是典型的順序儲存結構。

2.陣列的基本使用

(1)建立一個數組

// 建立一個數組--三種方式
// 第一種:只指定陣列大小,不賦值。如果沒有賦值,每個元素都是0
int a[] = new int[3];
// 第二種和第三種,建立陣列的同時賦值
int b[] = {1, 2, 3, 4};
int c[] = new int[]{7, 8, 9};

(2)陣列的長度

// 陣列的長度(一共可以放多少元素)
int aLength = a.length;

(3)獲取陣列中的元素

// 獲取陣列中的元素,使用方式:陣列名[下標] 下標從0開始,最大可以取到(陣列的長度-1)
int a0 = a[0];

(4)陣列元素賦值 

// 陣列元素賦值
a[0] = 111;

(5)遍歷陣列

// 遍歷陣列
for (int i = 0; i < b.length; i++) {
    System.out.println(b[i]);
}

 (6)快速檢視陣列中的元素

// 快速檢視陣列中的元素
System.out.println(Arrays.toString(a));

(7)增加陣列元素

package cn.kimtian.array.one;

import java.util.Arrays;

/**
 * 由於陣列的長度是不可變的,那麼想為陣列增加元素就需要進行:
 * 1.新建另一個數組
 * 2.把原陣列中的元素複製到新陣列中
 * 3.把新增加的元素加入新陣列的最後
 * 4.使用新陣列替換原有陣列
 *
 * @author kimtian
 */
public class OptionArrayAdd {
    public static void main(String[] args) {
        /**
         * 陣列的長度是不可變的,如下面就指定了陣列a的長度為5
         */
        int a[] = new int[]{1, 2, 3, 4, 5};
        // 快速檢視陣列中的元素
        System.out.println("原來的陣列:" + Arrays.toString(a));
        //要新加的元素
        int addNum = 9;

        // 建立一個新的陣列,長度是原陣列長度+1
        int newA[] = new int[a.length + 1];
        // 把原陣列中的元素複製到新陣列中
        for (int i = 0; i < a.length; i++) {
            newA[i] = a[i];
        }
        // 把目標元素放入新陣列的最後
        newA[newA.length - 1] = addNum;
        // 新陣列替換原資料
        a = newA;
        System.out.println("現在的陣列:" + Arrays.toString(a));
    }
}

(8)刪除陣列元素

package cn.kimtian.array.one;

import java.util.Arrays;

/**
 * 由於陣列的長度是不可變的,那麼想為陣列刪除元素就需要進行:
 * 1.新建另一個數組
 * 2.把原陣列中的不需要刪除的元素複製到新陣列中
 * 3.使用新陣列替換原有陣列
 *
 * @author kimtian
 */
public class OptionArrayDelete {
    public static void main(String[] args) {
        /**
         * 陣列的長度是不可變的,如下面就指定了陣列a的長度為5
         */
        int[] a = new int[]{1, 2, 3, 4, 5, 7, 9};
        // 快速檢視陣列中的元素
        System.out.println("原來的陣列:" + Arrays.toString(a));
        //要刪除的元素的下標
        int deleteNum = 2;

        // 建立一個新的陣列,長度是原陣列長度-1
        int[] newA = new int[a.length - 1];
        // 把原陣列中的除了要刪除的元素的其他元素複製到新陣列中
        for (int i = 0; i < newA.length; i++) {
            //當前遍歷下標小於要刪除元素的下標
            if (i < deleteNum) {
                newA[i] = a[i];
            }
            // 要刪除的元素之後的元素
            else {
                newA[i] = a[i + 1];
            }
        }
        // 新陣列替換原資料
        a = newA;
        System.out.println("現在的陣列:" + Arrays.toString(a));
    }
}

3.查詢演算法

(1)線性查詢

         按陣列順序,將每一個元素對比一次,直到查詢到目標元素。

/**
 * 這是陣列的線性查詢
 *
 * @author kimtian
 */
public class TestLinearSearch {
    public static void main(String[] args) {
        //目標陣列
        int[] arrOne = new int[]{1, 2, 3, 4, 5, 6};
        //目標元素
        int targetNum = 5;
        //目標元素所在的下標
        int index = -1;
        //遍歷陣列
        for (int i = 0; i < arrOne.length; i++) {
            if (arrOne[i] == targetNum) {
                index = i;
                //找到則停止,不繼續迴圈
                break;
            }
        }
        System.out.println("目標元素所在下標為:" + index);

    }
}

(2)二分法查詢

          將陣列一分為二,比較最中間的數,判斷大小,在選擇左部分和右部分,再依此迴圈查詢,直到找到為止。

          要求陣列必須是有序的。

          參見一個二分法的實際應用例子。

/**
 * 這是陣列的二分查詢
 *
 * @author kimtian
 */
public class TestDichotomySearch {
    public static void main(String[] args) {
        //目標陣列
        int[] arrTwo = new int[]{1, 2, 3, 4, 5, 6, 10, 23, 45, 67};
        //目標元素
        int targetNum = 10;
        //記錄開始位置
        int begin = 0;
        //記錄結束位置
        int end = arrTwo.length - 1;
        //記錄中間位置
        int mid = (begin + end) / 2;
        //記錄目標位置
        int index = -1;
        //迴圈查詢
        while (true) {
            //判斷中間的元素是不是要查詢的元素
            if (arrTwo[mid] == targetNum) {
                index = mid;
                break;
            }
            //中間這個元素不是要查的元素
            else {
                // 判斷中間這個元素是不是比目標元素大
                if (arrTwo[mid] > targetNum) {
                    end = mid - 1;
                } else {
                    begin = mid + 1;
                }
                mid = (begin + end) / 2;
            }
        }
        System.out.println("目標元素所在下標為:" + index);
    }
}

4.面向物件的陣列

建立一個面向物件的陣列,並對其封裝了以下操作。

(1)獲取陣列長度;

(2)往陣列新增元素;

(3)列印所有元素到控制檯;

(4)刪除陣列中的元素;

(5)往陣列中插入元素到指定位置;

(6)獲取某個下標的元素;

(7)替換指定位置的元素;

(8)線性查詢;

(9)二分法查詢。

package cn.kimtian.array.one;

import java.util.Arrays;

/**
 * 建立一個面向物件的可見陣列
 * 並對其進行操作
 *
 * @author kimtian
 */
public class MyArray {
    /**
     * 目標陣列,用於儲存資料的陣列
     **/
    private int[] elements;

    public MyArray() {
        elements = new int[0];
    }

    /**
     * /獲取陣列長度的方法
     *
     * @return int 陣列的長度
     */
    public int size() {
        return elements.length;
    }

    /**
     * 往陣列的末尾新增一個元素
     *
     * @param element 要新增的元素
     */
    public void add(int element) {
        // 建立一個新的陣列
        int[] newArr = new int[elements.length + 1];
        // 把原陣列中的元素複製到新的陣列中
        for (int i = 0; i < elements.length; i++) {
            newArr[i] = elements[i];
        }
        // 把新增的元素放入新陣列中
        newArr[elements.length] = element;
        // 使用新陣列替換老陣列
        elements = newArr;
    }

    /**
     * 列印所有元素到控制檯
     */
    public void printToConsole() {
        System.out.println(Arrays.toString(elements));
    }

    /**
     * 刪除陣列中的元素
     *
     * @param index 刪除的下標
     */
    public void delete(int index) {
        //如果下標<0,或者大於最大邊界了(最大的下標為陣列的長度-1)
        if (index < 0 || index > elements.length - 1) {
            throw new RuntimeException("下標越界");
        }
        // 建立一個新的陣列
        int[] newArr = new int[elements.length - 1];
        // 把原陣列中的元素複製到新的陣列中
        for (int i = 0; i < newArr.length; i++) {
            //當前遍歷下標小於要刪除元素的下標
            if (i < index) {
                newArr[i] = elements[i];
            }
            // 要刪除的元素之後的元素
            else {
                newArr[i] = elements[i + 1];
            }
        }
        // 使用新陣列替換老陣列
        elements = newArr;
    }

    /**
     * 往陣列中插入元素到指定位置
     *
     * @param index   插入的位置
     * @param element 插入的值
     */
    public void insert(int element, int index) {
        //如果下標<0,或者大於最大邊界了(最大的下標為陣列的長度-1)
        if (index < 0 || index > elements.length) {
            throw new RuntimeException("下標越界");
        }
        // 建立一個新的陣列
        int[] newArr = new int[elements.length + 1];
        // 把原陣列中的元素複製到新的陣列中
        for (int i = 0; i < elements.length + 1; i++) {
            // 目標位置之前的元素
            if (i < index) {
                newArr[i] = elements[i];
            }
            //目標位置的元素
            else if (i == index) {
                newArr[i] = element;
            }// 目標位置之後的元素
            else {
                newArr[i] = elements[i - 1];
            }
        }
        // 使用新陣列替換老陣列
        elements = newArr;
    }

    /**
     * 獲取某個下標的元素
     *
     * @param index 下標數
     */
    public int get(int index) {
        if (index < 0 || index > elements.length - 1) {
            throw new RuntimeException("下標越界");
        } else {
            return elements[index];
        }
    }

    /**
     * 替換指定位置的元素
     *
     * @param element 替換值
     * @param index   下標數
     */
    public void setIndexElement(int index, int element) {
        // 判斷下標是否合法
        if (index < 0 || index > elements.length - 1) {
            throw new RuntimeException("下標越界");
        }
        elements[index] = element;
    }

    /**
     * 線性查詢
     *
     * @param target 要查詢的目標數字
     */
    public int linesrSearch(int target) {
        //遍歷陣列
        for (int i = 0; i < elements.length; i++) {
            if (elements[i] == target) {
                return i;
            }
        }
        return -1;
    }

    /**
     * 二分法查詢
     *
     * @param target 要查詢的目標數字
     */
    public int dichotomySearch(int target) {
        //記錄開始位置
        int begin = 0;
        //記錄結束位置
        int end = elements.length - 1;
        //記錄中間位置
        int mid = (begin + end) / 2;
        //迴圈查詢
        while (true) {
            //如果開始和結束元素相等,且不等於目標元素,則結束迴圈
            if (begin == end && begin != target) {
                return -1;
            }
            //判斷中間的元素是不是要查詢的元素
            if (elements[mid] == target) {
                return mid;
            }
            //中間這個元素不是要查的元素
            else {
                // 判斷中間這個元素是不是比目標元素大
                if (elements[mid] > target) {
                    end = mid - 1;
                } else {
                    begin = mid + 1;
                }
                mid = (begin + end) / 2;
            }
        }
    }
}