快排和归并分治总结

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

快排

在快排中,首先运用的是分割的方式,选取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);
        }
    }

原文地址:https://www.cnblogs.com/zhichun/p/12110014.html

时间: 2024-10-10 02:30:28

快排和归并分治总结的相关文章

排序详解(希尔,快排,归并等)

今天集中把几种排序的方法列一下,当然最出名的希尔,快排,归并和其优化当然也是满载 说到希尔排序的话,不得不先提到的就是插入排序了,希尔排序就是对直接插入排序的一种优化,下面就是直接插入排序的思想 1 void InsertSort(int *a, size_t size) 2 { 3 assert(a); 4 for (int i = 1; i < size; ++i) 5 { 6 int index = i; 7 int tmp = a[index]; 8 int end = index -

三种排序:快排,归并,堆排

转自:http://www.cnblogs.com/LUO77/p/5798149.html (一)快排 快排考的是最多次的.之前看大神写的算法很简单,思想也很好.就一直用他的思想去思考快排了.挖坑法. 拿走第一个元素作为标兵元素,即挖坑,然后从后面找一个比它小的填坑,然后又形成一个坑,再从前面找一个比标兵大的填坑,又形成一个坑.……最后一个坑填入标兵就好. 然后就是递归了.再在标兵左边排序,右边排序. 1 void QSort(int* num, int start, int end) { 2

Python实现排序(冒泡、快排、归并)

Thomas H.Cormen 的<算法导论>上介绍的几个经典排序算法的Python实现. 1.冒泡排序: 简单的两重循环遍历,使最小(最大)的值不断地往上升(下沉)而实现的排序,算法时间为O(n2). 代码如下: 1 def up_sort(a): 2 # 冒泡排序 3 4 a_length = len(a) 5 while True: 6 i = 0 7 j = 1 8 9 while True: 10 if a[i] > a[j]: 11 a[i], a[j] = a[j], a[

排序 之 快排and归并&lt;时间复杂度&gt;----掌握思想和过程

俗话说:天下武功无坚不破,唯快不破.对于算法当然也是要使用时间最短.占用空间最小的算法来实现了. 注意:我代码里面打的备注仅供参考,建议不要背模板(因为没有固定的模板),可以写一个数列按着代码跑两圈或者把代码改一下输出每次排序后的结果. 总之,师傅领进门,修行在个人.奋斗把!骚年! ※冒泡排序.选择排序:(不稳定,时间复杂度 O(n^2)) 1 #include "cstdio" 2 #include "iostream" 3 using namespace std

[算法基础]快排、归并、堆排序比较

1.快速排序,上代码: def quickSort(arr): if len(arr) <= 1: return arr v = arr[0] high = [i for i in arr[1:] if i>=v] low = [i for i in arr[1:] if i<v] return quickSort(low) + [v] + quickSort(high) 分析一哈: 当不考虑最差情况(O(n^2))时,快排时间复杂度为O(nlogn):因为层数为O(logn)即调用栈的

排序(冒泡,快排,归并)

一,冒泡排序(n^2) for(int i=2;i<=n;i++)j在前,i在后 for(int j=1;j<=n-i;j++) if(a[j]<a[i]) swap(a[i],a[j]); 二:快速排序(n*logn~n^2) #include<iostream> using namespace std; int a[(int)1e5+5]; void quick_sort(int q[],int l,int r)//先排序再递归 { if(l>=r)return;

算法总结——三大排序(快排,计数排序,归并)

快排: 适用条件:方便...只要数字不是很多 复杂度:O(nlogn)  每一层n复杂度,共logn层 原理:利用一个随机数与最后面一个数交换,那么这个随机数就到了最后一位,然后循环,如果前面的数大于最后一个数,那么把这个数放到前面去,经过一次排序之后,前面的数都是大于最后一个的,然后对1到k和k+1到n进行排序,一层一层地下去 模板: #include<cstdio> #include<algorithm> #include<time.h> using namespa

快排、归并排序(分治)、堆排序

一.快速排序 1)算法简介 快速排序是由C. A. R. Hoare所发展的一种排序算法.其基本思想是基本思想是,通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序. 2)算法描述 快速排序使用分治法来把一个串(list)分为两个子串行(sub-lists). 步骤为: 1.从数列中挑出一个元素,称为 "基准"(pivot), 2.重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准

排序(一)归并、快排、优先队列等

排序(一) 初级排序算法 选择排序 思想:首先,找到数组中最小的那个元素.其次,将它和数组的第一个元素交换位置.再次,在剩下的元素中找到最小的元素,将它与数组的第二个元素交换位置.如此往复,直到将整个数组排序. [图例] 图中,x轴方向为数组的索引,y轴方向为待排序元素的值. 选择排序有两个很鲜明的特点: 运行时间和输入无关.为了找出最小的元素而扫描一遍数组并不能为下一遍扫描提供什么信息.这种性质在某些情况下是缺点.(无论数组的初始状态是什么,此算法效率都一样低效) 数据移动是最少的.每次交换都