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

歸併排序的C++實現

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

歸併過程為:比較a[i]和a[j]的大小,若a[i]≤a[j],則將第一個有序表中的元素a[i]複製到r[k]中,並令i和k分別加上1;否則將第二個有序表中的元素a[j]複製到r[k]中,並令j和k分別加上1,如此迴圈下去,直到其中一個有序表取完,然後再將另一個有序表中剩餘的元素複製到r中從下標k到下標t的單元。歸併排序的演算法我們通常用遞迴實現,先把待排序區間[s,t]以中點二分,接著把左邊子區間排序,再把右邊子區間排序,最後把左區間和右區間用一次歸併操作合併成有序的區間[s,t]。

以上內容來自百度百科。

歸併排序主要分為兩部分:

1、劃分子區間

2、合併子區間

現在以 9,6,7,22,20,33,16,20 為例講解上面兩個過程:

第一步,劃分子區間:每次遞迴的從中間把資料劃分為左區間和右區間。原始區間為[start,end],start=0,end=[length-1],減一是因為陣列的下標從0開始,本例中length=8,end=7.現在從中間元素劃分,劃分之後的左右區間分別為 [start,(end-start+1)/2+start],右區間為[(end-start+1)/2+start+1,end],本例中把start和end帶入可以得到[0,7],劃分後的左右子區間為[0,4],[5,7],然後分別對[start,end]=[0,4]和[start,end]=[5,7]重複上一步過程,直到每個子區間只有一個或者兩個元素。整個分解過程為:
這裡寫圖片描述


子區間劃分好以後,分別對左右子區間進行排序,排好序之後,在遞迴的把左右子區間進行合併,整個過程如下圖所示:
這裡寫圖片描述
現在看程式碼:

