數據結構之 數組 (附帶二分法查詢)

一、數組的簡要

Java數組對象的類是一種特殊的類,在Java內部是沒有這個類的,數組對象的類是在運行時確立的,沒有生命任何成員變量、成員方法、構造函數、Annotation甚至連length成員變量這都沒有,它就是一個徹徹底底的空類。

對數組對象取長度的時候,需用到.length,而不是一般對象的.length(),是因爲JVM在處理時對數組的長度做了特殊的處理,它是通過arraylength這條指令來實現的。

數組的典型使用案例: ArrayList 就是基於數組實現的

1、Java數組的默認初始化值

   a.基本數據類型byte,short,int,long,默認的初始化值爲0;

   b.基本數據類型float,double的默認初始值爲0.0

   c.基本數據類型char的默認初始值爲:\0000

   d.基本引用類型的默認初始值爲null

2、Java數組初始化的幾種方式

1、一種爲靜態初始化

    在創建數組的時候就指定了數組的長度,如下面的內容:

    int[] array_static=new int[]{1,2,3};

2、第二種爲動態初始化

    在創建數組的時候僅僅指定數組的長度

    int[] array_dynamic=new int[10];

3、數組的底層實現

java 的數組是一個特殊的存在,核心是一段連續的內存,數組的使用分爲四個步驟:聲明數組、分配空間、賦值、處理。

java中把內存分爲了堆內存和棧內存,當初始化數組時,堆內存分配相應大小的連續的內存塊,並將第一個內存塊的地址放入棧內存中存儲。這樣讀取數據的時候取第0個就是首地址的內存中的數據,第1個就是首地址+1的內存塊中數據。其餘刪除與寫入操作與讀取類似。

本人見解有限,更多參考:https://www.cnblogs.com/chenssy/p/3463719.html

二、數組的基本定義方式( 面向過程)

1、數組的創建方式一 (直接設置值)

        long[] arr = new long[]{2, 3, 4};
        
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }

2、數組的創建方式二 (設置數組長度)

        long[] arr2 = new long[3];
        arr2[0] = 1;
        arr2[1] = 2;
        arr2[2] = 2;
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr2[i]);
        }

3、數組的創建方式三 (二維數組)

  long[][] arr3 = new long[2][2];
        arr3[0][0] = 1;
        arr3[0][1] = 2;
        arr3[1][0] = 3;
        arr3[1][1] = 4;
        
        // 打印
        for (int i = 0; i < arr3.length; i++) {
            for (int j = 0; j < arr3[i].length; j++) {
                System.out.println("arr3[" + i + "][" + j + "] == " + arr3[i][j]);
            }
      }

上面這些就是數組的基本使用了,下面將使用對象來包裝數組,使數組獲取 增/刪/改/查 的功能

三、定義對象操作數組 ( 面向對象)

1、創建數組的包裝類

1、我們創建一個 Object[] arr 來存放任意的數組對象

2、我們創建一個 size 來數組arr 數組對象的長度,當arr 值發生變化時,可動態數組長度,等於擴容機制(此功能本爲不演示)

3、 創建構造器,XJArray() 和 XJArray(int size) ,當new 對象的所有可以獲取默認長度 或 手動設置長度

4、創建 println() 方法,方便測試和查看當前數組中存在的數據

public class XJArray {

    //數組內容
    private Object[] arr;

    //數組長度
    private int size;

    // new 對象時設置數組默認長度
    public XJArray() {
        arr = new Object[12];
    }

    // new 對象時手動數組的長度
    public XJArray(int size) {
        arr = new Object[size];
    }


    /**
     * TODO 打印數組數據,快速查看當前數組的數據,無實際用處
     */
    public void println() {
        System.out.print("[");
        for (int i = 0; i < size; i++) {
            System.out.print(arr[i] + ",");
        }
        System.out.println("]");
    }
}

使用數組對象示例

public class XJArrayTest {

    public static void main(String[] args) {
        XJArray xjArray = new XJArray();
        XJArray xjArray2 = new XJArray(16);
    }
}

數組對象創建出來了,那麼我們如何實現增刪改查呢

2、增1 (無序)

array 數組添加圖示例,無序的,傳入一個索引+1
在這裏插入圖片描述

 /**
     * TODO 添加數據
     */
    public void add(Object value) {
        arr[size] = value;
        size++;
    }

測試代碼

  xjArray.add(1);
  xjArray.add(5);
  xjArray.add(3);
  xjArray.add(2);
  xjArray.println();   //輸出  [1,5,3,2,]

