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

Java深入了解數(shù)據(jù)結(jié)構(gòu)中常見的排序算法

 更新時間:2022年01月27日 16:26:20   作者:/少司命  
這篇文章主要介紹了Java常用的排序算法及代碼實(shí)現(xiàn),在Java開發(fā)中,對排序的應(yīng)用需要熟練的掌握,這樣才能夠確保Java學(xué)習(xí)時候能夠有扎實(shí)的基礎(chǔ)能力。那Java有哪些排序算法呢?本文小編就來詳細(xì)說說Java常見的排序算法,需要的朋友可以參考一下

一,概念

1,排序

排序,就是使一串記錄,按照其中的某個或某些關(guān)鍵字的大小,遞增或遞減的排列起來的操作。 平時的上下文中,如果提到排序,通常指的是排升序(非降序)。 通常意義上的排序,都是指的原地排序(in place sort)。

2,穩(wěn)定性

兩個相等的數(shù)據(jù),如果經(jīng)過排序后,排序算法能保證其相對位置不發(fā)生變化,則我們稱該算法是具備穩(wěn)定性的排序算法。

或者我們說沒有跳躍的排序也是穩(wěn)定的排序

二,排序詳解

1,插入排序

①直接插入排序

整個區(qū)間被分為

               1. 有序區(qū)間

               2. 無序區(qū)間

每次選擇無序區(qū)間的第一個元素,在有序區(qū)間內(nèi)選擇合適的位置插入

 public static void main(String[] args) {
 
        int[] array = {12,5,9,34,6,8,33,56,89,0,7,4,22,55,77};
        insertSort(array);
        System.out.println(Arrays.toString(array));
    }
  /**
     * 時間復(fù)雜度:
     *        最好:O(N)   -> 數(shù)據(jù)是有序的
     *        最壞:O(N^2) -> 無序的數(shù)據(jù)
     * 空間復(fù)雜度:O(1)
     * 穩(wěn)定性:穩(wěn)定排序
     * @param array
     */
public static void insertSort(int[] array) {
        for(int i = 1;i < array.length;i++) {//n-1
            int tmp = array[i];
            int j = i-1;
            for(; j >= 0;j--) {//n-1
                if(array[j] > tmp) {
                    array[j+1] = array[j];
                }else{
                    //array[j+1] = tmp;
                    break;
                }
            }
            array[j+1] = tmp;
        }
    }

②希爾排序

希爾排序法又稱縮小增量法。希爾排序法的基本思想是:先選定一個整數(shù),把待排序文件中所有記錄分成個組,所有 距離為的記錄分在同一組內(nèi),并對每一組內(nèi)的記錄進(jìn)行排序。然后,取,重復(fù)上述分組和排序的工作。當(dāng)?shù)竭_(dá)=1時, 所有記錄在統(tǒng)一組內(nèi)排好序。

1. 希爾排序是對直接插入排序的優(yōu)化。

2. 當(dāng)gap > 1時都是預(yù)排序,目的是讓數(shù)組更接近于有序。當(dāng)gap == 1時,數(shù)組已經(jīng)接近有序的了,這樣就會很 快。這樣整體而言,可以達(dá)到優(yōu)化的效果。我們實(shí)現(xiàn)后可以進(jìn)行性能測試的對比。

   /**
     * 時間復(fù)雜度:不好算  n^1.3 - n^1.5 之間
     * 空間復(fù)雜度:O(1)
     * 穩(wěn)定性:不穩(wěn)定的排序
     *      技巧:如果在比較的過程當(dāng)中 沒有發(fā)生跳躍式的交換 那么就是穩(wěn)定的
     * @param array
     *
     *
     * @param array 排序的數(shù)組
     * @param gap   每組的間隔  -》 組數(shù)
     */
    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;
        }
    }
public static void main(String[] args) {
 
        int[] array = {12,5,9,34,6,8,33,56,89,0,7,4,22,55,77};
        shell(array,5);
        System.out.println(Arrays.toString(array));
    }

2,選擇排序

①直接選擇排序

每一次從無序區(qū)間選出最大(或最?。┑囊粋€元素,存放在無序區(qū)間的最后(或最前),直到全部待排序的數(shù)據(jù)元素排完 。

public static void main(String[] args) {
 
        int[] array = {12,5,9,34,6,8,33,56,89,0,7,4,22,55,77};
        selectSort(array);
        System.out.println(Arrays.toString(array));
    }
  /**
     * 時間復(fù)雜度:
     *      最好:O(N^2)
     *      最壞:O(N^2)
     * 空間復(fù)雜度:O(1)
     * 穩(wěn)定性:不穩(wěn)定的
     * @param array
     */
    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;
                }
            }
        }
    }

②堆排序

基本原理也是選擇排序,只是不在使用遍歷的方式查找無序區(qū)間的最大的數(shù),而是通過堆來選擇無序區(qū)間的最大的數(shù)。