void merge_sort(int *data, int start, int end, int *result)
{
    if(1 == end - start)//如果區間中只有兩個元素,則對這兩個元素進行排序
    {
        if(data[start] > data[end])
        {
            int temp  = data[start];
            data[start] = data
[end];
data[end] = temp; } return; } else if(0 == end - start)//如果只有一個元素,則不用排序 return; else { //繼續劃分子區間,分別對左右子區間進行排序 merge_sort(data,start,(end-start+1)/2+start,result); merge_sort(data,(end-start+1)/2+start+1,end,result); //開始歸併已經排好序的start到end之間的資料 merge(data,start,end,result); //把排序後的區間資料複製到原始資料中去 for(int i = start;i <= end;++i) data[i] = result[i]; } }

merge的過程為:

void merge(int *data,int start,int end,int *result)
{
    int left_length = (end - start + 1) / 2 + 1;//左部分割槽間的資料元素的個數
    int left_index = start;
    int right_index = start + left_length;
    int result_index = start;
    while(left_index < start + left_length && right_index < end+1)
    {
        //對分別已經排好序的左區間和右區間進行合併
        if(data[left_index] <= data[right_index])
            result[result_index++] = data[left_index++];
        else
            result[result_index++] = data[right_index++];
    }
    while(left_index < start + left_length)
        result[result_index++] = data[left_index++];
    while(right_index < end+1)
        result[result_index++] = data[right_index++];
}

現在對程式進行測試:

int main()
{
    int data[] = {9,6,7,22,20,33,16,20};
    const int length = 8;
    int result[length];
    cout << "Before sorted:" << endl;
    for(int i = 0;i < length;++i)
        cout << data[i] << "  ";
    cout << endl;
    cout << "After sorted:" << endl;
    merge_sort(data,0,length-1,result);
    for(int i = 0;i < length;++i)
        cout << data[i] << "  ";
    cout << endl;

    return 0;
}

程式執行結果如下:
這裡寫圖片描述

相關推薦

排序演算法】歸併排序(C++實現)

歸併排序是利用"歸併"技術來進行排序。歸併是指將若干個已排序的子檔案合併成一個有序的檔案。常見的歸併排序有兩路歸併排序(Merge Sort),多相歸併排序(Polyphase Merge Sort)

歸併排序 C++實現

// 歸併排序.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include&l

常見排序演算法總結分析之選擇排序歸併排序-C#實現

本篇文章對選擇排序中的簡單選擇排序與堆排序,以及常用的歸併排序做一個總結分析。 [常見排序演算法總結分析之交換排序與插入排序-C#實現](https://www.cnblogs.com/iwiniwin/p/12589405.html)是排序演算法總結系列的首篇文章,包含了一些概念的介紹以及交換排序(冒泡與

排序(6)---------歸併排序(C語言實現)

歸併排序: 歸併操作,也叫歸併演算法,指的是將兩個已經排序的序列合併成一個序列的操作。歸併排序演算法依賴歸併操作。 歸併操作的過程如下:     (1) 申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合併後的序列     (2) 設定兩個指標,最初位置分別為兩個

C語言二分歸併排序實現

趁著十一小長假,自學了一點兒演算法(初級),複雜度最低的就是二分歸併排序(nlog(n)),也是分支歸併思想的體現。博主,基於閒的沒事的原則,好久沒碰C語言,所以親自除錯了一段程式碼,並且進行debug測試得到。其中學習了不少新的知識。 直接貼程式碼:

排序(C++實現)】:二分歸併排序

一、虛擬碼 1.      MergeSort(A,l,r) 2.      Merge(A,l,m,r)  二、C/C++程式碼  /*********************************************************

選擇排序——C實現

return 最大 n-1 spa 工作 cnblogs ret clu 輸出 選擇排序:   選擇排序(Selection sort)是一種簡單直觀的排序算法。它的工作原理如下。首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然後,再從剩余未排序元素中繼續

排序 C++實現

logs pso int brush -- cpp end tac 排序 #include<iostream> #include<vector> #include<stack> #include<algorithm> #in

基數排序c++實現

復雜 -- cpp ++ stream c++實現 sin logs 中心 //中心思想,按照低位先排序,然後收集,再按照高位排序,然後再收集, //以此類推,直到最高位,是穩定算法,效率很高,復雜度是O(n㏒(r)m),r為采取的基數 //m為堆數,但是只能用在整數中,

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

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

歸併排序 java實現

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

1045 快速排序——c實現

1045 快速排序 (25 分) 著名的快速排序演算法裡有一個經典的劃分過程:我們通常採用某種方法取一個元素作為主元,通過交換,把比主元小的元素放到它的左邊,比主元大的元素放到它的右邊。 給定劃分後的 N 個互不相同的正整數的排列,請問有多少個元素可能是劃分前選取的主元? 例

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

歸併排序-java實現

基本思想: 歸併排序(MERGE-SORT)是利用歸併的思想實現的排序方法,該演算法採用經典的分治(divide-and-conquer)策略(分治法將問題分(divide)成一些小的問題然後遞迴求解,而治(conquer)的階段則將分的階段得到的各答案”修補

快速排序歸併排序------JavaScript實現

1.快速排序 演算法步驟: 在陣列中找到基準點(flag),其他數與之比較。 建立兩個陣列,小於基準點的數儲存在左邊陣列,大於基準點的數儲存在右邊陣列。 拼接陣列,然後左邊陣列與右邊陣列繼續執行1、2兩個步驟,直到最後完成陣列排序。(該步驟可以看出演算法存在迭代性質)

歸併排序java實現

package algorithm; public class MergeSort { public static void main(String[] args) { int[] a = {2,4,7,9,6,1,3,8}; int L = 0; int R

【資料結構】歸併排序-python實現

【資料結構】歸併排序--python 實現時間複雜度程式碼實現執行示例 歸併排序介紹 快速排序是典型的使用分治的思想來解決問題的演算法。分治策略會將原問題劃分為n個規模較小而結構與原問題相似的子問題。遞迴地解決這些子問題,然後再合併其結果,就得到原問題的解。

插入排序(c++實現)

github部落格傳送門 csdn部落格傳送門 插入排序原理: #include<iostream> using namespace std; //插入排序 void InsertionSort(int a[], int size) { int i; //有序區

選擇排序(c++實現)

github部落格傳送門 csdn部落格傳送門 選擇排序原理: #include<iostream> using namespace std; const int MAX_NUM = 100; //選擇排序 int main(){ int a[MAX_NUM]; in

演算法導論—歸併排序python實現

Suppose we have two piles of cards face up on a table. Each pile is sorted, with the smallest cards on top. We wish to merge the two pile