• 排序算法-快速排序


    属性

            快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中的某元 素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有 元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。

            . 1.快速排序整体的综合性能和使用场景都是比较好的,所以才敢叫快速排序

              2. 时间复杂度:O(N*logN)

    代码及注释(递归写法)

    1. public static void quickSort(int[]arr){
    2. quick1(arr,0,arr.length-1);
    3. }
    4. private static void quick(int[]arr,int begin,int end){
    5. //出递归
    6. if(begin>=end){
    7. return;
    8. }
    9. //由于参考值的取值要尽量取数据的中间值,所以我们可以拿begin,end和mid下标的中间值来作为参考值
    10. //获得了中间值的下标tmpIndex
    11. int tmpIndex=threeMid(arr,begin,end);
    12. //将中间值交换到第一个位置作为参考值
    13. swap(arr,begin,tmpIndex);
    14. //进行数据的划分,将小于参考值的数据放到左边,大于参考值的数据放到右边
    15. //得到划分好数据后,参考值最终放到的位置(参考值排序后的下标)
    16. int rid=parttion1(arr,begin,end);
    17. //以同样的方式划分参考值左边和右边的数据
    18. quick(arr,begin,rid-1);
    19. quick(arr,rid+1,end);
    20. }
    21. //进行begin-end范围内数据的划分,将小于参考值的数据放到左边,大于参考值的数据放到右边
    22. private static int parttion1(int[]arr,int begin,int end){
    23. //用挖坑法进行划分
    24. int tmp=arr[begin];
    25. while (begin
    26. //现在begin下标相当于已经没有数据了,是一个坑,要通过end下标找到一个比参考值小的值放到这个坑中
    27. while (begin=tmp){
    28. end--;
    29. }
    30. //跳出了上面的循环说明找到了一个比参考值小的数据
    31. //将数据放到坑中
    32. arr[begin]=arr[end];
    33. //现在end下标相当于已经没有数据了,是一个坑,要通过begin下标找到一个比参考值大的值放到这个坑中
    34. while (begin
    35. begin++;
    36. }
    37. //跳出了上面的循环说明找到了一个比参考值大的数据
    38. //将数据放到坑中
    39. arr[end]=arr[begin];
    40. }
    41. //当begin和end指向一个下标时便退出了循环,而他们指向的这个下标是一个坑(没有数据)
    42. //将参考值放到这个坑中
    43. arr[begin]=tmp;
    44. //返回参考值所在的下标,方便去划分参考值左边和右边的数据
    45. return begin;
    46. }
    47. //在array数组中找到下标begin,mid,end的中间值
    48. private static int threeMid(int[] array,int begin,int end){
    49. int mid=(begin+end)/2;
    50. if(array[begin]>array[end]){
    51. if(array[end]>array[mid]){
    52. return end;
    53. }
    54. else if(array[mid]>array[begin]){
    55. return begin;
    56. }
    57. else {
    58. return mid;
    59. }
    60. }
    61. else {
    62. if (array[mid]>array[end]){
    63. return end;
    64. } else if (array[begin]>array[end]) {
    65. return begin;
    66. }
    67. else {
    68. return mid;
    69. }
    70. }
    71. }
    72. private static void swap(int[] array,int m,int n){
    73. int tmp=array[m];
    74. array[m]=array[n];
    75. array[n]=tmp;
    76. }

    代码及注释(非递归写法)

            其实非递归写法的思路和递归相同,只是非递归要自己创建一个栈来模拟出递归的效果而已

    1. //非递归实现快速排序
    2. public static void quickSortNoRrcur(int[] array) {
    3. //当排序的数目小于一定范围时直接用插入排序
    4. if(array.length<5){
    5. InsertSort insertSort=new InsertSort();
    6. insertSort.insertSort(array);
    7. return;
    8. }
    9. Stack stack=new Stack<>();
    10. int start=0;
    11. int end=array.length-1;
    12. //三数取中
    13. int midIndex=threeMid(array, start, end);
    14. //把三个数中位于中间的值放到第一位
    15. swap(array,start,midIndex);
    16. //挖坑法将比array[begin]小的放左边,大的放右边
    17. int rid=parttion(array, start, end);
    18. //判断是否满足入栈条件
    19. if(rid>start+1){
    20. stack.push(start);
    21. stack.push(rid-1);
    22. }
    23. if(rid1){
    24. stack.push(rid+1);
    25. stack.push(end);
    26. }
    27. while (!stack.empty()){
    28. end=stack.pop();
    29. start=stack.pop();
    30. //当排序的数目小于一定范围时直接用插入排序
    31. if(end-start+1<5){
    32. InsertSort insertSort=new InsertSort();
    33. insertSort.insertSort(array);
    34. return;
    35. }
    36. //三数取中
    37. midIndex=threeMid(array, start, end);
    38. //把三个数中位于中间的值放到第一位
    39. swap(array,start,midIndex);
    40. //挖坑法将比array[begin]小的放左边,大的放右边
    41. rid=parttion(array, start, end);
    42. //判断是否满足入栈条件
    43. if(rid>start+1){
    44. stack.push(start);
    45. stack.push(rid-1);
    46. }
    47. if(rid1){
    48. stack.push(rid+1);
    49. stack.push(end);
    50. }
    51. }
    52. }
    53. private static int threeMid(int[] array,int begin,int end){
    54. int mid=(begin+end)/2;
    55. if(array[begin]>array[end]){
    56. if(array[end]>array[mid]){
    57. return end;
    58. }
    59. else if(array[mid]>array[begin]){
    60. return begin;
    61. }
    62. else {
    63. return mid;
    64. }
    65. }
    66. else {
    67. if (array[mid]>array[end]){
    68. return end;
    69. } else if (array[begin]>array[end]) {
    70. return begin;
    71. }
    72. else {
    73. return mid;
    74. }
    75. }
    76. }
    77. private static void swap(int[] array,int m,int n){
    78. int tmp=array[m];
    79. array[m]=array[n];
    80. array[n]=tmp;
    81. }

  • 相关阅读:
    SQL explain解析器
    Linux学习-37-查看文件系统硬盘信息(df、du命令)
    Ansible中的角色使用
    HTTP1.1强制缓存和协商缓存
    爬虫——爬虫初识、requests模块
    canvas力导布局
    护眼台灯哪个牌子最好?护眼台灯品牌实时排行榜分享
    Linux-进程管理
    接口自动化测试专栏博客汇总
    uni-app 开发调试自动打开手机屏幕大小界面(Aidex移动端开发项目)
  • 原文地址:https://blog.csdn.net/q322359/article/details/132881646