快排和归并分治总结

Posted zhichun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快排和归并分治总结相关的知识,希望对你有一定的参考价值。

快排和归并分治总结

快排和归并排序都运用了分治的思想,所以在我看来这两种排序方法都有自己的相似性。

快排

在快排中,首先运用的是分割的方式,选取pivot,将比pivot小的元素放在pivot前面。将比pivot大的元素放在pivot后面。

quickSort(arr[],low,high)
{
    if(low<high)
    {
        pi = partition(arr,low,high);
        quickSort(arr,low,pi-1);
        quickSort(arr,pi+1,high);
    }
}

接下来是实现这个方法的步骤,为了实现partition算法,我们可以首先选择数组中最后一位作为要比较的数。

partition(arr[],low,high)
{
    pivot = arr[high];
    i = low - 1;
    for(j=low;j<high;j++)
    {
        if(arr[j]<pivot)
        {
            i++;
            swap(arr,i,j);
        }   
    }   
    swap(arr,i+1,high);
}

在迭代循环中,i的作用是交换比pivot大的数与pivot小的数。直到最后完成交换结束。

而在归并排序中,

技术图片

它首先将数组分割成两个部分,然后调用自己继续分割。最后,merge()函数用来归并最后的结果。

    1. 找到中间值分割数组成两半
    1. 调用归并数组左半段分割
    1. 调用归并数组右半段分割
    1. 合并两个归并数组

接下来实现归并这块的算法:



void merge(int arr[], int l, int m, int r) 
{ 
        // Find sizes of two subarrays to be merged 
        int n1 = m - l + 1; 
        int n2 = r - m; 
  
        /* Create temp arrays */
        int L[] = new int [n1]; 
        int R[] = new int [n2]; 
  
        /*Copy data to temp arrays*/
        for (int i=0; i<n1; ++i) 
            L[i] = arr[l + i]; 
        for (int j=0; j<n2; ++j) 
            R[j] = arr[m + 1+ j]; 
  
  
        /* Merge the temp arrays */
  
        // Initial indexes of first and second subarrays 
        int i = 0, j = 0; 
  
        // Initial index of merged subarry array 
        int k = l; 
        while (i < n1 && j < n2) 
        { 
            if (L[i] <= R[j]) 
            { 
                arr[k] = L[i]; 
                i++; 
            } 
            else
            { 
                arr[k] = R[j]; 
                j++; 
            } 
            k++; 
        } 
  
        /* Copy remaining elements of L[] if any */
        while (i < n1) 
        { 
            arr[k] = L[i]; 
            i++; 
            k++; 
        } 
  
        /* Copy remaining elements of R[] if any */
        while (j < n2) 
        { 
            arr[k] = R[j]; 
            j++; 
            k++; 
        } 
} 
  

以及分割部分:

 void sort(int arr[], int l, int r) 
    { 
        if (l < r) 
        { 
            // Find the middle point 
            int m = (l+r)/2; 
  
            // Sort first and second halves 
            sort(arr, l, m); 
            sort(arr , m+1, r); 
  
            // Merge the sorted halves 
            merge(arr, l, m, r); 
        } 
    } 

以上是关于快排和归并分治总结的主要内容,如果未能解决你的问题,请参考以下文章

排序算法专题:快排和归并排序

JS--排序之快排和归并

算法排序02——归并排序介绍及其在分治算法思想上与快排的区别(含归并代码)

快排和并归

排序算法整理

分治算法的完美使用----归并排序