排序六 快速排序

快速排序(Quick Sort)

快速排序(Quicksort)是对冒泡排序的一种改进,由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。—百度百科

  • 时间复杂度:最好 O(n)=O(nlogn);平均O(n)=O(nlogn);最差O(n)=O(n2)
  • 空间复杂度:O(n)=O(n)
  • 稳定性:    不稳定

算法描述

  1. 设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。
  2. 分别对步骤1中的小的数大的数递归进行步骤1中快速排序,直到完成。
    Quick Sort
    图片来自维基百科

排序示例

数组S: [9,1,5,3,8,7,2,4,6,0]
第一趟:[(1,5,3,8,7,2,4,6,0),9]  –key=9
第二趟:[0,1,(5,3,8,7,2,4,6),9]  –key=1
第三趟:[0,1,(3,2,4),5,(8,7,6),9] –key=5
第四趟:[0,1,2,3,4,5,6,7,8,9]   –key=3,8

示例代码

public static void QuickSort(int[] S){  //C#
    QuickSort(S, 0, S.Length - 1);
}
private static void QucikSort(int[] S, int low, int high){
    if (high > low){
        int pivotIndex = Partition(S, low, high);
        QuickSort(S, low, pivotIndex - 1);
        QuickSort(S, pivotIndex + 1, high);
    }
}
/// <summary>
/// 选取第一个数据为关键字,将比其小的数放置其左,比其大的数放置其右
/// </summary>
/// <returns>选取的关键字的位置索引</returns>
private static void Partition(int[] S, int low, int high){
    int pivot = S[low];//关键字
    while (low < high){
        while (low < high && S[high] >= pivot){
            high--;
        }
        S[low] = S[high];//将比关键字小的数放置其左
        while (low < high && S[low] >= pivot){
            low++;
        }
        S[high] = S[low];//比关键字大的数放置其右
    }
    S[low] = pivot;
    return low;//关键字的位置
}
def quick_sort(s, low, high):  #Python
    if high > low:
        index_pivot = partition(s, low, high)
        quick_sort(s, low, index_pivot-1)
        quick_sort(s, index_pivot+1, high)

def partition(s, low, high):
    pivot = s[low]
    while low < high:
        while low < high and s[high] >= pivot:
            high -= 1
        s[low] = s[high]
        while low < high and s[low] <= pivot:
            low += 1
        s[high] = s[low]
    s[low] = pivot
    return low

三向切分快速排序

  • 三向切分快速排序是对快速排序的改进。根据关键字将待排序列分为三部分:左边均小于关键字,中间均等于关键字,右边均大于关键字。
    当待排序列中有较多相等数据时,其排序效率高于快速排序。否则,效率低于快速排序。
  • 时间复杂度:最好 O(n)=O(n);平均O(n)=O(nlogn);最差O(n)=O(n2)
  • 空间复杂度:O(n)=O(n)
  • 稳定性:    不稳定

算法描述

对于每次切分:从数组的左边到右边遍历一次,维护三个指针lt,gthe i,其中

  • lt指针使得元素 (arr[0]-arr[lt-1]) 的值均小于切分元素;
  • gt指针使得元素(arr[gt+1]-arr[N-1])的值均大于切分元素;
  • i指针使得元素(arr[lt]-arr[i-1])的值均等于切分元素,(arr[i]-arr[gt])的元素还没被扫描,切分算法执行到i>gt为止。

每次切分之后,位于gt指针和lt指针之间的元素的位置都已经被排定,不需要再去移动了。之后将(lo,lt-1),(gt+1,hi)分别作为处理左子数组和右子数组的递归函数的参数传入,递归结束,整个算法也就结束。
Quick3Way
简书

排序示例

Quick3Way Demo
图片来自简书

示例代码

public static void Quick3WaySort(int[] S){  //C#
    Quick3WaySort(S, 0, S.Length - 1);
}
private static void Quick3WaySort(int[] S, int low, int high){
    if (high <= low){
        return;
    }
    int left = low;
    int right = high;
    int pivot = S[low];//用于比较的关键字
    int i = low + 1;

    while (i <= right){
        if (S[i] < pivot){
            S.Swap(left++, i++); //小于关键字的元素放左边
        } else if (S[i] > pivot){
            S.Swap(right--, i);  //大于关键字的元素放右边
        } else{
            i++; //等于关键字的元素放中间
        }
    }
    Quick3WaySort(S, low, left -1);   //对左边进行排序
    Quick3WaySort(S, right + 1, high);//对右边进行排序
}
def quick3way_sort(s, low, high):  #Python
    if high > low:
        left = low
        right = high
        i = low + 1
        pivot = s[low]
        while i <= right:
            if s[i] < pivot:
                s[left], s[i] = s[i], s[left]
                i += 1
                left += 1
            elif s[i] > pivot:
                s[i], s[right] = s[right], s[i]
                right -= 1
            else:
                i += 1
        quick3way_sort(s, low, left-1)
        quick3way_sort(s, right+1, high)

文中若有什么错误,欢迎留言指正。

转载请保留出处:http://blog.csdn.net/x1060549/article/details/78789799

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值