Java數據結構和算法系列2--數組

1.介紹

Java最常用的數據結構就是數組了,Java中得數組有2種數據類型:基本類型(如int,long)和對象類型。在許多編程語言中數組是基本類型,但在Java中把它們當做對象來對待,因此在創建數組時必須使用new操作符:

int[] intArray = new int[100];

[]操作符對編譯器來說是一個標誌,它說明正在命名的是數組對象而不是普通變量,當然數組變量還可以這麼寫,就是將它放在變量名的後面:

int intArray[] = new int[100];

在內存中,數組變量名稱,只是它的引用(地址),並不是數組本身。

2.數組結構

這裏寫圖片描述

3.數組操作

3.1 創建數組

前面已經介紹過

int[] intArray = new int[100];

3.2 初始化

創建數組後,如果不另行指定,那麼數組會自動初始化爲空(特殊的null對象),如果此時嘗試訪問一個含有null的數組數據項,程序會出現NullPointer的運行時異常。使用下面語法可以對一個基本類型的數組初始化:

int[] intArray = {0,12,31,9,15,2,99};

上面語句就更簡單,創建一個數組對象並且對其初始化。

3.3 例子

下面通過一段代碼,演示數組的基本操作,包括創建,初始化,添加,查找,刪除。

/**
* 
*/
package com.tngtech.array;

/**
* 數組基本操作
* 
* @author tngtech
* @date 2015年12月27日
*       <p>
*       博客:http://blog.csdn.net/jacman
*       <p>
*       Github:https://github.com/tangthis
*
*/
public class MyArray {
private long[] arry;
private int length;// 數組長度

public MyArray(int max) {
    arry = new long[max];
    length = 0;
}

public boolean find(long searchKey) {
    for (int i = 0; i < length; i++) {
        if (arry[i] == searchKey) {
            return true;
        }
    }
    return false;
}

public void insert(long value) {
    arry[length] = value;
    length++;
}

public boolean delete(long value) {
    int j;
    for (j = 0; j < length; j++) {
        if (arry[j] == value) {
            break;
        }
    }

    if (j == length) {
        return false; // 沒有找到數據項
    }

    // 刪除對應數據項,並且將後面元素從被刪除的元素位置重新計算
    for (int k = j; k < length; k++) {
        arry[k] = arry[k + 1];
    }

    length--;
    return true;
}

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

public static void main(String[] args) {
    MyArray myArray = new MyArray(100);
    //在數據中插入10個元素
    myArray.insert(66);
    myArray.insert(99);
    myArray.insert(22);
    myArray.insert(55);
    myArray.insert(77);
    myArray.insert(44);
    myArray.insert(11);
    myArray.insert(0);
    myArray.insert(33);
    myArray.insert(88);

    myArray.display();

    long searchKey = 33;
    if(myArray.find(searchKey)){
        System.out.println("找到了" + searchKey);
    }else{
        System.out.println("沒有找到"+searchKey);
    }

    //刪除2個元素
    myArray.delete(0);
    myArray.delete(22);
    myArray.display();
}
}

4.有序數組

4.1 概念

假設一個數組,其中元素都是按照關鍵字升序或者降序排列,這種數組稱爲有序數組。
當向這種數組插入數據項時,需要爲插入操作找到正確的位置,剛好在稍小值後面,稍大值前面,然後將數據項大的值向後移,以騰出空間。
爲什麼要按照順序排列呢?好處之一就是可以通過二分查找顯著提高查找速度。
在有序數組假設數據項不重複,就剛纔的邏輯得出結論,它的查找速度提高了,但是插入操作速度降低了。

4.2 線性查找和二分查找

4.2.1 線性查找

正如剛纔3.3例子所示,線性查找和未排序的數組查找操作相似,依次向後,尋找匹配。在有序數組中,有些不同,當查到一個比待查數據大的值時就退出查找。

4.3.2 二分查找

假設一個數組從1到100,那麼二分查找法,就會從中間數字50來比較待查數字的範圍,如果小於50,那麼就從1-50範圍的中間數字來查找即25,如果小於25,那麼就從1-25的中間數字來查找即12(整除);反之,如果查找大於50,那麼就從50-100中間數組來找到即75,依次類推,直到查到待查數據就退出。
所以二分查找法,就是將有可能的值劃分爲2部分,最後範圍縮小到一個數字那麼大,就是待查找的值了。
下面,我們看下二分查找法的例子:

    /**
     * 二分查找法
     * 
     * @param value
     * @return
     */
    public int halfFind(long searchKey){
        int lowerBound = 0;
        int upperBound = length - 1;

        int curBound;
        while(true){
            curBound = (lowerBound + upperBound) / 2;
            if(arry[curBound] == searchKey){
                return curBound; 
            }else if(lowerBound > upperBound){
                return length; //用length表示找不到的位置
            }else{
                if(arry[curBound] < searchKey){
                    lowerBound = curBound + 1;
                }else{
                    upperBound = curBound - 1;
                }
            }
        }
    }

下面我們來測試下二分查找法,代碼如下:

//有序數組操作,二分查找法
    public static void sortArrayOper(){
        MyArray myArray = new MyArray(100);
        for(long i = 1 ; i <= 100; i++){
            myArray.insert(i);
        }
        long searchKey = 90;
        int index = myArray.halfFind(searchKey);
        if(index != myArray.length){
            System.out.println("二分查找法,找到了"+searchKey+",位置:"+index);
        }else{
            System.out.println("二分查找法,沒有找到了"+searchKey);
        }
    }
    public static void main(String[] args) {
        //myArryOper();

        sortArrayOper();
    }

程序跑起來,輸出結果爲:二分查找法,找到了90,位置:89
所以,有序數組可以使用二分查找法,來提高查找的速度。

Github源碼:https://github.com/tangthis/java-data

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