欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java內(nèi)部排序之插入排序與交換排序詳解

 更新時(shí)間:2023年12月08日 08:44:30   作者:菜鳥(niǎo)-小胖  
這篇文章主要介紹了Java內(nèi)部排序之插入排序與交換排序詳解,排序是將任意序列重新排列按照關(guān)鍵字有序,排序根基存儲(chǔ)器的不同分為內(nèi)部排序、外部排序,排序根據(jù)關(guān)鍵字分為穩(wěn)定排序、不穩(wěn)定排序,需要的朋友可以參考下

內(nèi)部排序

排序:將任意序列重新排列按照關(guān)鍵字有序;

排序根基存儲(chǔ)器的不同分為:內(nèi)部排序、外部排序;(這里指的都是內(nèi)部排序)

排序根據(jù)關(guān)鍵字分為:穩(wěn)定排序、不穩(wěn)定排序

排序根據(jù)不同的原則分為:插入排序、交換排序、選擇排序、歸并排序、基數(shù)排序;

排序根據(jù)時(shí)間復(fù)雜度分為:簡(jiǎn)單排序(O(N2))、先進(jìn)排序(O(nlogn))、基數(shù)排序(O(d*n))

排序的操作:比較、移動(dòng) 被稱(chēng)為基于比較的排序;

假設(shè)這里使用的存儲(chǔ)結(jié)構(gòu)均為:順序存儲(chǔ)結(jié)構(gòu);

內(nèi)部排序:

1、插入排序:直接插入排序、折半插入、2-路插入排序、希爾排序

2、交換排序:冒泡排序、快速排序

3、選擇排序:簡(jiǎn)單選擇排序、堆排序

4、歸并排序

5、基數(shù)排序

插入排序

1直接插入排序

由n-1趟排序組成; 對(duì)于P=1趟到P=N-1趟,插入排序保證從位置0到位置P上的元素為已排序狀態(tài);

第P趟,我們將位置P上的元素向左移動(dòng)到它在前P+1個(gè)元素中正確位置上。(這里需要使用一個(gè)哨兵元素)

直接插入程序示例:

public class InserSort {
    public static void insertSort(int a[]){
      int temp;//哨兵
      int i;//執(zhí)行趟數(shù)
      int j;
      for (i = 1; i < a.length; i++) {//執(zhí)行N-1趟
          temp=a[i];
        for ( j = i-1; (j >=0)&&(a[j]>temp); j--) {
            a[j+1]=a[j];
        }
        a[j+1]=temp;
    }
    }
    public static void main(String[] args) {
        int a[]={9,6,3,2,7,5};
        InserSort.insertSort(a);
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]);
        }
    }
}

算法分析:

排序的操作:比較、移動(dòng)

1、空間復(fù)雜度: 只需要一個(gè)記錄的輔助空間;

2、時(shí)間復(fù)雜度:O(N2) 如果已有序時(shí)間復(fù)雜度為:O(N)

3、適應(yīng)場(chǎng)景:數(shù)據(jù)量不是很大 、基本有序

2 折半插入排序

將查找工作交與“折半查找”來(lái)實(shí)現(xiàn)。定位后,后續(xù)移動(dòng)元素。

public class BInsertSort {
/**
* 折半插入排序
* @param a
*/
    public static void BinsertSort(int a[]){
        int temp;//哨兵
        for (int i = 1; i < a.length; i++) {
            temp=a[i];
            int low=0;
            int hight=i-1;
            //查詢(xún)
            while (low<=hight) {
                int mad=(low+hight)/2;
                if (a[mad]>a[i]) {
                    hight=mad-1;
                }
                if (a[mad]<a[i]) {
                    low=mad+1;
                }
            }   
            //移動(dòng)
            for (int k = i-1; k >=hight+1; k--) {
                a[k+1]=a[k];
            }
            a[hight+1]=temp;
        }
    }
    public static void main(String[] args) {
        int a[]={9,6,3,2,7,5};
        BInsertSort.BinsertSort(a);
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]);
        }
    }
}

折半插入排序減少關(guān)鍵字的比較次數(shù),但是記錄的移動(dòng)次數(shù)沒(méi)有改變。

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

3 希爾排序(縮小增量排序)

基本思想:先將整個(gè)待排序記錄序列分割成為若干子序列分別進(jìn)行直接插入排序,待整個(gè)序列中的記錄“基本有序”時(shí),在對(duì)整個(gè)記錄進(jìn)行一次直接插入排序。

希爾排序使用一個(gè)序列,叫做增量序列。

序列最終值為1 PS:增量序列中的值沒(méi)有除1之外的公因子,并且最后一個(gè)增量必須等于1;

算法示例: 增量序列最流行的選擇是使用shell建議的序列N/2