注意: 排升序要建大堆;排降序要建小堆。

  public static void main(String[] args) {
 
        int[] array = {12,5,9,34,6,8,33,56,89,0,7,4,22,55,77};
        heapSort(array);
        System.out.println(Arrays.toString(array));
    }
   public static void siftDown(int[] array,int root,int len) {
        int parent = root;
        int child = 2*parent+1;
        while (child < len) {
            if(child+1 < len && array[child] < array[child+1]) {
                child++;
            }
            //child的下標(biāo)就是左右孩子的最大值下標(biāo)
            if(array[child] > array[parent]) {
                int tmp = array[child];
                array[child] = array[parent];
                array[parent] = tmp;
                parent = child;
                child = 2*parent+1;
            }else {
                break;
            }
        }
    }
 
    public static void createHeap(int[] array) {
        //從小到大排序 -》 大根堆
        for (int i = (array.length-1 - 1) / 2;  i >= 0 ; i--) {
            siftDown(array,i,array.length);
        }
    }
 
    /**
     * 時間復(fù)雜度:O(N*logN)  都是這個時間復(fù)雜度
     * 復(fù)雜度:O(1)
     * 穩(wěn)定性:不穩(wěn)定的排序
     * @param array
     */
    public static void heapSort(int[] array) {
        createHeap(array);//O(n)
        int end = array.length-1;
        while (end > 0) {//O(N*logN)
            int tmp = array[end];
            array[end] = array[0];
            array[0] = tmp;
            siftDown(array,0,end);
            end--;
        }
    }

3,交換排序

①冒泡排序

在無序區(qū)間,通過相鄰數(shù)的比較,將最大的數(shù)冒泡到無序區(qū)間的最后,持續(xù)這個過程,直到數(shù)組整體有序

 public static void main(String[] args) {
 
        int[] array = {12,5,9,34,6,8,33,56,89,0,7,4,22,55,77};
         bubbleSort(array);
        System.out.println(Arrays.toString(array));
    }
   /**
     * 時間復(fù)雜度:
     *         最好最壞都是O(n^2) 
     * 空間復(fù)雜度:O(1)
     * 穩(wěn)定性:穩(wěn)定的排序
     *      冒泡  直接插入
     * @param array
     */
    public static void bubbleSort(int[] array) {
        for (int i = 0; i < array.length-1; i++) {
            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;
 
                }
            }
        }
    }

②快速排序

1. 從待排序區(qū)間選擇一個數(shù),作為基準(zhǔn)值(pivot);

2. Partition: 遍歷整個待排序區(qū)間,將比基準(zhǔn)值小的(可以包含相等的)放到基準(zhǔn)值的左邊,將比基準(zhǔn)值大的(可 以包含相等的)放到基準(zhǔn)值的右邊;

3. 采用分治思想,對左右兩個小區(qū)間按照同樣的方式處理,直到小區(qū)間的長度 == 1,代表已經(jīng)有序,或者小區(qū)間 的長度 == 0,代表沒有數(shù)據(jù)。

public static void main(String[] args) {
 
        int[] array = {12,5,9,34,6,8,33,56,89,0,7,4,22,55,77};
        quickSort1(array);
        System.out.println(Arrays.toString(array));
    }
public static int partition(int[] array,int low,int high) {
        int tmp = array[low];
        while (low < high) {
            while (low < high && array[high] >= tmp) {
                high--;
            }
            array[low] = array[high];
            while (low < high && array[low] <= tmp) {
                low++;
            }
            array[high] = array[low];
        }
        array[low] = tmp;
        return low;
    }
 public static void quick(int[] array,int start,int end) {
        if(start >= end) {
            return;
        }
        int mid = (start+end)/2;
        int pivot = partition(array,start,end);
        quick(array,start,pivot-1);
        quick(array,pivot+1,end);
    }
 
    /**
     * 時間復(fù)雜度:
     *         最好:O(n*logn)  均勻的分割下
     *         最壞:o(n^2)     數(shù)據(jù)有序的時候
     * 空間復(fù)雜度:
     *        最好:logn
     *        最壞:O(n)
     * 穩(wěn)定性:不穩(wěn)定的排序
     *
     * k*n*logn
     * 2
     * 1.2
     * @param array
     */
    public static void quickSort1(int[] array) {
        quick(array,0,array.length-1);
    }

4,歸并排序

歸并排序(MERGE-SORT)是建立在歸并操作上的一種有效的排序算法,該算法是采用分治法(Divide and Conquer)的一個非常典型的應(yīng)用。將已有序的子序列合并,得到完全有序的序列;即先使每個子序列有序,再使子 序列段間有序。若將兩個有序表合并成一個有序表,稱為二路歸并。

 public static void main(String[] args) {
 
        int[] array = {12,5,9,34,6,8,33,56,89,0,7,4,22,55,77};
        mergeSort1(array);
        System.out.println(Arrays.toString(array));
    }
