歸併排序(MergeSort)思想與實現
歸併排序屬於高階的排序方法,在介紹歸併排序的思想之前,先講述一種採用比較方式的排序方法。假設有兩個已經排好序的陣列arr1[ ],arr2[ ],且均是升序或者降序,那麼可以進行以下操作:以升序為例,先建立一個尺寸大小為arr1[ ]與arr2[ ]尺寸之和的陣列temp[
],然後同時從兩陣列的第0個元素開始遍歷,若arr1[i] < arr2[j],則可以把arr1[i]放入temp[k]中後,執行i++,k++,繼續往後比較;若arr1[i] > arr2[j],則可以把arr2[j]放入temp[k]中後,執行j++,k++,繼續往後比較;最終直到把兩個陣列中的所有元素放入陣列temp[ ]中。
總結地說,這種比較方式的排序方法思想就是:因為兩個陣列都是有序的(假設為升序),故兩個陣列自身的後一個元素肯定不小於前一個元素,所以當兩個陣列分別從頭開始遍歷時,只要發現本陣列的當前元素比另一個數組的當前元素小,那麼該元素肯定為目前兩陣列中最小的元素。
歸併排序就是用到的這種方法,接下來講述一下歸併排序的思想。
(1) 歸併排序的思想
歸併排序的思想就是:首先將原始陣列對半切分,然後將所切成的兩個子陣列再次切分,直到所切分的子陣列只有1個元素為止;在此基礎上,先建立一個臨時陣列,再將最後只有1個元素的子陣列進行排序,排完序之後將所切成的兩個子陣列進行合併到臨時陣列中,合併的方法為本文開頭所描述的方法第一步:首先將原始陣列對半切分,切分成左右兩個子陣列,再將左右兩個子陣列對半切分;以此類推,最終切分成如下各子陣列:{1},{8},{6},{4},{10},{3},{5},{2},{22}。
(2) 歸併排序的實現
本次排序演算法採用C++模版程式設計來實現,並採用了遞迴的方法。
#include <iostream>
#include <iterator>
#include <algorithm>
using namespace std;
template<class T,size_t N>
void PrintArr(T (&arr)[N])
{
copy(arr,arr+N,ostream_iterator<T>(cout," "));
cout << endl;
}
template<class T,size_t N>
void MergeSort(T (&arr)[N],size_t start = 0,ssize_t end = (N-1))
{
size_t size = end + 1 -start;
if(size <= 1) {
return;
}
if(size == 2) {
if(arr[start] > arr[end]) {
swap(arr[start],arr[end]);
}
return;
}
ssize_t mid = size/2;
MergeSort(arr,start,start+mid-1);
MergeSort(arr,start+mid,end);
size_t i(start),j(start+mid),k(0);
T temp[size];
while(i < (start+mid) or j <= end) {
if(arr[i] <= arr[j] and i < (start+mid) or j == (end+1)) {
temp[k] = arr[i];
k++;
i++;
} else if(arr[j] <= arr[i] and j <=end or i == (start+mid)) {
temp[k]= arr[j];
k++;
j++;
}
}
i = start;
k = 0;
while(i <= end ) {
arr[i] = temp[k];
i++;
k++;
}
PrintArr(arr);
return;
}
int main()
{
int arr[]= {1,8,6,4,10,5,3,2,22};
// int arr[]= {1,4,5,2,4,8,9,10,22,4,6,1,8,9,1,21,34,54,2,4};
cout << "The init:" << endl;
PrintArr(arr);
cout << "The sort:" << endl;
MergeSort(arr);
PrintArr(arr);
cout << "The final:" << endl;
PrintArr(arr);
}
原始陣列為:1 8 6 4 10 5 3 2 22
程式執行結果為:1 2 3 4 5 6 8 10 22
相關推薦
歸併排序(MergeSort)思想與實現
歸併排序屬於高階的排序方法,在介紹歸併排序的思想之前,先講述一種採用比較方式的排序方法。假設有兩個已經排好序的陣列arr1[ ],arr2[ ],且均是升序或者降序,那麼可以進行以下操作:以升序為
基數排序(RadixSort)思想與實現
基數排序屬於高階的排序方法,該排序演算法是在“桶排序”的基礎上所進行的改進,讀者若是想了解“桶排序”思想,可以點選這裡。接下來介紹一下基數排序的思想。 (1) 基數排序的思想 基數排序的思想就
插入排序(InsertSort)思想與實現
在介紹插入排序的思想之前,說一下插入排序的一個重要的優點:插入排序只有在需要排序時才會排序。該演算法的時間複雜度為:O(n^2),接下來我們來了解一下該排序的思想。 (1)插入排序的思想 插入
選擇排序(SelectSort)思想與實現
選擇排序屬於相對來說比較簡單的排序方法,時間複雜度為:O(n^2)。 (1) 選擇排序的思想 選擇排序的思想就是:選擇排序的本意在於每次選擇出最小或者最大的元素,將其放在陣列的前面,從而使得陣
梳排序(CombSort)思想與實現
梳排序也屬於簡單的排序演算法,也是一種不穩定的排序方法。在講述梳排序的思想之前,先介紹一下與該排序有關的一個關鍵常量:遞減率;該常量為固定值:1.3。該常量是由原作者Wlodzimierz Do
桶排序(BucketSort)思想與實現
桶排序屬於簡單而且易於理解的排序演算法,接下來介紹一下該演算法的思想。 (1) 桶排序的思想 桶排序的思想就是:首先遍歷一遍陣列,找出陣列中值最大的元素,假設最大的元素為Max;然後定義Max
Java排序演算法(三)--歸併排序(MergeSort)遞迴與非遞迴的實現
歸併有遞迴和非遞迴兩種。 歸併的思想是: 1.將原陣列首先進行兩個元素為一組的排序,然後合併為四個一組,八個一組,直至合併整個陣列; 2.合併兩個子陣列的時候,需要藉助一個臨時陣列,用來存放當前的
歸併排序(MergeSort)詳解和動畫
歸併排序演算法思想:將陣列不斷二分得到子陣列,知道子陣列長度為1(自然是排序好的),對左子陣列和右子陣列分別排序, 子陣列長度為1,2,4...., 子陣列排序使用了一個輔助陣列 def exchange(arr,i,j): temp=arr[i] arr[i]=arr[
Java排序演算法分析與實現:快排、氣泡排序、選擇排序、插入排序、歸併排序(一)
轉載 https://www.cnblogs.com/bjh1117/p/8335628.html 一、概述: 本文給出常見的幾種排序演算法的原理以及java實現,包括常見的簡單排序和高階排序演算法,以及其他常用的演算法知識。 簡單排序:氣泡排序、選擇排序、
資料結構與演算法C++之歸併排序(續)
上一篇部落格中實現的是自上以下的歸併排序,自上而下需要先不斷將陣列進行對半拆分(遞迴實現),然後再合併排序 其實也可以自下而上實現歸併排序,這樣使用for迴圈就可以實現,省掉了遞迴的操作 首先對陣列的每一個元素進行兩兩歸併(相鄰的兩個元素合併成一個有序陣列),然後將合併好的兩個元素的有序
快速排序(Quicksort)的Javascript實現
簡單 fun 遍歷數組 floor 演示 ont -s urn 元素 日本程序員norahiko,寫了一個排序算法的動畫演示,非常有趣。 這個周末,我就用它當做教材,好好學習了一下各種排序算法。 排序算法(Sorting algorithm)是計算機科學最古老、最基
kaggle入門項目:Titanic存亡預測(五)驗證與實現
tps 多參數 name 出了 運算 處理 defaults purpose sof 原kaggle比賽地址:https://www.kaggle.com/c/titanic 原kernel地址:A Data Science Framework: To Achieve 99
離散傅立葉變換(DFT)和快速傅立葉變換(FFT)原理與實現
目錄 1、影象變換 2、離散傅立葉變換(Discrete Fourier Transform) 3、DFT性質 4、DFT與數字影象處理 5、FFT-快速傅立葉變換 6、DFT與FFT的演算法實現 1. 影象變換 — —數學領域中有很多種變換,如傅立葉變換、拉普拉斯變
【排序演算法】歸併排序(C++)
歸併排序的遞迴實現 C++ class MergeSort { public: int* mergeSort(int* A, int n) { // write code he
C#歸併排序(一)
class Program { static void Main(string[] args) { int[] arr = arrInsert(100000); merge_sort(arr,0,arr.Le
排序演算法:二路歸併排序(java)
public class MergeSort { /** * * @param array 待排序陣列 * @param temp 輔助陣列 * @param start 開始下標 * @param end 結束下標
八大排序演算法實戰:思想與實現
摘要: 所謂排序,就是根據排序碼的遞增或者遞減順序把資料元素依次排列起來,使一組任意排列的元素變為一組按其排序碼線性有序的元素。本文將介紹八種最為經典常用的內部排序演算法的基本思想與實現,包括插入排序(直接插入排序,希爾排序)、選擇排序(直接選擇排序,堆排
平衡二叉樹(AVL)圖解與實現
平衡二叉樹(Balanced BinaryTree)又被稱為AVL樹。它具有以下性質:它是一棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,並且左右兩個子樹都是一棵平衡二叉樹。 平衡二叉樹一般是一個有序樹,它具有二叉樹的所有性質,其遍歷操作和二叉樹的遍歷操作相同。
java資料結構與演算法之棧(Stack)設計與實現
關聯文章: 本篇是java資料結構與演算法的第4篇,從本篇開始我們將來了解棧的設計與實現,以下是本篇的相關知識點: 棧的抽象資料型別 棧是一種用於儲存資料的簡單資料結構,有點類似連結串列或者順序表(統稱線性表),棧與線性表的最大區別是
直接插入排序、快排 AND歸併排序(圖)
插入排序的思想 n個待排序的元素有一個有序表和一個無序表組成,開始時,有序表中僅包含“一個元素”。排序工程中將“無序表中”取出一個元素,然後插入有序表中。 For(int i=1;i<a.length,i++) { If(a[i]<a[i-1]) {A[