• 排序算法系列:快速排序算法JAVA版(靠谱、清晰、真实、可用、不罗嗦版)


    在网上搜索算法的博客,发现一个比较悲剧的现象非常普遍:

    • 原理讲不清,混乱
    • 啰嗦
    • 图和文对不上
    • 不可用,甚至代码还出错

    为了不误人子弟耽误时间,推荐看一些靠谱的资源,如【啊哈!算法】系列:

    https://www.cnblogs.com/ahalei/p/3568434.html

    他是C语言实现,其实都是一样的。

    我总结一个清晰不罗嗦版:

    原理:

    快速排序使用分而治之策略。下面描述递归步骤:

    选择一个pivot支点值(在啊哈算法中叫“基准值”)。我们将中间元素的值作为支点值,但是它也可以是任何值,甚至它可以不存在于数组中。

    第一次排序:

    • 小于支点值的所有元素都到支点值的左侧
    • 而大于支点值的所有元素都到支点值的右侧
    • 与支点值相等的值保留。

    递归,再次以支点两侧排序:对两部分进行排序,将快速排序算法递归地应用到左右部分。数组可以以不相等数量的部分划分。

    算法要点:

    • 有两个索引i和j,在算法的第一次排序,i 指向数组中的第一个元素,j 指向最后一个元素。
    • i向前移动,直到找到一个值大于或等于支点值的元素。
    • 索引j向后移动,直到找到一个值小于或等于支点值的元素。
    • 如果i小于j,则它们被交换,然后进入下一个位置(i + 1),j进到前一个(j - 1)。
    • 当大于j时,算法停止。

    第一次排序的说明:

    在第一轮排序之后,会进入左右的递归。依次类推。

    复杂度分析

    排序方法 时间复杂度 空间复杂度 稳定性 复杂性
    平均情况 最坏情况 最好情况
    快速排序 O(nlog2n) O(n2) O(nlog2n) O(log2n) 不稳定 较复杂

    用JAVA实现(真实可用):

    package Sort;
    
    public class QuickSort {
        
        
        public static void main(String[] args) {
    
            int arr[] = {1, 12, 5, 26, 7, 14, 3, 7, 2}; 
            int n = arr.length; 
      
            QuickSort ob = new QuickSort(); 
            ob.quickSort(arr, 0, n-1); 
            //ob.sort(arr, 0, n-1); 
      
            System.out.println("快速排序结果:"); 
            printArray(arr); 
        }
        
        int partition(int arr[], int left, int right){
    
              int i = left, j = right;
              int tmp;
              int pivot = arr[(left + right) / 2];         
              System.out.println("pivot="+pivot+"; left="+left+"; right="+right); 
    
              while (i <= j) {
    
                    while (arr[i] < pivot){
                        System.out.println("跳过,i="+i+"; arr[i]="+arr[i]+", pivot="+pivot); 
                        i++;
                    }
    
                    while (arr[j] > pivot){
                        System.out.println("跳过,j="+j+"; arr[j]="+arr[j]+", pivot="+pivot); 
                        j--;
                    }
    
    
                    if (i <= j) {
                          System.out.println("交换前,i="+i+", j="+j+"; arr[i]="+arr[i]+", arr[j]="+arr[j]); 
    
                          tmp = arr[i];
                          arr[i] = arr[j];
                          arr[j] = tmp;
    
                          System.out.println("交换后,i="+i+", j="+j+"; arr[i]="+arr[i]+", arr[j]="+arr[j]); 
                          System.out.println("---"); 
    
                          i++;
                          j--;
    
                    }
              };         
    
              return i;
        }
         
        void quickSort(int arr[], int left, int right) {
    
              int index = partition(arr, left, right);
              if (left < index - 1){
                  System.out.println("递归 左侧,left="+left+", index="+index);
                  quickSort(arr, left, index - 1);
              }
    
              if (index < right){
                  System.out.println("递归右侧,right="+right+", index="+index);
                  quickSort(arr, index, right);
              }
        }
        
        static void printArray(int arr[]) 
        { 
            int n = arr.length; 
            for (int i=0; i<n; ++i) 
                System.out.print(arr[i]+" "); 
            System.out.println(); 
        } 
        
    
        //另一种简洁写法
         int partition1(int arr[], int low, int high) 
         { 
             int pivot = arr[high];  
             int i = (low-1); 
             for (int j=low; j<high; j++) 
             { 
    
                 if (arr[j] <= pivot) 
                 { 
                     i++; 
    
                     int temp = arr[i]; 
                     arr[i] = arr[j]; 
                     arr[j] = temp;
    
                 } 
             } 
           
             int temp = arr[i+1]; 
             arr[i+1] = arr[high]; 
             arr[high] = temp; 
    
             return i+1; 
         } 
    
    
         void sort(int arr[], int low, int high) 
         { 
             if (low < high) 
             { 
                 int pi = partition1(arr, low, high); 
    
                 sort(arr, low, pi-1); 
                 sort(arr, pi+1, high); 
             } 
         } 
    }

    调试信息:

    pivot=7; left=0; right=8
    跳过,i=0; arr[i]=1, pivot=7
    交换前,i=1, j=8; arr[i]=12, arr[j]=2
    交换后,i=1, j=8; arr[i]=2, arr[j]=12
    ---
    跳过,i=2; arr[i]=5, pivot=7
    交换前,i=3, j=7; arr[i]=26, arr[j]=7
    交换后,i=3, j=7; arr[i]=7, arr[j]=26
    ---
    交换前,i=4, j=6; arr[i]=7, arr[j]=3
    交换后,i=4, j=6; arr[i]=3, arr[j]=7
    ---
    跳过,j=5; arr[j]=14, pivot=7
    递归 左侧,left=0, index=5
    pivot=5; left=0; right=4
    跳过,i=0; arr[i]=1, pivot=5
    跳过,i=1; arr[i]=2, pivot=5
    交换前,i=2, j=4; arr[i]=5, arr[j]=3
    交换后,i=2, j=4; arr[i]=3, arr[j]=5
    ---
    跳过,j=3; arr[j]=7, pivot=5
    递归 左侧,left=0, index=3
    pivot=2; left=0; right=2
    跳过,i=0; arr[i]=1, pivot=2
    跳过,j=2; arr[j]=3, pivot=2
    交换前,i=1, j=1; arr[i]=2, arr[j]=2
    交换后,i=1, j=1; arr[i]=2, arr[j]=2
    ---
    递归 左侧,left=0, index=2
    pivot=1; left=0; right=1
    跳过,j=1; arr[j]=2, pivot=1
    交换前,i=0, j=0; arr[i]=1, arr[j]=1
    交换后,i=0, j=0; arr[i]=1, arr[j]=1
    ---
    递归右侧,right=4, index=3
    pivot=7; left=3; right=4
    交换前,i=3, j=4; arr[i]=7, arr[j]=5
    交换后,i=3, j=4; arr[i]=5, arr[j]=7
    ---
    递归右侧,right=8, index=5
    pivot=7; left=5; right=8
    跳过,j=8; arr[j]=12, pivot=7
    跳过,j=7; arr[j]=26, pivot=7
    交换前,i=5, j=6; arr[i]=14, arr[j]=7
    交换后,i=5, j=6; arr[i]=7, arr[j]=14
    ---
    递归右侧,right=8, index=6
    pivot=26; left=6; right=8
    跳过,i=6; arr[i]=14, pivot=26
    交换前,i=7, j=8; arr[i]=26, arr[j]=12
    交换后,i=7, j=8; arr[i]=12, arr[j]=26
    ---
    递归 左侧,left=6, index=8
    pivot=14; left=6; right=7
    交换前,i=6, j=7; arr[i]=14, arr[j]=12
    交换后,i=6, j=7; arr[i]=12, arr[j]=14
    ---
    快速排序
    1 2 3 5 7 7 12 14 26 
  • 相关阅读:
    Native RabbitMQ Direct Exchange
    RabbitMQ系列文章导读
    AbstractQueuedSynchronizer
    CountDownLatch和CyclicBarrier
    显示锁Lock
    《SeleniumBasic 3.141.0.0
    《SeleniumBasic 3.141.0.0
    《SeleniumBasic 3.141.0.0
    《SeleniumBasic 3.141.0.0
    《SeleniumBasic 3.141.0.0
  • 原文地址:https://www.cnblogs.com/starcrm/p/9681563.html
Copyright © 2020-2023  润新知