public static void merge(int[] array,int low,int mid,int high) {
        int s1 = low;
        int e1 = mid;
        int s2 = mid+1;
        int e2 = high;
        int[] tmp = new int[high-low+1];
        int k = 0;//代表tmp數(shù)組的下標(biāo)
        while (s1 <= e1 && s2 <= e2) {
            if(array[s1] <= array[s2]) {
                tmp[k++] = array[s1++];
            }else {
                tmp[k++] = array[s2++];
            }
        }
 
        //有2種情況
        while (s1 <= e1){
            //說明第2個歸并段沒有了數(shù)據(jù) 把第1個歸并段剩下的數(shù)據(jù) 全部拷貝過來
            tmp[k++] = array[s1++];
        }
 
        while (s2 <= e2) {
            //說明第1個歸并段沒有了數(shù)據(jù) 把第2個歸并段剩下的數(shù)據(jù) 全部拷貝過來
            tmp[k++] = array[s2++];
        }
        //tmp數(shù)組當(dāng)中 存儲的就是當(dāng)前歸并好的數(shù)據(jù)
 
        for (int i = 0; i < tmp.length; i++) {
            array[i+low] = tmp[i];
        }
    }
    public static void mergeSortInternal(int[] array,int low,int high) {
        if(low >= high) {
            return;
        }
        int mid = (low+high) / 2;
        mergeSortInternal(array,low,mid);
        mergeSortInternal(array,mid+1,high);
        //合并的過程
        merge(array,low,mid,high);
    }
 
    /**
     * 時間復(fù)雜度: O(N*log n)
     * 空間復(fù)雜度:O(N)
     * 穩(wěn)定性:穩(wěn)定的
     * @param array
     */
    public static void mergeSort1(int[] array) {
        mergeSortInternal(array, 0,array.length-1);
    }

到此這篇關(guān)于Java深入了解數(shù)據(jù)結(jié)構(gòu)中常見的排序算法的文章就介紹到這了,更多相關(guān)Java 排序算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JWT登錄認(rèn)證Springboot詳解

    JWT登錄認(rèn)證Springboot詳解

    文章主要介紹了如何在Java項(xiàng)目中使用JWT進(jìn)行用戶認(rèn)證和授權(quán),通過定義一個常量,編寫JWT工具類來生成和解析token,登錄時在服務(wù)端生成token并返回給客戶端,客戶端使用攔截器攔截請求,驗(yàn)證token的有效性,從而實(shí)現(xiàn)權(quán)限控制,文章旨在分享個人經(jīng)驗(yàn),為開發(fā)者提供參考
    2024-11-11
  • Spring中SmartLifecycle和Lifecycle的作用和區(qū)別

    Spring中SmartLifecycle和Lifecycle的作用和區(qū)別

    這篇文章主要介紹了Spring中SmartLifecycle和Lifecycle的作用和區(qū)別,本文通過實(shí)例代碼給大家介紹的非常詳細(xì)對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • Java讀取properties文件之中文亂碼問題及解決

    Java讀取properties文件之中文亂碼問題及解決

    這篇文章主要介紹了Java讀取properties文件之中文亂碼問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • Java版學(xué)生管理系統(tǒng)

    Java版學(xué)生管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了Java版學(xué)生管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • spring中BeanUtils.copyProperties的使用(深拷貝,淺拷貝)

    spring中BeanUtils.copyProperties的使用(深拷貝,淺拷貝)

    本文主要介紹了spring中BeanUtils.copyProperties的使用(深拷貝,淺拷貝),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • Java String 字符串常量池解析

    Java String 字符串常量池解析

    這篇文章主要介紹了Java String 字符串常量池解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Java中將 int[] 數(shù)組 轉(zhuǎn)換為 List分享

    Java中將 int[] 數(shù)組 轉(zhuǎn)換為 List分享

    這篇文章主要介紹了Java中將 int[] 數(shù)組 轉(zhuǎn)換為 List分享的相關(guān)資料,需要的朋友可以參考下
    2022-12-12
  • Java編程在方法中哪些時候需要參數(shù)

    Java編程在方法中哪些時候需要參數(shù)

    這篇文章主要介紹了Java編程在方法中哪些時候需要參數(shù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Java 中的字符串替換方法之replace, replaceAll 和 replaceFirst示例詳解

    Java 中的字符串替換方法之replace, replaceAll 和 rep

    在Java中,字符串的替換是一種常見的操作,特別是在處理文本和格式化輸出時,本文將詳細(xì)討論這些方法的用法、區(qū)別以及示例,感興趣的朋友一起看看吧
    2024-12-12
  • 解決spring boot 配置文件后綴的一個坑

    解決spring boot 配置文件后綴的一個坑

    這篇文章主要介紹了spring boot 配置文件后綴的一個坑,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09

最新評論

平乐县| 抚顺市| 武安市| 乌兰县| 南平市| 婺源县| 姚安县| 剑河县| 措勤县| 安陆市| 呼图壁县| 进贤县| 湘潭市| 兴山县| 衡水市| 班玛县| 万宁市| 景谷| 曲阜市| 蓬溪县| 东山县| 永康市| 峡江县| 泌阳县| 纳雍县| 永吉县| 邯郸市| 云霄县| 松滋市| 志丹县| 锡林郭勒盟| 同德县| 堆龙德庆县| 永福县| 金川县| 丹巴县| 保靖县| 靖边县| 顺平县| 永德县| 威宁|