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

Java實(shí)現(xiàn)插入排序,希爾排序和歸并排序

 更新時(shí)間:2022年12月22日 11:05:37   作者:程序小猿2  
這篇文章主要為大家詳細(xì)介紹了插入排序,希爾排序和歸并排序的多種語言的實(shí)現(xiàn)(JavaScript、Python、Go語言、Java),感興趣的小伙伴可以了解一下

插入排序

插入排序的代碼實(shí)現(xiàn)雖然沒有冒泡排序和選擇排序那么簡(jiǎn)單粗暴,但它的原理應(yīng)該是最容易理解的了,因?yàn)橹灰蜻^撲克牌的人都應(yīng)該能夠秒懂。插入排序是一種最簡(jiǎn)單直觀的排序算法,它的工作原理是通過構(gòu)建有序序列,對(duì)于未排序數(shù)據(jù),在已排序序列中從后向前掃描,找到相應(yīng)位置并插入。

插入排序和冒泡排序一樣,也有一種優(yōu)化算法,叫做拆半插入。

算法步驟

1.將第一待排序序列第一個(gè)元素看做一個(gè)有序序列,把第二個(gè)元素到最后一個(gè)元素當(dāng)成是未排序序列。

2.從頭到尾依次掃描未排序序列,將掃描到的每個(gè)元素插入有序序列的適當(dāng)位置。(如果待插入的元素與有序序列中的某個(gè)元素相等,則將待插入元素插入到相等元素的后面。)

動(dòng)圖演示

JavaScript代碼實(shí)現(xiàn)

function insertionsort(arr){
    var len = arr.length;
    var preIndex,current;
    for(var i = 1;i < len;i++){
        preIndex = i - 1;
        current = arr[i];
        while(preIndex >= 0 && arr[preIndex] > current){
            arr[preIndex+1] = arr[preIndex];
            preIndex--;
        }
        arr[preIndex+1] = current;
    }
    return arr;
}    

Python代碼實(shí)現(xiàn)

def insertionSort(arr):
    for i in range(len(arr)):
        preIndex = i-1
        current = arr[i]
        while preIndex >= 0 and arr[preIndex] > current:
            arr[preIndex+1] = arr[preIndex]
            preIndex-=1
        arr[preIndex+1] = current
    return arr

Go代碼實(shí)現(xiàn)

func insertionSort(arr []int)[]int{
    for i := range arr {
        preIndex := i - 1
        current := arr[i]
        for preIndex >= 0 && arr[preIndex] > current {
            arr[preIndex+1] = arr[preIndex]
            preIndex -= 1
        }
        arr[preIndex+1] = current
    }
    return arr
}

Java代碼實(shí)現(xiàn)

public class InsertSort implements IArraySort {

    @Override
    public int[] sort(int[] sourceArray) throws Exception {
        //對(duì)arr進(jìn)行拷貝,不改變參數(shù)內(nèi)容
        int[] arr = Array.copyOf(sourceArray,sourceArray.length);
        
        //從下標(biāo)為1的元素開始選擇合適的位置插入,因?yàn)橄聵?biāo)為0的只有一個(gè)元素,默認(rèn)是有序的
        for(int i = 1;i < arr.length;i++{
        
            //記錄要插入的數(shù)據(jù)
            int temp = arr[i];
            
            //從已經(jīng)排序的序列最右邊開始比較,找到比其小的數(shù)
            int j = i;
            while(j > 0 && temp < arr[j - 1] {
                arr[j] = arr[j-1];
                j--;
            }
            
            //存在比其小的數(shù),插入
            if(j != i){
                arr[j] = temp;
            }
            
        }
        return arr;
    }
}    

希爾排序

希爾排序,也稱遞減增量排序算法,是插入排序的一種更高效的改進(jìn)版本。但希爾排序是非穩(wěn)定排序算法。

希爾排序是基于插入排序以下兩點(diǎn)性質(zhì)而提出改進(jìn)方法的:

  • 插入排序在對(duì)幾乎已經(jīng)排好序的數(shù)據(jù)操作時(shí),效率高,即可以達(dá)到線性排序的效率;
  • 但插入排序一般來說是低效的,因?yàn)椴迦肱判蛎看沃荒軐?shù)據(jù)移動(dòng)一位;

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

