1. 程式人生 > >數據結構與算法(一)

數據結構與算法(一)

method 創建 city 初始化 ise 循環 sdf 無需 刪除算法

數據結構

  數據結構是計算機存儲、組織數據的方式,指相互之間存在一種或多種特定關系的數據元素的集合。

  常見數據結構有:

  1、數組 插入快 查找刪除慢 大小固定 元素單一

  2、有序數組 查找快 插入刪除慢 大小固定 元素單一

  3、棧 先進後出

  4、隊列 先進先出

  5、鏈表 插入刪除快 查找慢

  6、二叉樹 樹是平衡的則增刪改都快,刪除算法復雜

  7、紅黑樹 增刪改都快,樹總是平衡的,算法復雜

  8、2-3-4樹 增刪改都快,樹總是平衡的, 算法復雜

  9、哈希表 知道關鍵字則查詢插入都快,刪除慢,不知道關鍵字存取慢,對存儲空間使用不充分

  10、堆 插入刪除快,對最大數據項存取快,對其它數據項慢‘

  11、圖 對現實世界建模 有些算法慢且復雜

算法

  算法簡單來說就是解決問題的步驟

  在Java中,算法通常都是由類的方法來實現的。前面的數據結構,比如鏈表為啥插入、刪除快,而查找慢,平衡的二叉樹插入、刪除、查找都快,這都是實現這些數據結構的算法所造成的。

算法的特征:
  1、有窮性:對於任意一組合法輸入值,在執行又窮步驟之後一定能結束,即:算法中的每個步驟都能在有限時間內完成。

  2、確定性:在每種情況下所應執行的操作,在算法中都有確切的規定,使算法的執行者或閱讀者都能明確其含義及如何執行。並且在任何條件下,算法都只有一條執行路徑。

  3、可行性:算法中的所有操作都必須足夠基本,都可以通過已經實現的基本操作運算有限次實現之。

  4、有輸入:作為算法加工對象的量值,通常體現在算法當中的一組變量。有些輸入量需要在算法執行的過程中輸入,而有的算法表面上可以沒有輸入,實際上已被嵌入算法之中。

  5、有輸出:它是一組與“輸入”有確定關系的量值,是算法進行信息加工後得到的結果,這種確定關系即為算法功能。

  算法設計原則:

  1、正確性
  2、可讀性
  3、健壯性
  4、高效率與低存儲量需求:通常算法效率值得是算法執行時間;存儲量是指算法執行過程中所需要的最大存儲空間,兩者都與問題的規模有關。

數組

  數組的局限性分析:

  1、插入快,對於無序數組,上面我們實現的數組就是無序的,即元素沒有按照從大到小或者某個特定的順序排列,只是按照插入的順序排列。無序數組增加一個元素很簡單,只需要在數組末尾添加元素即可,但是有序數組卻不一定了,它需要在指定的位置插入。

  2、查找慢,當然如果根據下標來查找是很快的。但是通常我們都是根據元素值來查找,給定一個元素值,對於無序數組,我們需要從數組第一個元素開始遍歷,直到找到那個元素。有序數組通過特定的算法查找的速度會比無需數組快,後面我們會講各種排序算法。

  3、刪除慢,根據元素值刪除,我們要先找到該元素所處的位置,然後將元素後面的值整體向前面移動一個位置。也需要比較多的時間。

  4、數組一旦創建後,大小就固定了,不能動態擴展數組的元素個數。如果初始化你給一個很大的數組大小,那會白白浪費內存空間,如果給小了,後面數據個數增加了又添加不進去了。

簡單排序算法

  冒泡算法的運作規律如下:

  1、比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。

  2、對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對。這步做完後,最後的元素會是最大的數(也就是第一波冒泡完成)。

  3、針對所有的元素重復以上的步驟,除了最後一個。

  4、持續每次對越來越少的元素重復上面的步驟,直到沒有任何一對數字需要比較。

public class BubbleSort {


    public static int[] sort(int[] array){
        for(int i=1;i<array.length;i++){
            boolean flag = true;
            for(int j =0;j<array.length-i;j++){
                if(array[j]>array[j+1]){
                    int temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
                    flag = false;
                }
            }
            if(flag){
                break;
            }
        }
        return array;
    }

    public static void main(String[] args) {
        int[] array ={3,2,5,6,8,7,9,1,4};
        Arrays.stream(array).forEach(System.out::println);
        array = sort(array);
        Arrays.stream(array).forEach(System.out::println);
    }
}

  選擇排序運作規律:

  1、從待排序序列中,找到關鍵字最小的元素

  2、如果最小元素不是待排序序列的第一個元素,將其和第一個元素互換

  3、從余下的 N - 1 個元素中,找出關鍵字最小的元素,重復(1)、(2)步,直到排序結束

public class ChoiceSort {

    public static int[] sort(int[] array){
        for(int i=0;i<array.length;i++){
            for(int j =i+1;j<array.length;j++){
                if(array[i]>array[j]){
                    int temp = array[i];
                    array[i] = array[j];
                    array[j] =temp;
                }
            }
        }
        return array;
    }

    public static void main(String[] args) {
        int[] array ={3,2,5,6,8,7,9,1,4};
        Arrays.stream(array).forEach(System.out::println);
        array = sort(array);
        Arrays.stream(array).forEach(System.out::println);
    }
}  

  直接插入排序:
  基本思想是每一步將一個待排序的記錄,插入到前面已經排好序的有序序列中去,直到插完所有元素為止。

public class InsertSort {

    public static int[] sort(int[] array){
        for(int i =1;i<array.length;i++){
            int temp =array[i];
            int j =i;
            while(j>0 && temp <array[j-1]){
                array[j] =array[j-1];
                j--;
            }
            array[j] = temp;
        }

        return array;
    }


