最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java數(shù)據(jù)結構之基于比較的排序算法基本原理及具體實現(xiàn)

 更新時間:2021年09月26日 09:22:15   作者:信仰xinyang  
最近剛學習完七種比較常見的基于比較的排序算法,感覺比較重要,所以寫個博客記錄一下,通讀本篇對大家的學習或工作具有一定的價值,需要的朋友可以參考下

基于比較的排序算法基本原理及Java實現(xiàn)

1. 七大基于比較的排序-總覽

1.1常見基于比較的排序分類

在這里插入圖片描述

1.2時間復雜度,空間復雜度以及穩(wěn)定性。

  • 穩(wěn)定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。
  • 不穩(wěn)定:如果a原本在b的前面,而a=b,排序之后 a 可能會出現(xiàn)在 b 的后面。

2.直接插入排序

2.1 直接插入排序的基本思想

直接插入排序的基本思想,就是每次選取一個待排序元素,按照一定規(guī)定插入到前面已經(jīng)排好序的一組元素的適當位置。當每個元素都插入完畢,整個序列已經(jīng)有序。

當插入第i(i >= 1)時,前面的V[0],V[1],……,V[i-1]已經(jīng)排好序。這時,用V[I]的排序碼與V[i-1],V[i-2],…的排序碼順序進行比較,找到插入位置即將V[i]插入,原來位置上的元素向后順移。

2.2 直接插入排序動畫演示

在這里插入圖片描述

2.3 代碼示例

public static void insertSort(int[] arr){
        for(int i=1;i<arr.length;i++){//從第二個元素開始,遍歷整個數(shù)組
            int j=i-1;//i之前的序列 已經(jīng)有序
            int temp=arr[i];
            for(;j>=0;j--){//此循環(huán)用于尋找插入位置
                if(arr[j]>temp){//此時逐個向后移動元素
                    arr[j+1]=arr[j];
                }else break;//找到插入位置 直接break
            }
            arr[j+1]=temp;//直接插入
        }
}

2.4 時間復雜度,空間復雜度以及穩(wěn)定性

  • 時間復雜度最壞情況:數(shù)組整體逆序O(n^2);
  • 時間復雜度最好情況:數(shù)組已經(jīng)有序O(n^2);
  • 空間復雜度:O(1);
  • 穩(wěn)定性:穩(wěn)定;

3. 希爾排序

3.1 算法思想

希爾排序是特殊的插入排序,直接插入排序每次插入前的遍歷步長為1,而希爾排序是將待排序列分為若干個子序列,對這些子序列分別進行直接插入排序,當每個子序列長度為1時,再進行一次直接插入排序時,結果一定是有序的。常見的劃分子序列的方法有:初始步長(兩個子序列相應元素相差的距離)為要排的數(shù)的一半,之后每執(zhí)行一次步長折半。

3.2 圖片演示

3.3 代碼示例

public static void hell(int[] arr,int gap){//當gap=1時 其實就是直接插入排序
        for(int i=gap;i<arr.length;i++){
            int j=i-gap;
            int temp=arr[i];
            for(;j>=0;j-=gap){
                if(arr[j]>temp){
                    arr[j+gap]=arr[j];
                }else break;
            }
            arr[j+gap]=temp;
        }
}
public static void hellSort(int[] arr){
        int gap=arr.length;
        while(gap>1){
            gap=gap/2+1;
            hell(arr,gap);
        }
    }

3.4 時間復雜度,空間復雜度以及穩(wěn)定性

  • 時間復雜度最好:O(n);
  • 時間復雜度最壞:O(n^1.5);
  • 時間復雜度平均:O(n^1.3);
  • 空間復雜度:O(1);
  • 穩(wěn)定性:不穩(wěn)定;

4.選擇排序

4.1 算法思想

選擇排序(Selection-sort)是一種簡單直觀的排序算法。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再從剩余未排序元素中繼續(xù)尋找最?。ù螅┰?,然后放到已排序序列的末尾。以此類推,直到所有元素均排序完畢。

4.2 動畫演示

img

4.3 代碼示例

public static void selectSort(int[] arr){
        for(int i=0;i<arr.length;i++){
            for(int j=i+1;j<arr.length;j++){
                if(arr[j]<arr[i]){
                    int temp=arr[j];
                    arr[j]=arr[i];
                    arr[i]=temp;
                }
            }
      }
}

