1、時間複雜度和簡單排序

預備知識

1、時間複雜度

①常數的時間操作:一個操作如果和數據量沒有關係,每次都是固定時間操作,叫做常數操作。
②時間複雜度常用O(讀作big O)來表示。具體來說,在常數操作數量的表達式中,
只要高階項,不要低階項,也不要高階項的係數,剩下的部分記爲f(N),那麼時間複雜度記爲
O(f(N))。

例1、時間複雜度的例子

對一個長度爲N的數組進行排序:
算法:依次從0—-N-1個數中選出最小的數,放在數組的0位置
  從1—N-2個數中選出最小的數,放在數組的1位置
&nbsp&nbsp從2—N-3個數中選出最小的數,放在數組的2位置
time=N+(N-1)+(N-2)**+1=(N+1)N/2
只要高階項,不要低階項,也不要高階項的係數
所以時間複雜度位O(N*N)

例2、時間複雜度的例子

一個有序數組A,另一個無序數組B,請打印B中所有不在A中的數,A數組的長度爲N,
B數組的長度爲M。
·算法1:對於數組B中的每一個數,都在A中通過遍歷的方式找一下;
·算法2:對於數組B中的每一個數,都在A中通過二分的方式查找一下;
·算法3:先把B中的數進行排序,然後用類似外排的方式打印所有不在A中出現的數。
計算時間複雜度:
1、O(M*N)
2、①對有序的數組,二分查找的時間複雜度O(logN) 底數爲2
      在1,3,5,6,8,10中找出x
      L………………R
      mid=(L+R)/2 ,根據,數組[mid]與x比較大小的結果,確定下一次二分的方向,N個數二分最多能分logN次。
②所以算法2的時間複雜度爲 O(M*logN)
3、
①對無序數組使用基於比較的排序算法O(M*logM)
②1,3,5,7,10,16,18;2,4,8,17,20
….a…………………….b…………
使用類似外排的方式:如果a

2、排序算法

①冒泡排序

//O(N*N)
package Day01;

public class Day01_bubbleSort {
    public static  void  bubbleSort(int[] arr){
            /*1、判斷數組的長度*/
            if (arr==null||arr.length<2){
                System.out.print("數組太短無法滿足要求");
            }
            for(int end=arr.length-1;end>0;end--){
            for (int i=0;i<end;i++){
                if (arr[i]>arr[i+1]){
                    swap(arr,i,i+1);
                }
            }
        }

    }
    public static void swap(int[] arr,int i,int j){
        int tem=arr[i];
        arr[i]=arr[j];
        arr[j]=tem;

    }
    public static void main(String[] args) {
//        int[] a=[1,3,50,39,28,100,3,6,30]
        int[] a={1,3,50,39,28,100,3,6,30};
        Day01_bubbleSort.bubbleSort(a);
        for (int i=0;i<a.length;i++){
            System.out.println(a[i]);
        }
    }
}

2、選擇排序

public class Day01_SelectionSort {
    /*算法:依次從0----N-1個數中選出最小的數,放在數組的0位置;
    從1---N-2個數中選出最小的數,放在數組的1位置
    從2---N-3個數中選出最小的數,放在數組的2位置
    O(N*N)
    */
    public static void  selectionSort(int[] arr){
        /*1、判斷數組的長度*/
        if (arr==null||arr.length<2){
            System.out.print("無法滿足要求.....");
            return ;
        }
        for(int i=0;i<arr.length-1;i++){
            int minIndex=i;
            for (int j=i+1;j<arr.length;j++){
                minIndex=arr[j]<arr[minIndex]? j  :  minIndex;
            }
            swap(arr,i,minIndex);
        }
    }
    public static void swap(int[] arr,int i,int j){
        int tem=arr[i];
        arr[i]=arr[j];
        arr[j]=tem;

    }
    public static void main(String[] args) {
        int[] a={1,3,50,39,28,100,3,6,30};
        Day01_SelectionSort.selectionSort(a);
        for(int i=0;i<a.length;i++){
            System.out.println(a[i]);
        }
    }
}