3、增2 (有序)

  • 1、找到插入的索引位置
  • 2、使用 System.arraycopy 方法移動指定索引的數據位置
  • 3、添加找到的索引位置數據
    在這裏插入圖片描述
    添加方法
    /**
     * TODO 添加數據(有序的添加)
     */
    public void put(long value) {
        //
        int index = size;
        for (int i = 0; i < size; i++) {
            if (arr[i] >= value) {
                index = i;
                break;
            }
        }
        System.arraycopy(arr, index, arr, index + 1, size);
        arr[index] = value;
        size++;
    }
  • System.arraycopy 方法說明,估計很多人沒見個這個方法,簡單說明一下參數
//   Object src :  原數組
//   int srcPos :  從元數據的起始位置開始
//  Object dest : 目標數組
//  int destPos : 目標數組的開始起始位置
//  int length  : 要copy的數組的長度

測試代碼

  XJArray xjArray2 = new XJArray(16);
  xjArray2.put(1);
  xjArray2.put(5);
  xjArray2.put(3);
  xjArray2.put(2);
  xjArray2.put(4);
  xjArray2.println();  // 輸出 [1,2,3,4,5,]

4、刪

  • 原理同有序增加,
  • 有序增加是往後移動,
  • 刪除是往前移動,
  • 指定刪除的索引數據直接被從後移動的數據覆蓋
    -在這裏插入圖片描述
    public void delete(int index) {
        if (index >= size || index < 0) {
            throw new ArrayIndexOutOfBoundsException();
        } else {
            System.arraycopy(arr, index+1, arr, index , size);
            size--;
        }
    }

測試代碼

  XJArray xjArray2 = new XJArray(16);
  xjArray2.put(1);
  xjArray2.put(5);
  xjArray2.put(3);
  xjArray2.put(2);
  xjArray2.put(4);
  xjArray2.println();  //輸出  [1,2,3,4,5,]

  xjArray2.delete(0);
  xjArray2.println();  //輸出  [2,3,4,5,]

  xjArray2.delete(2);
  xjArray2.println();  //輸出  [2,3,5,]

5、改

改就沒什麼好說的了,直接在對應的索引重新賦值就好了

    public void upd(int index, int newValue) {
        if (index >= size || index < 0) {
            throw new ArrayIndexOutOfBoundsException();
        } else {
            arr[index] = newValue;
        }
    }

6、查1 (索引查值–線性查詢)

線性查詢就是普通查詢,這個也沒什麼好說的,根據索引直接獲取就好了

   public long get(int index) {
        if (index >= size || index < 0) {
            throw new ArrayIndexOutOfBoundsException();
        } else {
            return arr[index];
        }
    }

7、查2 (值查索引–二分法查詢)

二分法查詢

  • 1、數組必須是有序的
  • 2、每次從中間劃開,判斷值是在左邊還是右邊,判斷後重複劃開在判斷
    在這裏插入圖片描述

    /**
     * 二分法查找數據(arr 必須是有序的,否則不可使用)
     */
    public int binarySearch(long value) {
        int start = 0;            // 數組最小索引值
        int end = size;           // 數組最大索引值,長度=數組數據數量時可使用: arr.length - 1;
        while (start <= end) {
            int middle = (start + end) / 2;
            if (value < arr[middle]) {
                // 值小於中間值,那麼值一定在左邊
                end = middle - 1;
            } else if (value > arr[middle]) {
                // 值大於中間值,那麼值一定在右邊
                start = middle + 1;
            } else if (value == arr[middle]) {
                // 找到了
                return middle;
            }
        }
        //start>end的情況,這種情況下value的值大於arr中最大的元素值或者value的值小於arr中最小的元素值
        return -1;
    }

測試代碼

        XJArray xjArray2 = new XJArray(16);
        xjArray2.put(1);
        xjArray2.put(3);
        xjArray2.put(2);
        xjArray2.println();  // [1,2,3,]
        System.out.println("索引位置:"+xjArray2.binarySearch( 1)); // 輸出0
        System.out.println("索引位置:"+xjArray2.binarySearch( 2)); // 輸出1
        System.out.println("索引位置:"+xjArray2.binarySearch( 3)); // 輸出2
        System.out.println("索引位置:"+xjArray2.binarySearch( 4)); // 輸出-1

本文到此結束,如果覺得有用,勞煩點個右上方關注一下唄,將不定時持續更新更多的內容…,感謝大家的觀看!

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