4.4 時間復雜度,空間復雜度以及穩(wěn)定性

  • 時間復雜度最好:O(n);
  • 時間復雜度最壞:O(n^2;
  • 時間復雜度平均:O(n^2);
  • 空間復雜度:O(1);
  • 穩(wěn)定性:不穩(wěn)定;

5.堆排序

5.1 算法思想

堆是具有以下性質(zhì)的完全二叉樹:每個結點的值都大于或等于其左右孩子結點的值,稱為大頂堆;或者每個結點的值都小于或等于其左右孩子結點的值,稱為小頂堆。如下圖:

  • 將初始待排序關鍵字序列(R1,R2….Rn)構建成大頂堆,此堆為初始的無序區(qū);
  • 將堆頂元素R[1]與最后一個元素R[n]交換,此時得到新的無序區(qū)(R1,R2,……Rn-1)和新的有序區(qū)(Rn),且滿足R[1,2…n-1]<=R[n];
  • 由于交換后新的堆頂R[1]可能違反堆的性質(zhì),因此需要對當前無序區(qū)(R1,R2,……Rn-1)調(diào)整為新堆,然后再次將R[1]與無序區(qū)最后一個元素交換,得到新的無序區(qū)(R1,R2….Rn-2)和新的有序區(qū)(Rn-1,Rn)。不斷重復此過程直到有序區(qū)的元素個數(shù)為n-1,則整個排序過程完成。

img

5.2 動畫演示

img

5.3 代碼示例

public static void heapSort(int[] arr){//排序方法
        creatHeap(arr);
        int end=arr.length-1;
    //因為是大根堆,所以根節(jié)點值為最大值,根節(jié)點與最后一個節(jié)點值交換 輸出并刪除此時最后一個節(jié)點,然后向下調(diào)整根節(jié)點
        while(end>0){
            int temp=arr[0];
            arr[0]=arr[end];
            arr[end]=temp;
            shiftDown(arr,0,end);
            end--;
        }

    }
public static void creatHeap(int[] arr){//建堆
        for(int parent=(arr.length-1-1)/2;parent>=0;parent--){
            shiftDown(arr,parent,arr.length);
        }
    }
public static void shiftDown(int[]arr,int root,int len){//向下調(diào)整操作
        int parent=root;
        int child=parent*2+1;
        while(child<len){
            if(child+1<len&&arr[child]<arr[child+1]){//待調(diào)整節(jié)點右子樹大于左子樹
                child++;
            }
            if(arr[child]>arr[parent]){//由于是大根堆,如果兒子節(jié)點值大于父親節(jié)點就交換
                int temp=arr[parent];
                arr[parent]=arr[child];
                arr[child]=temp;
                parent=child;//繼續(xù)向下調(diào)整,防止調(diào)整后不滿足大根堆的條件
                child=parent*2+1;
            }else break;
        }
    }

5.4 時間復雜度,空間復雜度以及穩(wěn)定性

  • 時間復雜度最好:O(nlogn);
  • 時間復雜度最壞:O(nlogn);
  • 時間復雜度平均:O(nlogn);
  • 空間復雜度:O(1);
  • 穩(wěn)定性:不穩(wěn)定;

6.冒泡排序

6.1 算法思想

比較兩個相鄰的元素,將值大的元素交換到右邊

思路:依次比較相鄰的兩個數(shù),將比較小的數(shù)放在前面,比較大的數(shù)放在后面。

  • 1.第一次比較:首先比較第一和第二個數(shù),將小數(shù)放在前面,將大數(shù)放在后面。
  • 2.比較第2和第3個數(shù),將小數(shù) 放在前面,大數(shù)放在后面。
  • 3.如此繼續(xù),知道比較到最后的兩個數(shù),將小數(shù)放在前面,大數(shù)放在后面,重復步驟,直至全部排序完成
  • 4.在上面一趟比較完成后,最后一個數(shù)一定是數(shù)組中最大的一個數(shù),所以在比較第二趟的時候,最后一個數(shù)是不參加比較的。
  • 5.在第二趟比較完成后,倒數(shù)第二個數(shù)也一定是數(shù)組中倒數(shù)第二大數(shù),所以在第三趟的比較中,最后兩個數(shù)是不參與比較的。
  • 6.依次類推,每一趟比較次數(shù)減少依次

6.2 動畫演示

img

6.3 代碼示例

public static void bubbleSort(int[] arr){
        for(int i=0;i<arr.length-1;i++){//外層循環(huán)控制趟數(shù)
            boolean flag=false;//一個標記進行優(yōu)化
            for(int j=0;j<arr.length-1-i;j++){//內(nèi)層循環(huán)控制比較次數(shù)
                if(arr[j]>arr[j+1]){
                    int temp=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                    flag=true;
                }
            }
            if(flag==false) break;//如果一趟循環(huán)走完沒有交換,說明已經(jīng)有序,直接break
        }
    }

6.4 時間復雜度,空間復雜度以及穩(wěn)定性

  • 時間復雜度最好:O(n);
  • 時間復雜度最壞:O(n^2);
  • 時間復雜度平均:O(n^2);
  • 空間復雜度:O(1);
  • 穩(wěn)定性:穩(wěn)定

7.快速排序(十分重要)

7.1 算法思想

我們從數(shù)組中選擇一個元素,我們把這個元素稱之為中軸元素吧,然后把數(shù)組中所有小于中軸元素的元素放在其左邊,所有大于或等于中軸元素的元素放在其右邊,顯然,此時中軸元素所處的位置的是有序的。也就是說,我們無需再移動中軸元素的位置。

從中軸元素那里開始把大的數(shù)組切割成兩個小的數(shù)組(兩個數(shù)組都不包含中軸元素),接著我們通過遞歸的方式,讓中軸元素左邊的數(shù)組和右邊的數(shù)組也重復同樣的操作,直到數(shù)組的大小為1,此時每個元素都處于有序的位置。

7.2 動畫演示

img

7.3 代碼示例

//該代碼參考acwing創(chuàng)始人yxc的快排模板
public static void quickSort(int[] arr,int l,int r){
        if(l>=r) return;//每次判斷傳進來左右下標
        int i=l-1,j=r+1;//因為在循環(huán)中,要先i++,j--所以i,j定義為兩邊界偏移1
        int x=arr[(l+r)/2];//取x為數(shù)組中間位置數(shù)
        while(i<j){
            do i++;while(arr[i]<x);
            do j--;while(arr[j]>x);
            //此時i指向的數(shù)字大于中軸數(shù)字, j指向數(shù)字小于中軸數(shù)字 交換
            if(i<j){
                int temp=arr[i];
                arr[i]=arr[j];
                arr[j]=temp;
            }
        }
        quickSort(arr,l,j);//退出循環(huán)是i==j 遞歸排序
        quickSort(arr,j+1,r);
    }

7.4 時間復雜度,空間復雜度以及穩(wěn)定性

  • 時間復雜度最好:O(nlog2n);
  • 時間復雜度最壞:O(n^2);
  • 時間復雜度平均:O(nlog2n);
  • 空間復雜度:O(nlog2n);
  • 穩(wěn)定性:不穩(wěn)定;

8.歸并排序

8.1 算法思想

將一個大的無序數(shù)組有序,我們可以把大的數(shù)組分成兩個,然后對這兩個數(shù)組分別進行排序,之后在把這兩個數(shù)組合并成一個有序的數(shù)組。由于兩個小的數(shù)組都是有序的,所以在合并的時候是很快的。

通過遞歸的方式將大的數(shù)組一直分割,直到數(shù)組的大小為 1,此時只有一個元素,那么該數(shù)組就是有序的了,之后再把兩個數(shù)組大小為1的合并成一個大小為2的,再把兩個大小為2的合并成4的 …… 直到全部小的數(shù)組合并起來。

8.2 動畫演示

img

8.3 代碼示例

public static void mergerSort(int[]arr){
        mergerSortInternal(arr,0,arr.length-1);
    }
public static void mergerSortInternal(int[]arr,int l,int r) {//
        if (l >= r) return;
        int mid = (l + r) / 2;//把數(shù)組分為兩個
        mergerSortInternal(arr, l, mid);//對左邊數(shù)組遞歸排序
        mergerSortInternal(arr, mid + 1, r);//對右邊數(shù)組遞歸排序
        merge(arr,l,mid,r);//排序完成,進行合并
    }
 public static void merge(int[]arr,int low,int mid,int high){
        int s1=low;//mid左側(cè)數(shù)組的頭和尾
        int e1=mid;
        int s2=mid+1;//mid右側(cè)數(shù)組的頭和尾
        int e2=high;
        int[]temp=new int[high-low+1];//定義一個數(shù)字,用來合并他們
        int k=0;//指示數(shù)組下標
        while(s1<=e1&&s2<=e2){//選出兩側(cè)數(shù)組最小元素 插入temp數(shù)組
            if(arr[s1]<=arr[s2]) temp[k++]=arr[s1++];
            else temp[k++]=arr[s2++];
        }
        while(s1<=e1) temp[k++]=arr[s1++];//如果一側(cè)數(shù)組插入完畢,另一側(cè)還有剩余,則全部插入
        while(s2<=e2) temp[k++]=arr[s2++];
        for(int i=0;i<temp.length;i++){//返還到arr數(shù)組
            arr[i+low]=temp[i];
        }
    }
}

