快速排序之单轴快排实现

会有一股神秘感。 提交于 2020-03-06 16:09:41

文章摘自:

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Holmofy/article/details/71168530

快速排序使用的是分治思想,将原问题分成若干个子问题进行递归解决。通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

单轴快排(SinglePivotQuickSort)

单轴快速排序是快速排序最简单的实现。

步骤如下:

如果待排序的数组项数为0或1,直接返回。(递归出口)
在待排序的数组中任选一个元素,作为中心点(pivot)。
将小于pivot的元素,大于pivot的元素划分为开来。也就是将小于中心点的元素放在中心点前面,大于中心点的元素放在中心点后面。
对前面小于pivot的元素进行快速排序,对大于pivot的元素进行快速排序。
如何将大于pivot和小于pivot的元素进行划分是实现快速排序的关键

元素划分的方式
两端扫描交换方式
在这里插入图片描述
注意 :i 与 j 必须交错,如果两者相遇之后就停止比较,那相遇点所在的元素就没有和中心点进行比较。

/**
 * 双端扫描交换 Double-End Scan and Swap
 *
 * @param items
 *            待排序数组
 */
public void deScanSwapSort(int[] items) {
    deScanSwapSort(items, 0, items.length - 1);
}

public void deScanSwapSort(int[] items, int start, int end) {
    if (start < end) {
        int pivot = items[start];

        int i = start + 1, j = end;
        while (i <= j) {
            while (i <= j && items[i] < pivot)
                i++;
            while (i <= j && items[j] >= pivot)
                j--;
            if (i <= j) {
                swap(items, i, j);
            }
        }
        swap(items, start, j);// 将中心点交换到中间。
        deScanSwapSort(items, start, j - 1);// 中心点左半部分递归
        deScanSwapSort(items, j + 1, end);// 中心点右半部分递归
    }
}

private void swap(int[] items, int i, int j) {
    int tmp = items[i];
    items[i] = items[j];
    items[j] = tmp;
}

单向扫描划分方式
前面的i,j标记都是相向而行,i标记负责找比pivot大的元素,j标记负责比pivot小的元素。下面要说的这种实现方式中思想与前两者不太一样:

初始时,i=start,j=start+1;j 负责扫描整个序列。
在这里插入图片描述

扫描过程中始终保持:序列中start+1~ i 是小于pivot;i+1~ j 是大于pivot的。

在这里插入图片描述

为了保持2的特性,j扫描时遇到小于pivot的元素,i++,并将i元素与j元素进行交换,然后扫描下一个元素;

在这里插入图片描述

遇到大于pivot的元素,直接扫描下一个元素。

在这里插入图片描述

整个序列扫描完成后,将第一个元素pivot与小于pivot的元素的最后一个进行交换。

在这里插入图片描述

示例过程图如下:

在这里插入图片描述

实现代码:

/**
 * 单向扫描划分方式
 *
 * @param items
 *            待排序数组
 */
public void forwardScanSort(int[] items) {
    forwardScanSort(items, 0, items.length - 1);
}

public void forwardScanSort(int[] items, int start, int end) {
    if (start < end) {
        int pivot = items[start];
        int i = start, j = start + 1;
        while (j <= end) {
            if (items[j] < pivot) {
                i++;
                swap(items, i, j);
            }
            j++;
        }
        swap(items, start, i);
        forwardScanSort(items, start, i - 1);
        forwardScanSort(items, i + 1, end);
    }
}

————————————————
版权声明:本文为CSDN博主「Holmofy」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/holmofy/article/details/71168530

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!