排序算法之快速排序(java、python和C++实现)

xiaoxiao2021-02-28  58

快速排序的基本思想

快速排序是对起泡排序(冒泡排序)的改进,采用分治思想。在各种排序方法中,快速排序比较次数较少,速度较快。

给出一组待排序的数据记录。我们需要选择一个基准值作为分区标准,通常我们取第一个记录或者最后一个记录作为基准值。然后再将所有小于该基准值的记录移到左边,将所有大于该基准值得记录移到右边,中间放基准值记录,称为一趟排序。接着,对左右两个子序列分别重复上述过程。继续下去,直到所有的记录都排好序。

算法原理

例题:

待排序的数组:{5,7,2,9,1,4,6,8,10,3}

期望排好序后的数组:{1,2,3,4,5,6,7,8,9,10}

例题解析:

第一步:选择数组的第一个数据作为基准值,即 5

第二步:首先从左边开始,也就是从第二个数据开始与基准值比较。若小于基准值,则继续比较下一条数据;若大于基准值,则停止比较,并记录下大于基准值的数据的索引(下标)

第三步:从最右边的数据与比较起,若大于基准值,则继续比较下一条数据;若小于基准值,则停止比较,并记录下小于基准值的数据的索引(下标)

第四步:将左边大于基准值的数据与右边小于基准值的数据交换。

第五步:重复第二、三、四步,直到将数组中所有数据比较完。这时需要将第一个数据也就是基准值交换到左右分好的序列中间来。这时数组分成两边,左边的数据都小于基准,右边的数据都大于基准值。

第六步:将左右两边的数据分别重复以上五个步骤,直到所有数据排好序。注意,接下来的每一趟排序不是以5作为基准值了,而是以左右两边的数据的第一个数据作为基准值。

例题数组的每一趟排序的结果:

【】内是下一趟要比较的序列

第一趟后:{【1,3,2,4】,5,【9,6,8,10,7】}

第二趟后:{1,【3,2,4】,5,9,6,8,10,7}

第三趟后:{1,2,3,4,5,【9,6,8,10,7】 }

第四趟后:{1,2,3,4,5,【7,6,8】,9,【10】 }

第五趟后:{1,2,3,4,5,【6 】,7,【 8 】,9,10 }

java实现的代码:

public class QuickSort { public static void main(String[] args) { //要进行排序的数组 int[] a = {5,7,2,9,1,4,6,8,10,3}; //将数组a从小到大排序 quickSort(a, 0, a.length-1); //打印数组 printArray(a); } /** * 快速排序 * 将数组a的某一段元素进行划分,小的在左边,大的在右边 * @param a * @param left * @param right */ private static void quickSort(int[] a, int left, int right) { //如果只有一个元素,就不用再排下去了 if(left < right){ int pivot = a[left]; //用序列最左边的记录作为基准值 int i = left, j = right; while(i < j){ //从左边开始遍历,如果比基准值小,就继续向右走 while(i < j && a[i] <= pivot) i++; //从右边开始遍历,如果比基准值大,就继续向左走 while(i < j && a[j] > pivot) j--; //上面的while循环结束时,就说明当前的a[i]的值比基准值大, //当前的a[j]的值比基准值小,a[i]应与a[j]互换 if(i < j){ swap(a, i, j); } } //分组结束后,要将基准值交换到两组之间 swap(a, left, i-1); //继续递归排序左边的序列 quickSort(a, left, i-2); //继续递归排序右边的序列 quickSort(a, i, right); } } /** * 交换数组a中索引为 i 和 j 之间的数值 * @param a * @param i * @param j */ private static void swap(int[] a, int i, int j) { int temp = a[i]; a[i] = a[j]; a[j] = temp; } //打印数组 private static void printArray(int[] a) { for(int i = 0;i < a.length;i++){ System.out.print(a[i] + " "); } } }

python实现的代码:

def quickSort(a, l, r): if l < r: pivot = a[l] i = l j = r while i < j: while i < j and a[i] <= pivot: i += 1 while i < j and a[j] > pivot: j -= 1 if i < j: swap(a, i, j) swap(a, l, i-1) quickSort(a, l, i-2) quickSort(a, i, r) def swap(a,i,j): temp = a[i] a[i] = a[j] a[j] = temp a = [5,7,2,9,1,4,6,8,10,3] quickSort(a,0,len(a)-1) print(a)

C++实现的代码与java的代码基本一样,只需要修改极少的部分:

#include <iostream> using namespace std; /** * 交换数组a中索引为 i 和 j 之间的数值 * @param a * @param i * @param j */ void swap(int a[], int i, int j) { if(i != j) { int temp = a[i]; a[i] = a[j]; a[j] = temp; } } //打印数组 void printArray(int a[], int len) { for(int i = 0;i < len;i++) { cout<<a[i]<<" "; } } void quickSort(int a[], int left, int right) { //如果只有一个元素,就不用再排下去了 if(left < right){ int pivot = a[left]; //用序列最左边的记录作为基准值 int i = left, j = right; while(i < j){ //从左边开始遍历,如果比基准值小,就继续向右走 while(i < j && a[i] <= pivot) i++; //从右边开始遍历,如果比基准值大,就继续向左走 while(i < j && a[j] > pivot) j--; //上面的while循环结束时,就说明当前的a[i]的值比基准值大, //当前的a[j]的值比基准值小,a[i]应与a[j]互换 if(i < j){ swap(a, i, j); } } //分组结束后,要将基准值交换到两组之间 swap(a, left, i-1); //继续递归排序左边的序列 quickSort(a, left, i-2); //继续递归排序右边的序列 quickSort(a, i, right); } } int main(int argc, char* argv[]) { int a[] = {5,7,2,9,1,4,6,8,10,3}; int len = sizeof(a)/sizeof(int); quickSort(a, 0 , len-1); printArray(a, len); return 0; }
转载请注明原文地址: https://www.6miu.com/read-2627755.html

最新回复(0)