算法步驟

  • 選擇一個(gè)增量序列 t1,t2,……,tk,其中 ti > tj, tk = 1;
  • 按增量序列個(gè)數(shù) k,對(duì)序列進(jìn)行 k 趟排序;
  • 每趟排序,根據(jù)對(duì)應(yīng)的增量 ti,將待排序列分割成若干長(zhǎng)度為 m 的子序列,分別對(duì)各子表進(jìn)行直接插入排序。僅增量因子為 1 時(shí),整個(gè)序列作為一個(gè)表來處理,表長(zhǎng)度即為整個(gè)序列的長(zhǎng)度。

JavaScript代碼實(shí)現(xiàn)

function shellSort(arr) {
    var len = arr.length,
        temp,
        gap = 1;
    while(gap < len/3) { //動(dòng)態(tài)定義間隔序列
        gap =gap*3+1;
    }
    for (gap; gap > 0; gap = Math.floor(gap/3)) {
        for (var i = gap; i < len; i++) {
            temp = arr[i];
            for (var j = i-gap; j >= 0 && arr[j] > temp; j-=gap) {
                arr[j+gap] = arr[j];
            }
            arr[j+gap] = temp;
        }
    }
    return arr;
}

python代碼實(shí)現(xiàn)

def shellSort(arr):
    import math
    gap=1
    while(gap < len(arr)/3):
        gap = gap*3+1
    while gap > 0:
        for i in range(gap,len(arr)):
            temp = arr[i]
            j = i-gap
            while j >=0 and arr[j] > temp:
                arr[j+gap]=arr[j]
                j-=gap
            arr[j+gap] = temp
        gap = math.floor(gap/3)
    return arr
}

Go代碼實(shí)現(xiàn)

func shellSort(arr []int) []int {
    length := len(arr)
    gap := 1
    for gap < gap/3 {
        gap = gap*3 + 1
    }
    for gap > 0 {
        for i := gap; i < length; i++ {
            temp := arr[i]
            j := i - gap
            for j >= 0 && arr[j] > temp {
                arr[j+gap] = arr[j]
                j -= gap
            }
            arr[j+gap] = temp
        }
        gap = gap / 3
    }
    return arr
}

Java代碼實(shí)現(xiàn)

public class ShellSort implements IArraySort{

    @Override
    public int[] sort(int[] sourceArray) throws Exception{
        //對(duì)arr進(jìn)行拷貝,不改變參數(shù)內(nèi)容
        int[] arr = Arrays.copyOf(sourceArray,sourceArray.length);
        
        int gap = 1;
        while(gap < arr.length/3){
            gap = gap * 3 = 1;
        }
        
        while(gap > 0){
            for (int i = gap; i < arr.length; i++) {
                int tmp = arr[i];
                int j = i - gap;
                while (j >= 0 && arr[j] > tmp) {
                    arr[j + gap] = arr[j];
                    j -= gap;
                }
                arr[j + gap] = tmp;
            }
            gap = (int) Math.floor(gap / 3);
        }

        return arr;
    }
}

歸并排序

歸并排序(Merge sort)是建立在歸并操作上的一種有效的排序算法。該算法是采用分治法(Divide and Conquer)的一個(gè)非常典型的應(yīng)用。

作為一種典型的分而治之思想的算法應(yīng)用,歸并排序的實(shí)現(xiàn)由兩種方法:

  • 自上而下的遞歸(所有遞歸的方法都可以用迭代重寫,所以就有了第 2 種方法);
  • 自下而上的迭代;

在《數(shù)據(jù)結(jié)構(gòu)與算法 JavaScript 描述》中,作者給出了自下而上的迭代方法。但是對(duì)于遞歸法,作者卻認(rèn)為:

However, it is not possible to do so in JavaScript, as the recursion goes too deep for the language to handle.

然而,在 JavaScript 中這種方式不太可行,因?yàn)檫@個(gè)算法的遞歸深度對(duì)它來講太深了。

說實(shí)話,我不太理解這句話。意思是 JavaScript 編譯器內(nèi)存太小,遞歸太深容易造成內(nèi)存溢出嗎?還望有大神能夠指教。

和選擇排序一樣,歸并排序的性能不受輸入數(shù)據(jù)的影響,但表現(xiàn)比選擇排序好的多,因?yàn)槭冀K都是 O(nlogn) 的時(shí)間復(fù)雜度。代價(jià)是需要額外的內(nèi)存空間。

算法步驟

1.申請(qǐng)空間,使其大小為兩個(gè)已經(jīng)排序序列之和,該空間用來存放合并后的序列;

2.設(shè)定兩個(gè)指針,最初位置分別為兩個(gè)已經(jīng)排序序列的起始位置;

