1. 程式人生 > >對比快速排序,理解歸併排序

對比快速排序,理解歸併排序

對比快速排序來理解歸併排序。

有時經常講歸併排序和快速排序記混亂,因為兩者都用到了分治法。其實兩者的不同之處非常明顯。

快速排序:“先治後分”,

void quickly_sort(int arr[], int low, int high) {
  if (low < high) {
    // 先治後分
    int pivot = _qucikly_sort(arr, low, high);  //治
    quickly_sort(arr, low, pivot-1); //分
    quickly_sort(arr, pivot + 1, high); //分
  }
}

歸併排序:“先分後治”。

void merge_sort_up2down(int a[], int start, int end) {
    if(a==NULL || start >= end)
        return ;
    // 先分後治
    int mid = (end + start)/2;
    merge_sort_up2down(a, start, mid); // 分
    merge_sort_up2down(a, mid+1, end); // 分
    merge(a, start, mid, end); // 治
}

“分”的過程用遞迴實現起來分簡單,主要是理解兩者的“治”。

快速排序的根本處理是:如何在選定一個元素後,將這個元素放在合適的位置,使得元素左邊都是小於這個元素的,右邊都是大於這個元素的(挖坑填坑法)

int _qucikly_sort(int arr[], int low, int high) {
  int pivot = arr[low]; //挖第一個坑,把“蘿蔔”放進籃子
  while(low<high) { //開始迴圈挖坑填坑
    //如果low等於high,說明找坑的過程中,找到了上一次挖的坑,因此可以停止了
    while(low<high && arr[high]>=pivot) //從右邊往左邊找填坑的元素(比pivot小的元素)。 2,4,6的過程
      --high;
    arr[low] = arr[high]; //將找到之後,挖出來,填到左邊的坑裡
    while(low<high && arr[low]<=pivot) //從左邊往右邊找填坑的(比pivot大的元素)。3,5的過程
      ++low;
arr[high] = arr[low];//找到之後,填到右邊的坑裡
  }
  arr[low] = pivot; //籃子裡的“蘿蔔”填到坑裡
  return low;//返回這個坑的位置,作為分而治之的中軸
}

歸併排序的根本處理是:如何將兩個有序的陣列,合併成一個有序陣列(申請一個數組,大小是兩個有序陣列(原陣列的兩個子陣列)的大小之和,遍歷比較兩個陣列的元素,按大小放進新陣列,將新陣列替換原陣列的子陣列即可):
void merge(int a[], int start, int mid, int end) {
    int *tmp = (int *)malloc((end-start+1)*sizeof(int));    // tmp是彙總2個有序區的臨時區域
    int i = start;            // 第1個有序區的索引
    int j = mid + 1;        // 第2個有序區的索引
    int k = 0;                // 臨時區域的索引

    while(i <= mid && j <= end) {
        if (a[i] <= a[j])
            tmp[k++] = a[i++];
        else
            tmp[k++] = a[j++];
    }

    while(i <= mid)
        tmp[k++] = a[i++];

    while(j <= end)
        tmp[k++] = a[j++];

    // 將排序後的元素,全部都整合到陣列a中。
    for (i = 0; i < k; i++)
        a[start + i] = tmp[i];

    free(tmp);
}


這樣,都過簡單的程式碼對比,就可以很簡單的分清楚兩者的關係與不同。

相關推薦

對比快速排序理解歸併排序