    public static void main(String[] args) {
        int[] array ={3,2,5,6,8,7,9,1,4};
        Arrays.stream(array).forEach(System.out::println);
        array = sort(array);
        Arrays.stream(array).forEach(System.out::println);
    }
}

  冒泡、選擇、插入用大 O 表示法都需要 O(N2) 時間級別。一般不會選擇冒泡排序,雖然冒泡排序書寫是最簡單的,但是平均性能是沒有選擇排序和插入排序好的。
選擇排序把交換次數降低到最低,但是比較次數還是挺大的。當數據量小,並且交換數據相對於比較數據更加耗時的情況下,可以應用選擇排序。
在大多數情況下,假設數據量比較小或基本有序時,插入排序是三種算法中最好的選擇。

基於數組實現棧

  這裏順帶做個小測試,證明java中泛型是一個語法糖,僅在編譯時起作用,當我們使用反射時,就可以越過泛型檢查

public class ArrayStock<E>{

    private Object[] elements;

    private int top;

    private int size;

    public ArrayStock(){

        this.elements = new Object[10];
        this.top = -1;
        this.size = 10;
    }

    public ArrayStock(int size) {
        if(size<=0){
            throw new IllegalArgumentException("size不能小於0");
        }
        this.elements = new Object[size];
        this.top = -1;
        this.size = size;
    }
    public E push(E e){
        if(size<= top+1){
            grow();
        }
        elements[++top] = e;
        return e;
    }

//    public E poll() {
//        if(top==-1){
//            throw new EmptyStackException();
//        }
//        E e =(E) elements[top];
//        elements[top--] = null;
//
//        return e;
//    }

    public Object poll() {
        if(top==-1){
            throw new EmptyStackException();
        }
        Object e =  elements[top];
        elements[top--] = null;

        return e;
    }

    private void grow(){
        System.out.println("kuorong ");
        int oldCapacity = size;
        int newCapacity  = oldCapacity<<1;
        Object[] newArray = new Object[newCapacity];
        System.arraycopy(elements,0,newArray,0,size);
        this.elements = newArray;
        this.size = newCapacity;


    }

    public static void main(String[] args) throws Exception{

        ArrayStock<String> arrayStock = new ArrayStock(3);
        arrayStock.push("asd");
        Method method =ArrayStock.class.getDeclaredMethod("push",Object.class);
        method.invoke(arrayStock,13);
        arrayStock.push("sdf");
        arrayStock.push("qwe");
        arrayStock.push("sdfsdfsf");
        System.out.println(arrayStock.poll());
        System.out.println(arrayStock.poll());
        System.out.println(arrayStock.poll());
        System.out.println(arrayStock.poll());
        System.out.println(arrayStock.poll());

    }

}

基於數組實現循環隊列和優先級隊列

public class ArrayQueue {

    private Object[] queueArray;
    private int maxSize;
    private int front;
    private int rear;
    private int items;

    public ArrayQueue(){
        this.queueArray = new Object[3];
        maxSize =3;
        front =0;
        rear = -1;
        items = 0;
    }

    public void push(Object o){
        if(isFull()){
            System.out.println("已滿");
        }else{
            if(rear ==maxSize-1){
                rear =-1;

            }
            queueArray[++rear] = o;
            items++;
        }
    }


    public Object poll(){
        Object returnValue = null;
        if(!isEmpty()){
            returnValue = queueArray[front];
            queueArray[front] =null;
            front++;
            if(front==maxSize){
                front = 0;
            }
            items--;
        }
        return returnValue;
    }
    private boolean isFull(){
        return items ==maxSize;
    }
    public boolean isEmpty(){
        return (items ==0);
    }

    public static void main(String[] args) {
        ArrayQueue arrayQueue = new ArrayQueue();
        arrayQueue.push(12);
        arrayQueue.push(13);
        arrayQueue.push(14);
        System.out.println(arrayQueue.poll());
        System.out.println(arrayQueue.poll());
        arrayQueue.push(34);
        arrayQueue.push(56);
        arrayQueue.push(6756);
        arrayQueue.push(2342);
        System.out.println(arrayQueue.poll());
        System.out.println(arrayQueue.poll());
        System.out.println(arrayQueue.poll());
        System.out.println(arrayQueue.poll());
    }
}
public class PriorityQueue {

    private int maxSize;
    private int[] priQueArray;
    private int nItems;

    public PriorityQueue(int s){
        maxSize = s;
        priQueArray = new int[maxSize];
        nItems = 0;
    }

    public void push(int value){
        if(nItems==0){
            priQueArray[0] =value;
        }else{
            int j ;
            j = nItems-1;
            while(j>=0&& value>priQueArray[j]){
                priQueArray[j+1] = priQueArray[j];
                j--;
            }
            priQueArray[j+1] = value;
        }
        nItems++;
    }

    public int poll(){

        int returnValue =priQueArray[nItems-1];
        priQueArray[nItems-1] = -1;
        nItems--;
        return returnValue;

    }
    public static void main(String[] args) {
        PriorityQueue arrayQueue = new PriorityQueue(10);
        arrayQueue.push(12);
        arrayQueue.push(13);
        arrayQueue.push(14);
        System.out.println(arrayQueue.poll());
        System.out.println(arrayQueue.poll());
        arrayQueue.push(34);
        arrayQueue.push(56);
        arrayQueue.push(6756);
        arrayQueue.push(2342);
        System.out.println(arrayQueue.poll());
        System.out.println(arrayQueue.poll());
        System.out.println(arrayQueue.poll());
        System.out.println(arrayQueue.poll());
        System.out.println(arrayQueue.poll());
    }

}

數據結構與算法(一)