public class ShellSort {
    /**
     * 希爾排序
     * @param a
     */
    public static void shellSort(int a[]){
        int i,j;
        int inc;//增量
        int temp;//哨兵
        for ( inc = a.length/2; inc >0; inc/=2) {//設(shè)置增量隊(duì)列
            //一趟希爾排序
            for ( i = inc; i < a.length; i++) {
                temp=a[i];
                for ( j = i; j >= inc; j-=inc) {
                    if (temp<a[j-inc]) {
                        a[j]=a[j-inc];
                    }else {
                        break;
                    }
                }
                a[j]=temp;
            }
        }
    }
    public static void main(String[] args) {
        int a[]={9,6,3,2,7,5};
        shellSort(a);
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]);
        }
    }
}

算法分析: 希爾排序的運(yùn)算時(shí)間依賴(lài)于增量序列的選擇,最壞情況O(N2)

使用場(chǎng)景: 適度地大量的輸入數(shù)據(jù)

交換排序

交換排序:冒泡排序、快速排序

1 冒泡排序

思路: 一趟排序:將第一個(gè)記錄的關(guān)鍵字與第二個(gè)關(guān)鍵字進(jìn)行比較,若為逆序記錄交換,然后比較第二個(gè)與第三個(gè),以此類(lèi)推,直到地N-1個(gè)記錄與N個(gè)記錄比較位置。

其結(jié)果使得最大的記錄安置在最后一個(gè)記錄位置; 第二趟對(duì)n-1個(gè)記錄進(jìn)行冒泡排序。

判斷冒泡排序結(jié)束的條件:在一趟排序中沒(méi)有進(jìn)行過(guò)交換記錄的操作。 算法演示:

public class BubbleSort {
    /**
     * 冒泡排序
     * @param a
     */
    public static void bubbleSort(int a[]){
         int temp=0;
         int log=0;//1表示有交換 0表示沒(méi)有交換  作為結(jié)束標(biāo)識(shí)
        for (int i = a.length-1; i >1; i--) {
            for (int j = 0; j < i; j++) {
                if (a[j+1]<a[j]) {
                    temp=a[j+1];
                    a[j+1]=a[j];
                    a[j]=temp;
                    log=1;
                }
            }
            if (log==0) {
                break;
            }
        }
    }
    public static void main(String[] args) {
        int a[]={2,3,5,6,7,9};
        BubbleSort.bubbleSort(a);
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]);
        }
    }
}

算法分析: 時(shí)間復(fù)雜度:O(N2)

2快速排序

快速排序(Quick Sort)的基本思想:通過(guò)一趟排序?qū)⒋庞涗浄指畛瑟?dú)立的兩部分,其中一部分記錄的關(guān)鍵字均比另一部分記錄的關(guān)鍵字小,則可分別對(duì)這兩部分記錄繼續(xù)進(jìn)行排序,以達(dá)到整個(gè)序列有序。

首先選擇一個(gè)記錄(可選擇第一個(gè)記錄,不是最佳的做法)作為支點(diǎn)(pivot),然后按下述原則重新排列其余記錄:將所有關(guān)鍵字較它小的記錄都安置在它的位置之前,將所有關(guān)鍵字較它大的記錄都安置在它位置之后。

由此可以該支點(diǎn)記錄最后所落的位置i作為分界線,這就是一趟快速排序。 具體做法:附設(shè)兩個(gè)指針low和high,它們的初值分別指向序列的前端與后端,設(shè)支點(diǎn)的記錄關(guān)鍵字為pivotkey,則首先從high所指位置起向前搜索找到第一個(gè)關(guān)鍵字小于pivotkey的記錄和支點(diǎn)記錄交換,然后從low所指位置起向后搜索,找到第一個(gè)關(guān)鍵字大于pivotkey的記錄和支點(diǎn)記錄相互交換,重復(fù)這兩步直到low=high為止。

算法示例:

public class QuickSort {
    /**
     * 一趟快排序
     */
    public static int partition(int a[],int low ,int high) {
        int temp = a[low];// 支點(diǎn)
        while (low < high) {
            while ((low < high)&&(a[high] >= temp) ) {
                high--;
            }
            a[low]=a[high];
            while ((low < high)&&(a[low] <= temp)) {
                low++;
            }
            a[high]=a[low];
        }
        a[low]=temp;
        return low;
    }
    /**
     * 遞歸排序
     * @param a
     * @param low
     * @param high
     */
    public static void QSort(int a[],int low,int high){
        //對(duì)子序列進(jìn)行排序
        if (low<high) {
            int pivot=partition(a, low , high);
            QSort(a,low, pivot-1);
            QSort(a,pivot+1,high);
        }
    }
    /**
     * 快速排序
     * @param a
     */
    public static void QuickSort(int a[]){
            QSort(a, 0, a.length-1);
    }
    //測(cè)試
    public static void main(String[] args) {
        int a[]={7,6,3,8,4,9,7};
        QuickSort.QuickSort(a);
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]);
        }
    }
}

算法分析:

1、時(shí)間復(fù)雜度: 快速排序的平均時(shí)間為:O(nlogn) 就平均時(shí)間而言,快排序是目前被認(rèn)為最好的一種內(nèi)部排序方法; 較壞的情況:當(dāng)關(guān)鍵字基本有序或者有序時(shí),快速排序?qū)⑼凶優(yōu)槊芭菖判颍瑫r(shí)間復(fù)雜度:O(n2); 支點(diǎn)的選取可以?xún)?yōu)化該算法,一般認(rèn)為“三者取中”的做法最合適:即a[i],a[j],a[(i+j)/2],取三者的中值。這樣可以改善最壞情況下的性能。

2、空間復(fù)雜度: 平均空間復(fù)雜度為:O(log2N) 因?yàn)榭焖倥判蛐枰粋€(gè)??臻g來(lái)實(shí)現(xiàn)遞歸。 一般如果一趟排序記錄均勻分布在支點(diǎn)兩側(cè),棧的深度為log2N+1 最壞情況,一趟排序后,都跑到一端空間,深度為N 降低空間復(fù)雜度的方法: 在一趟排序之后比較分割所得兩部分的長(zhǎng)度,且先對(duì)長(zhǎng)度短的子序列中的記錄進(jìn)行快速排序,則棧的最大深度可降為O(logn).

到此這篇關(guān)于Java內(nèi)部排序之插入排序與交換排序詳解的文章就介紹到這了,更多相關(guān)Java插入排序與交換排序內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java詳細(xì)分析梳理垃圾回收機(jī)制

    Java詳細(xì)分析梳理垃圾回收機(jī)制

    垃圾回收,顧名思義,便是將已經(jīng)分配出去的,但卻不再使用的內(nèi)存回收回來(lái),以便能夠再次分配。在?Java?虛擬機(jī)的語(yǔ)境下,垃圾指的是死亡的對(duì)象所占據(jù)的堆空間
    2022-04-04
  • 如何替換@PathVariable中的變量

    如何替換@PathVariable中的變量

    這篇文章主要介紹了如何替換@PathVariable中的變量,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • mybatis注解開(kāi)發(fā) 一對(duì)多嵌套查詢(xún)方式

    mybatis注解開(kāi)發(fā) 一對(duì)多嵌套查詢(xún)方式

    這篇文章主要介紹了mybatis注解開(kāi)發(fā) 一對(duì)多嵌套查詢(xún)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。
    2023-03-03
  • FastDFS分布式文件系統(tǒng)環(huán)境搭建及安裝過(guò)程解析

    FastDFS分布式文件系統(tǒng)環(huán)境搭建及安裝過(guò)程解析

    這篇文章主要介紹了FastDFS分布式文件系統(tǒng)環(huán)境搭建及安裝過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • springboot序列化和反序列化器配置方法

    springboot序列化和反序列化器配置方法

    這篇文章主要介紹了springboot序列化和反序列化器配置方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • Java實(shí)現(xiàn)Excel導(dǎo)入導(dǎo)出的步驟詳解

    Java實(shí)現(xiàn)Excel導(dǎo)入導(dǎo)出的步驟詳解

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)Excel的導(dǎo)入、導(dǎo)出,文中示例代碼介紹的非常詳細(xì),對(duì)我們的學(xué)習(xí)或工作有一定的幫助,感興趣的小伙伴們可以參考一下
    2023-06-06
  • 一文詳解Spring構(gòu)造函數(shù)推斷

    一文詳解Spring構(gòu)造函數(shù)推斷

    這篇文章主要介紹了Spring構(gòu)造函數(shù)推斷自動(dòng)注入及底層原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加
    2023-04-04
  • 使用Spring AOP實(shí)現(xiàn)MySQL數(shù)據(jù)庫(kù)讀寫(xiě)分離案例分析(附demo)

    使用Spring AOP實(shí)現(xiàn)MySQL數(shù)據(jù)庫(kù)讀寫(xiě)分離案例分析(附demo)

    分布式環(huán)境下數(shù)據(jù)庫(kù)的讀寫(xiě)分離策略是解決數(shù)據(jù)庫(kù)讀寫(xiě)性能瓶頸的一個(gè)關(guān)鍵解決方案,這篇文章主要介紹了使用Spring AOP實(shí)現(xiàn)MySQL數(shù)據(jù)庫(kù)讀寫(xiě)分離案例分析(附demo),有興趣的可以了解一下。
    2017-01-01
  • java基于遞歸算法實(shí)現(xiàn)漢諾塔問(wèn)題實(shí)例

    java基于遞歸算法實(shí)現(xiàn)漢諾塔問(wèn)題實(shí)例

    這篇文章主要介紹了java基于遞歸算法實(shí)現(xiàn)漢諾塔問(wèn)題,結(jié)合具體實(shí)例形式分析了java遞歸算法的實(shí)現(xiàn)與使用技巧,需要的朋友可以參考下
    2017-07-07
  • Java全面解析string類(lèi)型的xml字符串

    Java全面解析string類(lèi)型的xml字符串

    這篇文章主要介紹了Java全面解析string類(lèi)型的xml字符串,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03

最新評(píng)論