對比快速排序來理解歸併排序。 有時經常講歸併排序和快速排序記混亂,因為兩者都用到了分治法。其實兩者的不同之處非常明顯。 快速排序:“先治後分”, void quickly_sort(int arr[], int low, int high) { if (low <

分治法:快速排序3種劃分方式隨機化快排快排快還是歸併排序快?

快速排序不同於之前瞭解的分治,他是通過一系列操作劃分得到子問題,不同之前的劃分子問題很簡單,劃分子問題的過程也是解決問題的過程 我們通常劃分子問題儘量保持均衡,而快排缺無法保持均衡 快排第一種劃分子問題實現方式,左右填空的雙指標方式 def partition_1(arr,low

各種排序演算法的場景以及c++實現(插入排序希爾排序氣泡排序快速排序選擇排序歸併排序

對現有工作並不是很滿意,所以決定找下一個坑。由工作中遇到排序場景並不多,大都是用氣泡排序,太low,面試又經常問到一些排序演算法方面的東西。剛好讓小學妹郵的資料結構也到了。就把各種排序演算法重新總結一下,以作留存。 排序分為內部排序和外部排序,內部排序是在記憶體中排序。外

插入排序希爾排序選擇排序快速排序氣泡排序歸併排序

插入排序 1、介紹:        簡單插入排序演算法原理:從整個待排序列中選出一個元素插入到已經有序的子序列中去,得到一個有序的、元素加一的子序列,直到整個序列的待插入元素為0,則整個序列全部有序。   在實際的演算法中

經典排序演算法氣泡排序選擇排序直接插入排序希爾排序快速排序歸併排序二分查詢。原理及python實現。

1.氣泡排序 氣泡排序 1.比較相鄰的元素,如果第一個比第二個大(升序),就交換他們兩個 2.對每一對相鄰的元素做同樣的工作,從開始到結尾的最後一對 這步做完後,最後的元素會是最大的數 3.針對所有的元素重複以上的步驟,除了最

氣泡排序選擇排序插入排序希爾排序排序歸併排序快速排序實現

前言:排序的定義 排序是計算機內經常進行的一種操作,其目的是將一組“無序”的記錄序列調整為“有序”的記錄序列。分內部排序和外部排序,若整個排序過程不需要訪問外存便能完成,則稱此類排序問題為內部排序。反之,若參加排序的記錄數量很大,整個序列的排序過程不可能在記憶

排序演算法: 氣泡排序 快速排序希爾排序,直接插入排序 直接選擇排序,歸併排序,堆排序

幾種排序演算法分析:   氣泡排序:   氣泡排序的方法排序速度比較慢。   思路:進行n-1排序,第一次排序先找出最小的數字,放在第一個位置,然後在剩餘的數字中再找出最小的數字,放在第二個位置上,依次類推,可以排出所有的數字。   當然也可以從大到小的排序。   例如

常用排序:氣泡排序選擇排序插入排序希爾排序歸併排序快速排序

#include <stdio.h> #define MAX 10 typedef int  ElementType; typedef ElementType ARR[MAX]; void swap(ARR arr,int i,int j) {     E

排序演算法中——歸併排序快速排序

氣泡排序、插入排序、選擇排序這三種演算法的時間複雜度都為 O (

野生前端的數據結構練習(10)希爾排序歸並排序快速排序

merge lang quick 分治法 ado uic pos 快速 ons 一.希爾排序 shell sort也稱縮小增量排序,是對插入排序算法的改進,其工作原理是定義一個間隔序列來表示排序過程中進行比較的元素之間有多遠的間隔,每次將具有相同間隔的數分為一組,進行插入

java幾種排序簡單實現(快速排序氣泡排序直接插入排序

package Test; import com.alibaba.fastjson.JSONObject; public class Test { static int[] arrays = new int[] { 3, 10, 11, 1, 8, 2, 9, 4 }; // index

排序比較之歸併排序快速排序

異同點:    雖然在於演算法的區別主要在於遞迴實現的時機不同,在一些細節上也有著一些區別:   快速排序:   進行選擇排序的時候,如果一輪還沒有排序結束,會暫時將比中心值小的數放在緊挨著中心值的右邊,並設定一個遊標來控制這些數的下標,每找到一個小於的數就將遊標的值加一換到下一個,直到一輪排序結束後,再將中

Java語言陣列排序——氣泡排序選擇排序快速排序直接插入排序

今天主要來說下陣列排序的問題,主要介紹的有氣泡排序,選擇排序,快速排序,直接插入排序四種排序: 1.氣泡排序: 主要有原理圖與程式碼解釋; 原理圖借鑑一位老師畫的圖,嘻嘻,老師畫的圖比較好看,就拿來借鑑下: 2.選擇排序 3.快速排序 4.直接插

“深入理解”—歸併排序演算法

歸併排序:  歸併排序 (merge sort) 是一類與插入排序、交換排序、選擇排序不同的另一種排序方法。歸併的含義是將兩個或兩個以上的有序表合併成一個新的有序表。如圖所示:import java.u

輸入隨機數實現歸併排序

題目:隨機產生一個數量為n的陣列,用歸併排序進行排序。 分析: 1、需要隨機產生一個整數陣列; 2、採用的演算法是合併排序,也就是用歸併排序; 3、輸出排序後的陣列。 歸併排序: 先把已知陣列分成兩組,然後兩組中分別再分成兩組,直到每一組都只有一個數據,然後再合併的同時排序,直到都合併起

幾種常用的排序演算法(快速排序希爾排序排序選擇排序氣泡排序

1、歸併排序      基本原理:歸併排序也稱合併排序,其演算法思想是將待排序序列分為兩部分,依次對分得的兩個部分再次使用歸併排序,之後再對其進行合併。操作步驟如下。(1)將所要進行的排序序列分為左右兩個部分,如果要進行排序的序列的起始元素下標為first,最後一個元素的

java排序演算法-比較快速排序氣泡排序雙向氣泡排序的執行效率

快速排序 原理是找出一個元素(理論上可以隨便找一個)作為基準(pivot),然後對陣列進行分割槽操作,使基準左邊元素的值都不大於基準值,基準右邊的元素值 都不小於基準值,如此作為基準的元素調整到排序後的正確位置。遞迴快速排序,將其他n-1個元素也調整到排序後的正確位置。

算法系列(四)排序演算法中篇--歸併排序快速排序

在算法系列(三)排序演算法上篇 一文中,介紹了氣泡排序,插入排序和選擇排序演算法。這篇文章繼續講解排序演算法。 概述 氣泡排序,插入排序和選擇排序演算法這些演算法的時間複雜度都是O(N^2),是否有更

通俗理解插入排序(直接插入排序折半插入排序希爾排序

直接插入排序 直接插入排序就是將待排序的值,逐一按元素的大小插入前面的有序序列 例如對-23,45,2,-45,9,5,3,65,-24進行直接插入排序,我們可以看成將45,2,-45,9,5,3,65,-24逐步插入-23的序列 package

array和list排序演算法對比(二):歸併排序

接著上一篇文章,這裡簡單討論陣列和連結串列的歸併排序在演算法設計上的區別。 歸併排序的特點是採用二分的策略,將陣列的子陣列進行排序,然後將兩個有序的子數組合併成一個大的有序陣列。如果採用陣列結構,二分是非常簡單的操作,但二分後的合併空間開銷相對較大。如果採用連