亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java重點(diǎn)之基于比較的七大排序

 更新時(shí)間:2021年10月08日 09:25:49   作者:小玄ks  
最近幾天在研究排序算法,看了很多博客,發(fā)現(xiàn)網(wǎng)上有的文章中對排序算法解釋的并不是很透徹,而且有很多代碼都是錯誤的,所以我根據(jù)這幾天看的文章,整理了一個(gè)較為完整的排序算法總結(jié),本文中的所有算法均有JAVA實(shí)現(xiàn),經(jīng)本人調(diào)試無誤后才發(fā)出,如有錯誤,請各位前輩指出

七大基于比較的排序

直接插入排序

思想:以雙指針來進(jìn)行遍歷數(shù)組和尋找較小元素的操作,每次找到較小元素的時(shí)候就將其插入到前面的適當(dāng)位置,當(dāng)遍歷完整個(gè)數(shù)組,并完成插入操作后,排序完成。

時(shí)間復(fù)雜度:最好情況:O(N)
最壞情況:O(N^2)
空間復(fù)雜度:O(1)
結(jié)論:當(dāng)一組數(shù)據(jù)趨近于有序,適用于插入排序

public static void insertSort(int[] array) {
        //該循環(huán)實(shí)現(xiàn)對整個(gè)數(shù)組的遍歷操作
        for (int i = 1; i < array.length; ++i) {
            
            //記錄將被插入的元素(i下標(biāo)元素)
            int tmp = array[i];
            //j指向i的前一個(gè)元素
            int j = i - 1;

            for (; j >= 0; j--) {
                //如果j指向的元素比被插入元素大,就往后移一位
                if (array[j] > tmp) {
                    array[j + 1] = array[j];
                } else {//否則就找到了插入位置,跳出該循環(huán)
                    break;
                }
            }

            
            //j+1即為插入位置
            array[j + 1] = tmp;
        }
}

希爾排序

思想:將數(shù)組不斷分組再進(jìn)行排序,當(dāng)分組的長度為1時(shí),進(jìn)行的就是直接插入排序。

時(shí)間復(fù)雜度:O(N1.3 ~ N1.5)
空間復(fù)雜度:O(1)

public static void shellSort(int[] array) {
        int gap = array.length;
        while (gap > 1) {
            //gap為1時(shí),就是直接插入排序
            gap = gap / 3 + 1;
            shell(array, gap);
        }
}
public static void shell(int[] array, int gap) {
        for (int i = gap; i < array.length; ++i) {
            int tmp = array[i];
            int j = i - gap;
            for (; j >= 0; j -= gap) {
                if (array[j] > tmp) {
                    array[j + gap] = array[j];
                } else {
                    break;
                }
            }
            array[j + gap] = tmp;
        }
}

選擇排序

思想:選擇排序是一種簡單直觀的排序算法。它的工作原理是:第一次從待排序的數(shù)據(jù)元素中選出最小(或最大)的一個(gè)元素,存放在序列的起始位置,然后再從剩余的未排序元素中尋找到最小(大)元素,繼續(xù)放在起始位置直到未排序元素個(gè)數(shù)為0。

時(shí)間復(fù)雜度:O(N2)

空間復(fù)雜度:O(N2)

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

堆排序

思想:從小到大排序,就先建一個(gè)大堆,堆頭元素就是整個(gè)數(shù)組中最大的數(shù),==因此我們每次將堆頭元素與堆尾元素交換,交換一次,堆尾下標(biāo)往前移動一位,形成一個(gè)新堆,再向下調(diào)整構(gòu)建成大堆;==以此循環(huán),直到堆尾下標(biāo)與堆頭下標(biāo)重合,堆排序完成。

時(shí)間復(fù)雜度:O(N*log N)

空間復(fù)雜度:O(1)

