• 快速排序 [Java实现]


    快速排序又被称为分割交换排序,是目前公认最佳的排序方法。它的原理和冒泡排序一样都是用交换的方式,不过它会现在数据中找到一个虚拟的中间值作为基准数,把小于这个基准数的数据放到它的左边,大于这个基准数的数据放到它的右边,再以递归的方式处理这个基准数左右两边的数据,直到完成为止。

    假设我们有一组数56,18,6,3,97,66,8,26,88,30,99,93

    第一轮,我们将56视为基准数

    将大于它的数据放到它的右边,小于它的数据放到它的左边

    再将最左侧的8视为基准数,将大于它的数据放到它的右边,小于它的数据放到它的左边

    再选定6为基准数

    左侧只剩一个3,不用排它也已经归为

    我们再来排8的右侧,以18为基准数

    这样,18就归归位了,它的左侧没有其它数字,那么我们再看它的右边,以30为基准数

    排序过后左边就完成了

    右边同理

    不断的把左侧第一个数据当作基准数,一个一个地归为

    通过上述图解,我们应该理解了快速排序的基本思路,这样我们就可以写出一个大致的框架:

     1 //将索引left到right区间的下标元素进行快速排序
     2 public static void quickSort(int[] arr,int left,int right) {
     3      if(left>=right)return;//如果left大于等于right,方法结束
     4      int p = arr[left];//设置最左边的元素为基准点
     5      
     6      
     7      ··· ···//把序列当中比p大的放到右边,比p小的
     8      ··· ···//放到左边,p放置在下标为i的位置
     9         
    10      
    11      quickSort(arr,left,i-1);//对序列中i左边的元素实施快速排序
    12      quickSort(arr,i+1,right);//对序列中i右边的元素实施快速排序
    13  }            

    大致框架写好了,我们所要研究的就是中间的代码,怎样做到基准数的左侧都小于它,右侧都大于它呢?我们先用图片的方式来看一下:

     首先我们设置两个循环变量,i 指向最左边,j 指向最右边,变量 p 的值为最左边的元素的值

    先让 j 向左移动,一直到碰到一个比 p 的值小的元素

    再让 i 向右移动,一直到碰到一个比 p 的值大的元素

    这两个元素交换一下位置

    接着我们重复之前的行为,让 j 继续向左移动,一直到它再次碰到一个比 p 值小的元素

    然后,i 再向右移动,一直到它再次碰到一个比 p 值大的元素

    找到之后,再交换一下

    接着我们继续让 j 去找比p小的值,让 i 去找比p大的值

     当我们发现,i 等于 j 时,交换 p 和 j 的元素,

     

    这样,我们的第一轮排序就完成了

    我们通过代码来实现一下这一轮所进行的行为:

     1 //设置最左边的元素为基准点
     2 int p = arr[left];
     3         
     4 //把要排序的序列中比p大的放到右边,比p小的放到左边,p的下标位置为i
     5 int i = left,j=right;
     6 while(i!=j) {
     7     //j向左移动,找到一个比p小的元素
     8     while(arr[j]>=p && i<j) {
     9         j--;
    10     }
    11     //i向右移动,找到一个比p大的元素
    12     while(arr[i]<=p && i<j) {
    13         i++;
    14     }
    15     //i和j交换,如果i>j则不交换
    16     if(i<j) {
    17         int temp = arr[i];
    18         arr[i] = arr[j];
    19         arr[j] = temp;
    20     }
    21 }
    22 //将j找到的最后一个比p小的值与基准值交换
    23 arr[left] = arr[i];
    24 arr[i] = p;

    我们再将这段代码套入之前的框架

     1     public static void quickSort(int[] arr,int left,int right) {
     2         //如果left大于等于right,则需要排序的部分至多只有一个元素,方法结束
     3         if(left>=right) {
     4             return;
     5         }
     6         //设置最左边的元素为基准点
     7         int p = arr[left];
     8         
     9         //把要排序的序列中比p大的放到右边,比p小的放到左边,p的下标位置为i
    10         int i = left,j=right;
    11         while(i!=j) {
    12             //j向左移动,找到一个比p小的元素
    13             while(arr[j]>=p && i<j) {
    14                 j--;
    15             }
    16             //i向右移动,找到一个比p大的元素
    17             while(arr[i]<=p && i<j) {
    18                 i++;
    19             }
    20             //i和j交换,如果i等于j则不用再交换
    21             if(i<j) {
    22                 int temp = arr[i];
    23                 arr[i] = arr[j];
    24                 arr[j] = temp;
    25             }
    26         }
    27         //将j找到的最后一个比p小的值与基准值交换
    28         arr[left] = arr[i];
    29         arr[i] = p;
    30         
    31         //对序列中,j左边的元素实施快速排序
    32         quickSort(arr,left,i-1);
    33         //对序列中,j右边的元素实施快速排序
    34         quickSort(arr,i+1,right);35     }

    这样,我们的快速排序算法就写完啦

    我们将举例的一组数据输入,来测试一下:

    你学会了吗?

  • 相关阅读:
    CPP标准模板库 随笔
    C++ Concurrency In Action 一些重点
    标准模板库(STL)
    单链表常见操作
    android三大组件之Intent
    数组k平移三种方法(java)
    java中空字符串、null的区别
    java最大最小堆
    java学习笔记之基础知识
    笔试题集锦
  • 原文地址:https://www.cnblogs.com/Miic517x/p/9088722.html
Copyright © 2020-2023  润新知