高级排序算法之双路快速排序

双路快速排序算法分析

对于具有大量重复数据的排序按照之前的方式性能会很低,现在我们增加两个标志,想办法把大量重复的数据分到两部分,例如设置v作为标志数据,让等于v的数据分为两部分,如下图所示,这样可以避免两边的数据出现一边倒的情况。

根据以上算法的思想,代码修改如下:

//双路快速排序算法:解决具有大量重复源数据排序慢的问题
template<typename T>
int _partition2Ways(T arr[], int l, int r)
{
    //优化点2:通过随机选择元素标志,防止对几乎有序的数据排序慢的问题
    srand(time(NULL));
    swap(arr[l], arr[rand()%(r-l+1)+l]);

    T v = arr[l];

    int i = l+1, j = r;      //arr[l+1...j] < v ; arr[j+1...r] > v
    while(true)
    {
        while(i <= r && arr[i] < v)
            i++;
        while(j >= l && arr[j] > v)
            j--;

        if(i > j)
            break;

        swap(arr[i], arr[j]);
        i++;
        j--;
    }

    swap(arr[l], arr[j]);
    return j;
}

template<typename T>
void _quickSort2Ways(T arr[], int l, int r)
{
    //优化点1:小规模数据使用插入排序
    if(r-l <= 15)
    {
        insertionSort(arr, l, r);
        return;
    }

    int p = _partition2Ways(arr, l, r); //调用双路快速排序
    _quickSort2Ways(arr, l, p-1);
    _quickSort2Ways(arr, p+1, r);
}

template<typename T>
void quickSort2Ways(T arr[], int n)
{
    srand(time(NULL));
    _quickSort2Ways(arr, 0, n-1);
}

  

经过性能测试,双路排序算法对具有大量重复的数据排序性能很好,但是在此基础上还可以进行优化,请查看三路快速排序算法的实现。

原文地址:https://www.cnblogs.com/baihl/p/10674371.html

时间: 2024-08-03 12:16:58

高级排序算法之双路快速排序的相关文章

高级排序算法之三路快速排序

三路快速排序算法分析 双路快速排序算法把等于v的数据分为两部分,方式了数据量一边倒的情况,三路排序算法把排序的数据分为三部分,分别为小于v,等于v,大于v,这样三部分的数据中,等于v的数据在下次递归中不再需要排序,小于v和大于v的数据也不会出现某一个特别多的情况(如下图所示),通过此方式三路快速排序算法的性能更优. 三路快速排序主要关注三个标志,分别为lt,i,gt,这三个标志会把数据分为四部分,arr[l+1...lt]的数据全部小于v,arr[lt+1...i-1]的数据等于v,arr[i.

高级排序算法之快速排序

快速排序是一个高级排序算法,算法核心思想:确定每一个值的正确位置,即该值左边为小,右边为大即可 这个算法实现上面也是需要经过递归,一般取第一个值开始进行排序 当然也有特别需要注意的地方 设 需要找正确位置的值 定义为 arr[ l ]  = v; 此时需要比较 值 e 与 v 的关系,无非两种(三种即多一个等于) 若e > v ,则无话可说,无需移动,继续移动游标比较arr[ i + 1]  与 v 的大小 若 e < v,则需要交换  e  和 arr [ j + 1 ] 的值,并需要将 j

双路快速排序法

1.算法出现的背景 之前讲的,当我们排序的是一个近乎有序的序列时,快速排序会退化到一个O(n^2)级别的排序算法,而对此的改进就是 引入了随机化快速排序算法:但是当我们的排序的是一个数值重复率非常高的序列时,此时随机化快速排序算法就不再起作用 了,而将会再次退化为一个O(n^2)级别的排序算法,那为什么会出现这种情况呢?且听下面的分析: 如上图所示就是之前分析的快速排序算法的partition的操作原理,我们通过判断此时i索引指向的数组元素e>v还是<v, 将他放在橙色或者是紫色两个不同的位置

排序算法之 Java简单快速排序算法

package net.qh.test.sort; import java.util.ArrayList; import java.util.Calendar; import java.util.List; /** * Created by Administrator on 2016/03/01. */ public class SimpleQuick { public int[] sort(int[] arr,int left,int right){ if ( arr == null || a

javascript数据结构与算法--高级排序算法

高级排序算法是处理大型数据集的最高效排序算法,它是处理的数据集可以达到上百万个元素,而不仅仅是几百个或者几千个.现在我们来学习下2种高级排序算法---- 希尔排序和快速排序. 一:希尔排序: 希尔排序的核心理念是:首先比较距离较远的元素,而非相邻的元素. 基本原理:通过定义一个间隔序列来表示在排序过程中进行比较的元素之间有多远的间隔. 下面我们来看看数组[0,9,1,8,7,6,2,3,5,4] 来使用希尔排序的原理:如下图: 代码分析如下: 1. 执行 "间隔序列=3的步骤" A.

java算法面试题:设计一个快速排序。双路快速排序,简单易于理解。

package com.swift; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class QuickSort { /* * 快速排序 */ public static void main(String[] args) { int[] strVoid = new int[] { 11, 66, 22, 0,

数据结构之高级排序算法

一.希尔排序 希尔排序(缩小增量法) 属于插入类排序,由Shell提出,希尔排序对直接插入排序进行了简单的改进:它通过加大插入排序中元素之间的间隔,并在这些有间隔的元素中进行插入排序,从而使数据项大跨度地移动,当这些数据项排过一趟序之后,希尔排序算法减小数据项的间隔再进行排序,依次进行下去,进行这些排序时的数据项之间的间隔被称为增量,习惯上用字母h来表示这个增量. 具体代码实现: 1 package data.struct.algorithm; 2 3 //高级排序算法之希尔排序 4 class

#排序算法#【4】快速排序

快速排序法是对冒泡排序的一种改进,本来是要和冒泡排序写在一个文章里的,不过前两天刚开始在递归调用的时候没有完全理解,昨天晚上google了一把发现原来自己理解错了,我看的这个教材没有写清楚,今天早上调试了一把终于成功. 快速排序算法的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列. 快速排序使用分治策略来把待排序数据序列分为两个子序列

几种排序算法的C++实现——快速排序、堆排序、基数排序

排序算法是非常常见的面试笔试问题,考查的一个人的基本功,本文将一些排序做了C++的实现,就当是做个学习总结吧. 1.快速排序 快速排序的中心是填坑法,取一个数(这里选取第一个数)作为基准数temp,从队尾开始寻找第一个比基准数小的数a[j],交换a[j]和temp,然后队首开始查找第一个比temp大的数a[i],交换之,遍历的结果是当i>=j时,temp左边的数都小于temp,后边的数都大于temp,这个有点像归并排序.最后利用递归调用完成排序,代码如下: 1 void QuickSort(in