8.4 時間復雜度,空間復雜度以及穩(wěn)定性

  • 時間復雜度最好:O(nlog2n);
  • 時間復雜度最壞:O(nlog2n);
  • 時間復雜度平均:O(nlog2n);
  • 空間復雜度:O(n);

到此這篇關于Java數(shù)據(jù)結構之基于比較的排序算法基本原理及具體實現(xiàn)的文章就介紹到這了,更多相關Java 排序算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • JDBC自定義連接池過程詳解

    JDBC自定義連接池過程詳解

    這篇文章主要介紹了JDBC自定義連接池過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-02-02
  • Java關鍵字volatile詳析

    Java關鍵字volatile詳析

    這篇文章主要介紹了Java關鍵字volatile,volatile關鍵字可以說是Java虛擬機提供的最輕量級的同步機制,但對于為什么它只能保證可見性,不保證原子性,它又是如何禁用指令重排的,還有很多同學沒徹底理解,文章會讓大家牢掌握一個Java核心知識點
    2022-01-01
  • 小白教程! Linux服務器上JDK安裝配置方法

    小白教程! Linux服務器上JDK安裝配置方法

    這篇文章主要為大家詳細介紹了Linux服務器上JDK安裝配置方法,小白教程!具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Java直接插入排序算法實現(xiàn)

    Java直接插入排序算法實現(xiàn)

    這篇文章主要介紹了Java直接插入排序算法實現(xiàn),有需要的朋友可以參考一下
    2014-01-01
  • Java設計圖形與多媒體處理

    Java設計圖形與多媒體處理

    本文主要介紹了Java的圖形設計以及多媒體處理,源碼也做了詳細的注釋,對于初學者應該不難。詳細請看下文
    2015-09-09
  • Spring?cloud如何實現(xiàn)FeignClient指定Zone調(diào)用

    Spring?cloud如何實現(xiàn)FeignClient指定Zone調(diào)用

    這篇文章主要介紹了Spring?cloud如何實現(xiàn)FeignClient指定Zone調(diào)用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • java獲取當前日期使用實例

    java獲取當前日期使用實例

    本文為大家介紹java日期的使用實例,日期輸出格式為date:2013-12-17,大家參考使用吧
    2014-01-01
  • springboot項目部署到k8s上的方法步驟

    springboot項目部署到k8s上的方法步驟

    本文主要介紹了springboot項目部署到k8s上的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-05-05
  • Java List轉(zhuǎn)換成String數(shù)組幾種實現(xiàn)方式詳解

    Java List轉(zhuǎn)換成String數(shù)組幾種實現(xiàn)方式詳解

    這篇文章主要介紹了Java List轉(zhuǎn)換成String數(shù)組幾種實現(xiàn)方式詳解的相關資料,需要的朋友可以參考下
    2016-12-12
  • java 實現(xiàn)比較版本號功能

    java 實現(xiàn)比較版本號功能

    本篇文章主要介紹了java 中涉及到客戶端的系統(tǒng)經(jīng)常需要用到比較版本號的功能,并附小示例,希望能幫助需要的小伙伴
    2016-07-07

最新評論

伊吾县| 孟州市| 镇赉县| 凤山市| 嵩明县| 徐汇区| 湖南省| 清丰县| 罗江县| 家居| 子洲县| 台东市| 卓尼县| 铜鼓县| 新龙县| 枞阳县| 邛崃市| 保山市| 黄龙县| 峨边| 宁强县| 龙口市| 桓仁| 衡阳县| 突泉县| 秦皇岛市| 通山县| 诸城市| 锦州市| 磐石市| 郓城县| 丰县| 泸西县| 来安县| 沙雅县| 济阳县| 同江市| 定西市| 舞钢市| 吉木萨尔县| 古丈县|