3.比較兩個(gè)指針?biāo)赶虻脑兀x擇相對(duì)小的元素放入到合并空間,并移動(dòng)指針到下一位置;

4.重復(fù)步驟 3 直到某一指針達(dá)到序列尾;

5.將另一序列剩下的所有元素直接復(fù)制到合并序列尾。

動(dòng)圖演示

JavaScript代碼實(shí)現(xiàn)

function mergeSort(arr) { // 采用自上而下的遞歸方法
    var len = arr.length;
    if(len < 2) {
        return arr;
    }
    var middle = Math.floor(len / 2),
        left = arr.slice(0, middle),
        right = arr.slice(middle);
    return merge(mergeSort(left), mergeSort(right));
}

function merge(left, right)
{
    var result = [];

    while (left.length && right.length) {
        if (left[0] <= right[0]) {
            result.push(left.shift());
        } else {
            result.push(right.shift());
        }
    }

    while (left.length)
        result.push(left.shift());

    while (right.length)
        result.push(right.shift());

    return result;
}

python代碼實(shí)現(xiàn)

def mergeSort(arr):
    import math
    if(len(arr)<2):
        return arr
    middle = math.floor(len(arr)/2)
    left, right = arr[0:middle], arr[middle:]
    return merge(mergeSort(left), mergeSort(right))
    
def merge(left,right):
    result = []
    while left and right:
        if left[0] <= right[0]:
            result.append(left.pop(0));
        else:
            result.append(right.pop(0));
    while left:
        result.append(left.pop(0));
    while right:
        result.append(right.pop(0));
    return result

Go代碼實(shí)現(xiàn)

func mergeSort(arr []int) []int {
    length := len(arr)
    if length < 2 {
        return arr
    }
    middle := length / 2
    left := arr[0:middle]
    right := arr[middle:]
    return merge(mergeSort(left), mergeSort(right))
}

func merge(left []int, right []int) []int {
    var result []int
    for len(left) != 0 && len(right) != 0 {
        if left[0] <= right[0] {
            result = append(result, left[0])
            left = left[1:]
        } else {
            result = append(result, right[0])
            right = right[1:]
        }
    }

    for len(left) != 0 {
        result = append(result, left[0])
        left = left[1:]
    }

    for len(right) != 0 {
        result = append(result, right[0])
        right = right[1:]
    }

    return result
}

Java代碼實(shí)現(xiàn)

public class MergeSort implements IArraySort {

    @Override
    public int[] sort(int[] sourceArray) throws Exception {
        // 對(duì) arr 進(jìn)行拷貝,不改變參數(shù)內(nèi)容
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

        if (arr.length < 2) {
            return arr;
        }
        int middle = (int) Math.floor(arr.length / 2);

        int[] left = Arrays.copyOfRange(arr, 0, middle);
        int[] right = Arrays.copyOfRange(arr, middle, arr.length);

        return merge(sort(left), sort(right));
    }

    protected int[] merge(int[] left, int[] right) {
        int[] result = new int[left.length + right.length];
        int i = 0;
        while (left.length > 0 && right.length > 0) {
            if (left[0] <= right[0]) {
                result[i++] = left[0];
                left = Arrays.copyOfRange(left, 1, left.length);
            } else {
                result[i++] = right[0];
                right = Arrays.copyOfRange(right, 1, right.length);
            }
        }

        while (left.length > 0) {
            result[i++] = left[0];
            left = Arrays.copyOfRange(left, 1, left.length);
        }

        while (right.length > 0) {
            result[i++] = right[0];
            right = Arrays.copyOfRange(right, 1, right.length);
        }

        return result;
    }

}

