數據結構(數組實現)

數組是應用最廣泛的一種數據結構,常常被植入到編程語言中,作爲基本數據類型使用,因此,在一些教材中,數組並沒有被當做一種數據結構單獨拿出來講解(其實數組就是一段連續的內存,即使在物理內存中不是連續的,在邏輯上肯定是連續的)。其實沒必要在概念上做糾纏,數組可以當做學習數據結構的敲門磚,以此爲基礎,瞭解數據結構的基本概念以及構建方法

數據結構不僅是數據的容器,還要提供對數據的操作方法,比如檢索、插入、刪除、排序等。

無序數組(假設數組中,沒有重複的值)

package www.panda.array;

/**
 * @Author: panda
 * @Data: 2018/12/2 21:19
 * @Version: 1.0
 * @remark 沒有實現數組擴容,想要實現,各位同學自己拓展
 */
public class DisorderlyArray<E> {

    private String[] stringsArray;

    private static int size = 0;

    private static final int ERROEINDEX = -1;

    public DisorderlyArray(int capacity){
        if(capacity <= 0) throw new IllegalArgumentException("數組的長度不能小於或等於0");
        stringsArray = new String[capacity];
    }

    //新增
    public void insertElem(String value){
        stringsArray[size++] = value;
    }

    //查看是否包含元素
    public int containsElem(String value){
        for(int i=0;i<stringsArray.length;i++){
            if(stringsArray[i].equals(value)){
                return i;
            }
        }
       return ERROEINDEX;
    }

    //通過下標得到元素
    public String getElem(int index){
        if(index <= 0) throw new IllegalArgumentException("沒有此下表元素");
        return stringsArray[index];
    }

    //通過值刪除元素
    public Boolean deleteElem(String value){
        int index = -1;
        if((index = containsElem(value)) != -1){
            for(int i=index;i<size;i++){
                stringsArray[i]=stringsArray[i+1];
            }
            size--;
            return true;
        }else{
            return false;
        }
    }

    //通過下標修改值
    public void updateElemByIndex(int index,String value){
        stringsArray[index] = value;
    }

    //遍歷所有元素
    public void display(){
        for(int i=0;i<size;i++){
            System.out.print(stringsArray[i]+"\n");
        }
    }

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

    public static void main(String[] args){
        DisorderlyArray disorderlyArray = new DisorderlyArray(10);
        disorderlyArray.insertElem("張三");
        disorderlyArray.insertElem("李四");
        disorderlyArray.insertElem("王五");
        disorderlyArray.insertElem("趙六");
        String elem = disorderlyArray.getElem(1);
        System.out.print(elem);
        disorderlyArray.updateElemByIndex(1,"猴八");
        disorderlyArray.deleteElem("趙六");
        disorderlyArray.display();
        System.out.print(disorderlyArray.getSize());
    }

}

無序數組的特點:插入快,假設知道下標,可以很快獲取到元素

無序數組的缺點:刪除慢,查找慢

有序數組(假設數組中是沒有重複值的,數據是從小到大的順序排列的)

package www.panda.array;

/**
 * @Author: panda
 * @Data: 2018/12/2 22:10
 * @Version: 1.0
 * @remark 當前是1.1 新增二分查找,以及二分查找優化 
 */
public class OrderlyArray<E> {

   private int[] intArray;

    private int size = 0;

    private static final int ERRORVALUE = -1;

    public OrderlyArray(int capacity){
        if(capacity <= 0) throw new IllegalArgumentException("數組的長度不能小於或等於0");
        this.intArray = new int[capacity];
    }


    //增加元素
    public void insertElem(int elem){
        int index = 0;
        for(;index<size;index++){
            if(intArray[index] > elem){//如果當前元素大於,目標元素,結束循環
                break;
            }
        }
        for(int i=size;i>index;i--){
            intArray[i] = intArray[i - 1];//前一位賦值給後一位
        }
        intArray[index] = elem;
        size++;
    }

    //通過要查找的值,得到數組的下標
    public int getIndex(int value){
        for(int i=0;i<size;i++){
            if(intArray[i] == value){
                return i;
            }
        }
        return ERRORVALUE;
    }

    /**
     * 簡單版的二分查找
     * @param array
     * @param value
     * @return
     */
    public int easyBinarySearch(int[] array,int value){
        int lower = 0,upper = array.length-1,center = 0;
        if(center < intArray[lower] || center> intArray[upper] || lower > upper){
            return ERRORVALUE;
        }
        while(lower <= upper){
            center = (lower+upper)/2;
            if(array[center] == value){
                return center;
            }else if(value > array[center]){
                lower = center + 1;
            }else if(value < array[center]){
                upper = center - 1;
            }
        }
        return ERRORVALUE;
    }


    /**
     *  對二分查找進行了優化,性能提高了30% 到 80%
     * @param array
     * @param value
     * @return
     */
    public static int optimizeBinarySearch(int[] array,int value){
        int lower = 0,upper = array.length-1,center = 0;
        while(lower + 1 != upper){
            center = (upper + lower)/2;
            if(array[center] < value)
                lower = center;
            else
                upper =center;
        }
        if(upper >= array.length || array[upper] != value)
            upper = ERRORVALUE;
        return upper;
    }

    //通過下標獲取到元素
    public int getElem(int index){
        if(index <= 0) throw new IllegalArgumentException("沒有此下表元素");
        if(index>size-1) throw new ArrayIndexOutOfBoundsException("數組下標越界了");
        return intArray[index];
    }

    //刪除數組中的元素
    public void deleteElem(int elem){
        int index = -1;
        for(int i=0;i<size;i++){
            if(intArray[i] == elem){
                index = i;
                break;
            }
        }
        if(index >= 0){
            for(int i=index;i<size-1;i++){
                intArray[i] = intArray[i + 1];
            }
            size--;
        }else{
            //這裏不自定義異常了,各位同學可以自己拓展
            System.out.println("沒有找到你想要刪除的值");
        }
    }

    //查詢所有的元素
    public void display(){
        for(int i=0;i<size;i++){
            System.out.print(intArray[i]+"\n");
        }
    }

    //得到整個數組的長度
    public int getSize(){
        return size;
    }

    public static void main(String[] args){
        int[] intArray ={1,2,3,4,5,6};
        int i = OrderlyArray.optimizeBinarySearch(intArray,4);
        System.out.println(i);
        OrderlyArray<Object> objectOrderlyArray = new OrderlyArray<>(10);
        int i1 = objectOrderlyArray.easyBinarySearch(intArray, 2);
        System.out.println(i1);
         objectOrderlyArray.insertElem(1);
        objectOrderlyArray.insertElem(2);
        objectOrderlyArray.insertElem(3);
        objectOrderlyArray.insertElem(4);
        objectOrderlyArray.deleteElem(5);
        int size1 = objectOrderlyArray.getSize();
        objectOrderlyArray.display();
    }



}

lower和upper指向數組的第一個和最後一個非空數據項。通過設置這些變量可以確定查找的範圍。然後再while循環中,當前的下標center被設置爲這個範圍的中間值

如果center就是我們要找的數據項,則返回下標,如果不是,就要分兩種情況來考慮:如果center指向的數據項比我們要找的數據小,則證明該元素只可能在center和upper之間,即數組後一半中(數組是從小到大排列的),下輪要從後半段檢索;如果center指向的數據項比我們要找的數據大,則證明該元素只可能在lower和center之間,下一輪要在前半段中檢索

有序數組的特點:採用二分查找,查找速度很快(以及優化版二分查找)

有序數組的缺點:刪除慢,插入慢

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