3、插入排序

package Day01;
/*輸入:一個含有N個元素的數組
* 1、遍歷數組的下標    1.......N-1
* 2、依次把下標所對應的元素與前一個元素進行比較,小於之前的元素就交換,並不斷比較
*
*時間複雜度O(N^2)
*
* 最好O(N)
* 最壞O(N^2)
*
* */
public class Day01_InstertionSorting {
    public static void InsertionSorting(int [] arr){
        if (arr==null||arr.length<2){
            System.out.print("無法滿足要求.....");
            return ;
        }
        for (int i=1;i<arr.length;i++){
            for(int j=i;j>=0;j--){
                if (arr[j-1]>arr[j]){
                    swap(arr,j-1,j);
                }
                else {
                    j=-1;
                }
            }
        }
    }
    private static void swap(int[] arr, int i, int j) {
        int tem=arr[i];
        arr[i]=arr[j];
        arr[j]=tem;
    }

    public static void main(String[] args) {
    int[] arr={1,3,2,29,30,42,14,11,18,20,100,50};
    Day01_InstertionSorting.InsertionSorting(arr);
        for (int arr_ele:arr){
            System.out.println(arr_ele);
        }
    }
}

3、遞歸的時間複雜度和master公式

(1)用遞歸的方法求最大值

public class Day01_recursion {
    public static int getMAx(int [] arr,int L,int R){
        if (L==R){
            return arr[L];
        }
        int mid=(L+R)/2;
        int maxLeft=getMAx(arr,L,mid);
        int maxRight=getMAx(arr,mid+1,R);
        return Math.max(maxLeft,maxRight);
    }
    public static void main(String[] args) {
        int []arr={11,2,1,4,50,8,23,36,13,46,90};
        System.out.println(Day01_recursion.getMAx(arr,0,8));
    }
}

(2)主定理(master Theorem)

設a>=1,b>1爲常數,f(n)爲函數,T(n)爲非負整數,且

T(n)=aT(n/b)+f(n)

a是歸約後子問題的個數
b是子問題的規模
f(n)是歸約過程及組合子問題解的工作量

Alt text


如歸併排序:T(n)=2T(n/2)+O(N)
帶入公式其時間複雜度爲O(n*logn)

4、歸併排序


package Day01;
/*
歸併排序的時間複雜度是O(N*lgN)
T(n)=2T(n/2)+O(N)
* */
public class Day01_mergeSort {
    public static void  mergeSort(int[] arr){
        if(arr==null||arr.length<2){
            return;
        }
        sortProcess(arr,0,arr.length-1);
    }
    public static void sortProcess(int[]arr,int L,int R){
        if(L==R){
            return;
        }
        int mid=(L+R)/2;
        sortProcess(arr,L,mid);//T(2/n)
        sortProcess(arr, mid+1, R);//T(2/n)
        merge(arr,L,mid,R);//O(n)
    }
    public static void merge(int [] arr,int L,int mid,int R){
        int [] help=new int[R-L+1];
        int p1=L;
        int p2=mid+1;
        int i=0;
        while (p1<=mid && p2<=R){
           help[i++]=arr[p1]<arr[p2]?arr[p1++]:arr[p2++];//比較完之後,向右移動一位
        }
        while (p1<=mid){
            help[i++]=arr[p1++];
        }
        while (p2<=R){
            help[i++]=arr[p2++];
        }
        for (i=0;i<help.length;i++){
            arr[L+i]=help[i];
        }
    }

    public static void main(String[] args) {
        int[]arr={1,2,1,5,7,0,100,40,20,19,12,10,16};
     Day01_mergeSort.mergeSort(arr);
     for (int i=0;i<arr.length;i++){
         System.out.println(arr[i]);
     }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章