以上就是Java實(shí)現(xiàn)插入排序,希爾排序和歸并排序的詳細(xì)內(nèi)容,更多關(guān)于Java排序的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Springboot項(xiàng)目啟動(dòng)找不到啟動(dòng)類的解決

    Springboot項(xiàng)目啟動(dòng)找不到啟動(dòng)類的解決

    這篇文章主要介紹了Springboot項(xiàng)目啟動(dòng)找不到啟動(dòng)類的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Springboot工程中使用filter過程解析

    Springboot工程中使用filter過程解析

    這篇文章主要介紹了springboot工程中使用filter過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Java多線程常見案例分析線程池與單例模式及阻塞隊(duì)列

    Java多線程常見案例分析線程池與單例模式及阻塞隊(duì)列

    這篇文章主要介紹了多線程的常見案例,線程池(重點(diǎn))、單例模式、阻塞隊(duì)列,本文通過圖文實(shí)例相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-05-05
  • maven項(xiàng)目pom.xml中parent標(biāo)簽的使用小結(jié)

    maven項(xiàng)目pom.xml中parent標(biāo)簽的使用小結(jié)

    使用maven是為了更好的幫項(xiàng)目管理包依賴,maven的核心就是pom.xml,當(dāng)我們需要引入一個(gè)jar包時(shí),在pom文件中加上就可以從倉(cāng)庫(kù)中依賴到相應(yīng)的jar包,本文就來介紹一下maven項(xiàng)目pom.xml中parent標(biāo)簽的使用小結(jié),感興趣的可以了解一下
    2023-12-12
  • 帶你重新認(rèn)識(shí)MyBatis的foreach

    帶你重新認(rèn)識(shí)MyBatis的foreach

    這篇文章主要介紹了重新認(rèn)識(shí)MyBatis的foreach,本文提出了一種簡(jiǎn)化<foreach>寫法的設(shè)想,更重要的是通過解決空集時(shí)生成的SQL語法問題,更深刻地理解MyBatis的foreach的生成機(jī)制,需要的朋友可以參考下
    2022-11-11
  • SpringMVC實(shí)現(xiàn)上傳下載文件

    SpringMVC實(shí)現(xiàn)上傳下載文件

    這篇文章主要為大家詳細(xì)介紹了SpringMVC實(shí)現(xiàn)上傳下載文件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-09-09
  • Java找出1000以內(nèi)的所有完數(shù)

    Java找出1000以內(nèi)的所有完數(shù)

    一個(gè)數(shù)如果恰好等于它的因子之和,這個(gè)數(shù)就稱為 "完數(shù) "。例如6=1+2+3.編程找出1000以內(nèi)的所有完數(shù)
    2017-02-02
  • Mybatis源碼分析之存儲(chǔ)過程調(diào)用和運(yùn)行流程

    Mybatis源碼分析之存儲(chǔ)過程調(diào)用和運(yùn)行流程

    這一篇我們學(xué)習(xí)一下Mybatis調(diào)用存儲(chǔ)過程的使用和運(yùn)行流程,首先我們創(chuàng)建一個(gè)簡(jiǎn)單的存儲(chǔ)過程,具體創(chuàng)建過程大家可以通過本文學(xué)習(xí)下
    2016-11-11
  • 基于Apache組件分析對(duì)象池原理的實(shí)現(xiàn)案例分析

    基于Apache組件分析對(duì)象池原理的實(shí)現(xiàn)案例分析

    本文從對(duì)象池的一個(gè)簡(jiǎn)單案例切入,主要分析common-pool2組件關(guān)于:池、工廠、配置、對(duì)象管理幾個(gè)角色的源碼邏輯,并且參考其在Redis中的實(shí)踐,對(duì)Apache組件分析對(duì)象池原理相關(guān)知識(shí)感興趣的朋友一起看看吧
    2022-04-04
  • Java畢業(yè)設(shè)計(jì)實(shí)戰(zhàn)之寵物醫(yī)院與商城一體的系統(tǒng)的實(shí)現(xiàn)

    Java畢業(yè)設(shè)計(jì)實(shí)戰(zhàn)之寵物醫(yī)院與商城一體的系統(tǒng)的實(shí)現(xiàn)

    這是一個(gè)使用了java+Springboot+Jsp+maven+Mysql開發(fā)的寵物醫(yī)院與商城一體的系統(tǒng),是一個(gè)畢業(yè)設(shè)計(jì)的實(shí)戰(zhàn)練習(xí),具有寵物醫(yī)院和寵物商城該有的所有功能,感興趣的朋友快來看看吧
    2022-02-02

最新評(píng)論

贡山| 青铜峡市| 白河县| 龙门县| 芮城县| 平阳县| 孝义市| 策勒县| 云梦县| 漳州市| 阳城县| 岑巩县| 漳浦县| 镇宁| 忻城县| 通榆县| 玉门市| 永胜县| 桂林市| 鸡泽县| 安阳市| 高台县| 大丰市| 铜梁县| 台南市| 高安市| 保亭| 旌德县| 梁河县| 大同市| 密山市| 德州市| 公安县| 上思县| 景泰县| 房山区| 抚顺县| 龙游县| 马鞍山市| 英德市| 喜德县|