• 快排算法的实现


    先来说网上流行最多的实现,用两个指针,一个从前往后,一个从后往前。直接上代码,如下。

     1 package com.jeaven;
     2 
     3 public class Solution2 {
     4     public void quick_sort(int[] arr, int begin, int end) {
     5         if(begin < end) {
     6             int mid = partition(arr, begin, end);
     7             quick_sort(arr, begin, mid-1);
     8             quick_sort(arr, mid+1, end);
     9         }
    10     }
    11     
    12     
    13     /* 双向指针的快排思路
    14      * 前一个指针指向开始元素begin,第二个指针指向数组倒数第二个end-1,最后一个元素为轴pivot
    15      *当arr[i] > pivot时,交换arr[i]和arr[j]然后 j=j-1
    16      *当arr[i] < pivot时,就i++
    17      *最终当i和j重合的时候相遇,再将轴归位返回轴的位置,注意下标即可
    18     */
    19     public int partition(int[] arr, int begin, int end) {
    20         int pivot = arr[end];
    21         int i = begin;
    22         int j = end - 1;
    23         while(i < j) {
    24             if(arr[i] > pivot) {
    25                 int temp = arr[j]; 
    26                 arr[j] = arr[i];
    27                 arr[i] = temp;
    28                 j--;
    29             } else {
    30                 i++;
    31             }
    32         }
    33         int temp = arr[j+1];
    34         arr[j+1] = arr[end];
    35         arr[end] = temp;
    36         return j+1;
    37     }
    38     
    39     public static void main(String[] args) {
    40         int[] arr = {1,4,2,3,5};
    41         new Solution2().quick_sort(arr, 0, arr.length-1);
    42         for(int c : arr) {
    43             System.out.print(c + " ");
    44         }
    45     }
    46 }

    再来说说我最喜欢的风格,也是算法导论上的快排实现方法,两个指针从同一边开始,算法导论的思路很清晰,还给出了完整的理论推导,不变性的证明,有兴趣的可以去看看算法道路的快排章节。

    下面是算法导论关于快排的实现思路,如下:

     然后我给出java版本的快排实现:

     1 package com.jeaven;
     2 
     3 public class Solution3 {
     4     public void quick_sort(int[] arr, int begin, int end) {
     5         if(begin < end) {
     6             int mid = partition(arr, begin, end);
     7             quick_sort(arr, begin, mid-1);
     8             quick_sort(arr, mid+1, end);
     9         }
    10     }
    11     
    12     public int partition(int[] arr, int begin, int end) {
    13         int pivot = arr[end];
    14         int i = begin - 1;
    15         for(int j = begin; j < end; j++) {
    16             if(arr[j] < pivot) {
    17                 i++;
    18                 int temp = arr[j];
    19                 arr[j] = arr[i];
    20                 arr[i] = temp;
    21             }
    22         }
    23         int temp = arr[i+1];
    24         arr[i+1] = arr[end];
    25         arr[end] = temp;
    26         return i+1;
    27     }
    28     
    29     public static void main(String[] args) {
    30         int[] arr = {1,4,2,3,5};
    31         new Solution3().quick_sort(arr, 0, arr.length-1);
    32         for(int c : arr) {
    33             System.out.print(c + " ");
    34         }
    35     }
    36 }

    说明:我喜欢选最后一个元素为轴pivot,当然可以选取数组任意位置为轴,即使分的恨不均匀,但是可以证明除了极端情况,时间复杂度仍然为O(nlgn)。如果选取其他位置作为轴,代码实现的时候可以先将轴和最后一个元素交换位置,这样就可以看成是最后一个位置是轴,就可以很容易实现。

  • 相关阅读:
    如何提高游戏中的打击感?
    javascript !!作用
    cocos2d-x图片变灰或者变亮
    cocos2d-x生成随机数
    javaScript 类型判断
    Cocos2dx游戏源码合集(BY懒骨头+持续更新+2014.02.21)
    (译)如何优化cocos2d程序的内存使用和程序大小:第二部分(完)
    (译)如何优化cocos2d程序的内存使用和程序大小:第一部分
    游戏中的心理学(一):认知失调有前提条件
    java定时任务
  • 原文地址:https://www.cnblogs.com/jeavenwong/p/11712260.html
Copyright © 2020-2023  润新知