public static void heapSort(int[] array) {
        createHeap(array);//建大堆
        int end = array.length - 1;
    //將堆頭元素與堆尾元素互換位置,就將最大元素放到了最后一位,舍去最后一位小標(biāo)重新將堆向下調(diào)整;直到堆為空,數(shù)組中元素就排序完成。
        while (end >= 0) {
            int tmp = array[0];
            array[0] = array[end];
            array[end] = tmp;
            end--;
            siftDown(array, 0, end);
        }
    }
	//從小到大排序,建一個(gè)大堆
	public static void createHeap(int[] array) {
        for (int parent = (array.length - 1) / 2; parent >= 0; parent--) {
            siftDown(array, parent, array.length-1);
        }
    }

	//向下調(diào)整大堆
    public static void siftDown(int[] array, int root, int end) {
        int parent = root;
        int child = 2 * parent + 1;
        while (child <= end) {
            if (child + 1 <= end && array[child] < array[child + 1])
                child++;
            if (array[parent] < array[child]) {
                int tmp = array[parent];
                array[parent] = array[child];
                array[child] = tmp;
                parent = child;
                child = parent * 2 + 1;
            } else {
                break;
            }
        }
    }

冒泡排序

思想:相鄰的元素兩兩比較,較大的數(shù)下沉,較小的數(shù)冒起來,這樣一趟比較下來,最大(小)值就會排列在一端。該冒泡排序?yàn)閮?yōu)化過的排序,定義一個(gè)boolean類型的變量來判斷數(shù)組是否已經(jīng)有序,若有序可以直接返回,以此來減少時(shí)間復(fù)雜度。

時(shí)間復(fù)雜度:最壞:O(N2)

​ 最優(yōu):O(N)

空間復(fù)雜度:O(1)

 public static void bubbleSort(int[] array) {
     //最外層循環(huán)為比較的趟數(shù)
        for (int i = 0; i < array.length - 1; ++i) {
            //flag是為了判斷接下來的循環(huán)是否有必要進(jìn)行
            boolean flag = false;
            //內(nèi)層循環(huán)為每趟比較的次數(shù)
            for (int j = 0; j < array.length - 1 - i; ++j) {
                if (array[j] > array[j + 1]) {
                    int tmp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = tmp;
                    flag = true;
                }
            }
            //flag==false說明這趟循環(huán)沒有交換數(shù)據(jù),也就是說數(shù)組已經(jīng)有序,可以直接返回。
            if (flag == false) return;

        }
    }

快速排序

思想:先找到一個(gè)中間元素,將小于這個(gè)元素的數(shù)放到它的左邊,大于這個(gè)元素的數(shù)放到它的右邊,再將左右兩部分進(jìn)行上述操作,重復(fù)以往,就完成快排操作。
時(shí)間復(fù)雜度:最好:O(Nlog 2N)
最壞:O(N2)
時(shí)間復(fù)雜度平均:O(Nlog2N)
空間復(fù)雜度:O(Nlog2N)

public static void quickSort(int[] array, int l, int r) {
        if (l >= r) return;
    //因?yàn)橛胐o while()循環(huán),所以先將左右指針向兩邊移動一位
        int i = l - 1, j = r + 1;
    //取數(shù)組中間元素的值作為這個(gè)分割點(diǎn)
        int mid = array[(l + r)>>1];

        while (i < j) {
            //左邊的數(shù)小于中間值,指針向右移動
            do ++i; while (array[i] < mid);
            //右邊的數(shù)大于中間值,指針向左移動
            do --j; while (array[j] > mid);
            //兩個(gè)指針停下后交換元素
            if (i < j) {
                int tmp = array[i];
                array[i] = array[j];
                array[j] = tmp;
            }

        }
    //遞歸左半部分
        quickSort(array, l, j);
    //遞歸右半部分
        quickSort(array, j + 1, r);


    }

歸并排序

思想:先分組再排序,和快排操作順序相反。將數(shù)組分為左右兩部分,再對左右兩部分 分別再分組,以此類推,直到每一部分只有一個(gè)元素,然后按順序合并為一個(gè)個(gè)新的有序數(shù)組,小數(shù)組歸并為大數(shù)組,以此類推就得到排序后的數(shù)組。

時(shí)間復(fù)雜度:O(N*logN)

