1. 程式人生 > >歸併排序的實現

歸併排序的實現

原理

歸併的意思是將兩個有序的線性表組合成一個新的有序線性表。是基於分治思想的排序演算法,它在遞迴到對陣列的l到r的位置之間的數進行排序時,首先根據中間位置 mid=(l+r)/2 分成兩半,然後遞迴分別對左邊一半和右邊一半進行歸併排序,最後對兩個已排序好的一半進行合併。(穩定)
其中主要的部分是對兩個有序陣列的合併,複雜度為O(n)。以下將合併的部分程式碼專門寫成一個函式

function merge1(arr, left, mid, right) {
    // 兩個陣列: arr[left..mid], arr[mid+1..right], 都是有序的
    var n = right-left+1
; // 兩個陣列的總長度 var temp = []; // 用來儲存元素的臨時陣列 var l = left, r = mid+1; // 用兩個指標分別遍歷兩個陣列 while (l <= mid && r <= right){ // 在指標都在陣列範圍內時 // 比較兩個指標指向的元素,把較小的一個放進temp,然後指標+1 if (arr[l] <= arr[r]) { temp.push(arr[l++]); } else { temp.push(arr[r++]); } } // 迴圈結束後,肯定有一個數組已經遍歷完成,將另一個數組的剩餘元素全都加入temp
while (l <= mid) { temp.push(arr[l++]); } while (r <= right) { temp.push(arr[r++]); } // 完成後temp是有序的,這時候把它的元素copy回arr陣列的對應位置(left-right) for (var k = 0; k < n; k++) { arr[left+k] = temp[k]; // copy back } } function mergeSort(arr, left, right)
{
if (left < right) { var mid = Math.floor((left+right) / 2); // 留意js這裡需要處理成整數 mergeSort(arr, left, mid); mergeSort(arr, mid+1, right); merge2(arr, left, mid, right); } }

其中,對於merge部分,遍歷兩個數組合併成一個,還有一個程式碼更少但理解起來略微複雜的寫法:

function merge2(arr, left, mid, right) {
    var n = right-left+1;
    var temp = []; 
    var l = left, r = mid+1;
    while (l <= mid || r <= right) {
        if (l <= mid && (r > right || arr[l] <= arr[r])) {
            temp.push(arr[l++]);
        }else {
            temp.push(arr[r++]);
        }
    }
    for (var k = 0; k < n; k++) {
        arr[left+k] = temp[k]; 
    } 
}

相關推薦

歸併排序實現java

public class Sort { public static void main(String[] args) { int[] arr = {1, 4, 6, 2, 3,

Java 自頂向下歸併排序實現(int型別)

如果演算法能將兩個子陣列排序,那麼它能夠通過歸併兩個子陣列來將整個陣列排序。 時間複雜度:NlogN,空間複雜度:N 輔助陣列歸併前情況如圖: 程式碼: public class MergeTD { public static void m

python二路歸併排序實現

歸併原理: 第一步:申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合併後的序列 第二步:設定兩個指標,最初位置分別為兩個已經排序序列的起始位置 第三步:比較兩個指標所指向的元素,選擇相對小的元素放入到合併空間,並移動指標到下一位置 重複步驟3直到某一指

python--歸併排序實現

對於一個想找工作的人來說,歸併排序必須能手寫出來。 歸併排序原理無需解釋,直接給出python程式碼: def mergesort(num): if(len(num)==1):return num mid=len(num)//2 left=merg

歸併排序實現單鏈表的排序

今天做了百度的一套資料探勘的筆試題,其中有一道對單鏈表進行歸併排序,因為剛學歸併排序的時候是針對陣列來說,所以這道題著實費了一點心思。 考點:1歸併演算法;2單雙步求中點;3連結串列指標的操作,以及邊界空指標問題;4記憶體分配與回收; 單鏈表與陣列相比只能順序訪問每個元素,

python實現排序、快速排序歸併排序

堆排序     快速排序     快速排序一般選擇序列的兩頭位置,分別記為low和high,第一遍排序將low指標對應的值作為一個key值,試圖將大於key值的放在它的右邊,小於key值的放在左邊。具體實現是以key為標準,將high指標依

歸併排序(程式碼實現比較難)

歸併排序是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治法(Divide and Conquer)的一個非常典型的應用 首先考慮下如何將將二個有序數列合併。這個非常簡單,只要從比較二個數列的第一個數,誰小就先取誰,取了後就在對應數列中刪除這個數。然後再進行比較,如果有數列

分治法 實現歸併排序

分治法 實現歸併排序 1 問題描述   二路歸併排序,不仔細詳解了。之所以記錄是因為被坑了, 詳細看程式碼 2 python 實現 def merge(row_data, result_data, start, center, end): i = start j = center

Java常用的八種排序演算法與程式碼實現(二):歸併排序法、快速排序

注:這裡給出的程式碼方案都是通過遞迴完成的 --- 歸併排序(Merge Sort):   分而治之,遞迴實現   如果需要排序一個數組,我們先把陣列從中間分成前後兩部分,然後對前後兩部分進行分別排序,再將排好序的數組合並在一起,這樣整個陣列就有序了   歸併排序是穩定的排序演算法,時間

歸併排序 java實現

歸併排序利用的是分治的思想實現的,對於給定的一組資料,利用遞迴與分治技術將資料序列劃分成為越來越小的子序列,之後對子序列排序,最後再用遞迴方法將排好序的子序列合併成為有序序列。合併兩個子序列時,需要申請兩個子序列加起來長度的記憶體,臨時儲存新的生成序列,再將新生成的序列賦值到原陣列相應的位置。

歸併排序的java實現(超詳解)

歸併排序,見名知意,就是遞迴+合併 原理: 使用遞迴的手段,達到分割的目的,在分割後進行合併,合併也是遞迴的,這就是這裡的雙向過程都是遞迴進行的,結果如圖: 示例(例項): 以一下一串數字為例,首先進行拆分,然後合併,在合併的過程,進行排序,這裡需要說明的是,遞迴在整個過程中都

c#程式碼實現排序演算法之歸併排序

歸併排序的平均時間複雜度為O(nlogn),最好時間複雜度為O(nlogn),最壞時間複雜度為O(nlogn),空間複雜度為O(n),是一種穩定的演算法。 1.將待排序序列r(1),r(2),…,r(n)劃分為兩個長度相等的子序列r(1),…r(n/2)和r(n/2+1),…,r

快速排序歸併排序的非遞迴實現

1.快速排序 # 快速排序 def partition(li, left, right): i = left j = right r = random.randint(i, j) li[i], li[r] = li[r], li[i] tmp = li[i]

【Java】 歸併排序的非遞迴實現 資料結構與演算法合集 資料結構與演算法合集

  歸併排序可以採用遞迴方法(見:歸併排序),但遞迴方法會消耗深度位O(longn)的棧空間,使用歸併排序時,應該儘量使用非遞迴方法。本文實現了java版的非遞迴歸併排序。 更多:資料結構與演算法合集 思路分析   遞迴排序的核心是merge(int[] arr, int start, int mid,

java實現歸併排序

歸併排序:顯示不停的分割,一次分一半。。。直到分到全部為單個的時候,然後在慢慢合併回來。 程式碼: package test2018926; public class MergeSort { public static void main(String[] args) {

12_資料結構與演算法_歸併排序_Python實現

#Created By: Chen Da #定義一個合併方法,等價於Python內建的sorted def merge_sorted_list(sorted_a,sorted_b): length_a,length_b = len(sorted_a),len(sorted_b) a

資料結構-陣列排序-二路歸併-迴圈實現-C語言

/* * * 歸併排序-迴圈實現 * * */ #include <stdio.h> #include <stdlib.h> void Merge(int Element[],int TmpA[],int L,int R,int RightEnd){

經典排序演算法的實現(選擇,插入,shell,堆,快速,歸併排序

1.選擇排序 //選擇排序 void selectSort(int * arr, int n) { for (int i = 0; i < n - 1; i++) { int min = arr[i]; int minPos = i; for (int j = i

Java實現--歸併排序(遞迴)

《Java資料結構和演算法》如此描述分治演算法: 把一個大問題分成兩個相對來說更小的問題,並且分別解決每一個小問題,對每一個小問題的解決方案是一樣的:把每個小問題分成兩個更小的問題,並且解決它們。這個過程一直持續小去知道達到易於求解的基值情況,就不用再繼續分了。 時間複雜度: