• JAVA数据结构--快速排序


    快排概念

    快速排序英语:Quicksort),又称划分交换排序partition-exchange sort),一种排序算法,最早由东尼·霍尔提出。在平均状况下,排序n个项目要{displaystyle O(nlog n)}(大O符号)次比较。在最坏状况下则需要O(n^{2})次比较,但这种状况并不常见。事实上,快速排序通常明显比其他{displaystyle O(nlog n)}算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。

    实现思想

    快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists)。

    步骤为:

    1. 从数列中挑出一个元素,称为"基准"(pivot),
    2. 重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(相同的数可以到任何一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
    3. 递归地(recursively)把小于基准值元素的子数列和大于基准值元素的子数列排序。

    递归到最底部时,数列的大小是零或一,也就是已经排序好了。这个算法一定会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

    借用下啊哈算法的图:

    094811yilrz1tkzkvlrriz.png

    i和j分别为左哨兵和右哨兵,这里枢纽元定为6,然后分别从左往右(i++)和右往左(j--)开始遍历

    左哨兵查找比6大的元素,右哨兵查找比6小的元素

    第一次交换结果

    095430axy0qkhxxkktkktk.png

    095437kdandfxhbtokk2qh.png

    第二次交换结果

    095448k1kevwlz41373e7k.png

    095458ejza15wscjv7iw5c.png

    095506uz7e1uuukcblhkxv.png

    相遇后直接与枢纽元交换

    095514cag5fumuqqg5jnsw.png

    095530e0jf6p0y6aaaw2ir.png

    然后再递归排序就行

    232129ogop8gk0r8y7l70k.png


    快排核心算法代码

     1 public static <T extends Comparable<? super T>> void quicksort(T[] a,int left,int right) {
     2         /*
     3          * 当数组不小于3时,才推荐使用快排
     4          * */
     5         if(left+CUTOFF<=right)
     6         {
     7             //取出枢纽元,枢纽元的位置为right-1
     8             T privot=median3(a, left, right);
     9             
    10             int i=left,j=right-1;
    11             for(;;)
    12             {
    13                 while(a[++i].compareTo(privot)<0) {}//i哨兵向右遍历
    14                 while(a[--j].compareTo(privot)>0) {}//j哨兵向左遍历
    15                 if(i<j)
    16                     swapReferences(a, i, j);
    17                 else
    18                     break;
    19             }
    20             /*
    21              * for循环终止条件为i和j相遇,此时再将枢纽元归位
    22              * */
    23             swapReferences(a, i, right-1);
    24             
    25             quicksort(a, left, i-1);//对左半部进行递归
    26             quicksort(a, i+1, right);//对右半部进行递归
    27         }
    28         else
    29         {}
    30     }

    全部代码实现

     1 public class MyQuickSort {
     2     private static final int CUTOFF=3;
     3     public static <T extends Comparable<? super T>> void quicksort(T[] a) {
     4         quicksort(a,0,a.length-1);
     5     }
     6     public static <T extends Comparable<? super T>> void quicksort(T[] a,int left,int right) {
     7         /*
     8          * 当数组不小于3时,才推荐使用快排
     9          * */
    10         if(left+CUTOFF<=right)
    11         {
    12             //取出枢纽元,枢纽元的位置为right-1
    13             T privot=median3(a, left, right);
    14             
    15             int i=left,j=right-1;
    16             for(;;)
    17             {
    18                 while(a[++i].compareTo(privot)<0) {}//i哨兵向右遍历
    19                 while(a[--j].compareTo(privot)>0) {}//j哨兵向左遍历
    20                 if(i<j)
    21                     swapReferences(a, i, j);
    22                 else
    23                     break;
    24             }
    25             /*
    26              * for循环终止条件为i和j相遇,此时再将枢纽元归位
    27              * */
    28             swapReferences(a, i, right-1);
    29             
    30             quicksort(a, left, i-1);//对左半部进行递归
    31             quicksort(a, i+1, right);//对右半部进行递归
    32         }
    33         else
    34         {}
    35     }
    36     /*
    37      * 数组中数值交换
    38      * */
    39     public static <T> void swapReferences(T[] a,int index1,int index2) {
    40         T tmp=a[index1];
    41         a[index1]=a[index2];
    42         a[index2]=tmp;
    43     }
    44     /*
    45      * 确定枢纽元,枢纽元的位置放在right-1位置
    46      * */
    47     private static <T extends Comparable<? super T>> T median3(T[] a,int left,int right) {
    48         int center=(left+right)/2;
    49         if(a[center].compareTo(a[left])<0)
    50             swapReferences(a, left, center);
    51         if(a[right].compareTo(a[center])<0)
    52             swapReferences(a, center, right);
    53         if(a[right].compareTo(a[left])<0)
    54             swapReferences(a, left, right);
    55         
    56         swapReferences(a, center, right-1);
    57         return a[right-1];
    58     }
    59 }
    View Code
  • 相关阅读:
    生成器
    装饰器
    类的特殊方法
    获取对象的信息之反射
    获取对象信息之内置函数dir()
    获取对象的信息之内置函数type()
    获取对象的信息之内置函数issubclass() 和 isinstance()
    生成可下载图片
    js数组常用方法
    sql存储过程基本语法
  • 原文地址:https://www.cnblogs.com/vi3nty/p/8033147.html
Copyright © 2020-2023  润新知