空間復(fù)雜度:O(N)

 public static void mergeSort(int[] array){
        mergerSortInternal(array,0,array.length-1);
    }
    public static void mergerSortInternal (int[] array,int l,int r){
        if(l>=r)    return;
        int mid = (l+r)>>1;
        //遞歸左半部分
        mergerSortInternal(array,l,mid);
        //遞歸右半部分
        mergerSortInternal(array,mid+1,r);
        //歸并
        merge(array,l,mid,r);
    }
    public static void merge(int[] array,int l,int mid, int r){
        int s1 = l,e1 = mid;
        int s2 = mid+1, e2 = r;
        int [] tmp = new int[r-l+1];
        int k = 0;
        //比較兩個(gè)有序小數(shù)組元素,將小的元素放到新數(shù)組前面,大的元素放到新數(shù)組后面
        while(s1<=e1 && s2<=e2){
            if(array[s1]<array[s2]){
                tmp[k++] = array[s1++];
            }else{
                tmp[k++] = array[s2++];
            }
        }
        //處理剩余元素
        while(s1<=e1)   tmp[k++] = array[s1++];
        while(s2<=e2)   tmp[k++] = array[s2++];
        //將排完序的新數(shù)組元素放回原數(shù)組中
        for(int i = 0;i<tmp.length;++i){
            array[i+l] = tmp[i];
        }
    }

到此這篇關(guān)于Java重點(diǎn)之基于比較的七大排序的文章就介紹到這了,更多相關(guān)Java 排序內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • spring-boot-maven-plugin:unknown的完美解決方法

    spring-boot-maven-plugin:unknown的完美解決方法

    這篇文章主要介紹了spring-boot-maven-plugin:unknown的完美解決方法,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • java 中maven pom.xml文件教程詳解

    java 中maven pom.xml文件教程詳解

    這篇文章主要介紹了java 中maven pom.xml文件教程詳解,非常不錯,具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-08-08
  • SpringBoot Actuator潛在的OOM問題的解決

    SpringBoot Actuator潛在的OOM問題的解決

    本文主要介紹了SpringBoot Actuator潛在的OOM問題的解決,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • Springboot項(xiàng)目對數(shù)據(jù)庫用戶名密碼實(shí)現(xiàn)加密過程解析

    Springboot項(xiàng)目對數(shù)據(jù)庫用戶名密碼實(shí)現(xiàn)加密過程解析

    這篇文章主要介紹了Springboot項(xiàng)目對數(shù)據(jù)庫用戶名密碼實(shí)現(xiàn)加密過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • SpringBoot可以同時(shí)處理多少請求流程分析

    SpringBoot可以同時(shí)處理多少請求流程分析

    SpringBoot默認(rèn)的內(nèi)嵌容器是Tomcat,也就是我們的程序?qū)嶋H上是運(yùn)行在Tomcat里的,所以與其說SpringBoot可以處理多少請求,到不如說Tomcat可以處理多少請求,這篇文章主要介紹了SpringBoot可以同時(shí)處理多少請求,需要的朋友可以參考下
    2023-02-02
  • SpringBoot整合MyBatis實(shí)現(xiàn)樂觀鎖和悲觀鎖的示例

    SpringBoot整合MyBatis實(shí)現(xiàn)樂觀鎖和悲觀鎖的示例

    這篇文章主要介紹了SpringBoot整合MyBatis實(shí)現(xiàn)樂觀鎖和悲觀鎖的示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Character.UnicodeBlock中cjk的說明詳解

    Character.UnicodeBlock中cjk的說明詳解

    這篇文章主要為大家詳細(xì)介紹了Character.UnicodeBlock中cjk的說明,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • idea中如何連接hive

    idea中如何連接hive

    這篇文章主要介紹了idea中如何連接hive問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Spring循環(huán)依賴的解決方法詳解

    Spring循環(huán)依賴的解決方法詳解

    Spring的解決循環(huán)依賴是有前置條件的,要解決循環(huán)依賴我們首先要了解Spring Bean對象的創(chuàng)建過程和依賴注入的方式。依賴注入方式,我之前的博客有所分享,大家可以在看本篇文章之前進(jìn)行一下小小的回顧
    2022-08-08
  • Spring五大類注解讀取存儲Bean對象的方法

    Spring五大類注解讀取存儲Bean對象的方法

    這篇文章主要介紹了Spring五大類注解讀取存儲Bean對象,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-09-09

最新評論