• Java与算法之(2)


    快速排序的基本思路是,每次选定数列中的一个基准数,将小于基准数的数字都放到基准数左边,大于基准数的数字都放到基准数右边。然后再分别对基准数左右的两个数列分别重复以上过程。仍以4 3 6 2 7 1 5为例。

    选定最左侧数字4为基准数,首先从右开始向左找小于4的数,找到第一个数1后停止。然后从左开始向右找到第一个大于4的数,即6。

    交换这两个数的位置,得到

    继续寻找,仍然从右边开始,从上一步找到1的位置向左寻找小于4的数,找到2停止。然后从左边找到6的位置向右找大于4的数。右移一格后,和右侧来的“探路者”相遇了,这意味着这一轮排序结束。

    最后把结束位置的数和基准数交换

    观察完成后的数列,可以看到以基准数4为分界线,左边的数全都比4小,右边的数全都比4大。接下来分别对左边的2 3 1和右边的7 6 5重复上面的排序步骤。

    2 3 1

    以2为基准数 -> 2 1 3 -> 1 2 3

    7 6 5

    以7为基准数 -> 5 6 7

    我们例子中的数字较少,如果数列足够长,对第一次排序后得到的子数列排序,将再得到两个子数列,然后再一分为二、二分为四。。。直到以基准数拆分后两边都只剩下一个数字。首先来看递归形式的实现代码

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. public class QuickSort {  
    2.   
    3.     public void sort(int left, int right, int... numbers) {  
    4.         if (left >= right) {  
    5.             return;  
    6.         }  
    7.         int temp = numbers[left];  
    8.         int t = 0;  
    9.         int i = left;  
    10.         int j = right;  
    11.         while (i != j) {  
    12.             // 先从右往左找  
    13.             while (numbers[j] >= temp && i < j)  
    14.                 j--;  
    15.             // 再从左往右找  
    16.             while (numbers[i] <= temp && i < j)  
    17.                 i++;  
    18.             // 交换两个数在数组中的位置  
    19.             if (i < j) {  
    20.                 t = numbers[i];  
    21.                 numbers[i] = numbers[j];  
    22.                 numbers[j] = t;  
    23.             }  
    24.         }  
    25.         // 将基准数归位  
    26.         numbers[left] = numbers[i];  
    27.         numbers[i] = temp;  
    28.   
    29.         sort(left, i - 1, numbers);  
    30.         sort(i + 1, right, numbers);  
    31.     }  
    32. }  

    测试代码

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. public static void main(String[] args) {  
    2.     int[] numbers = new int[] { 4, 3, 6, 2, 7, 1, 5 };  
    3.   
    4.     new QuickSort().sort(0, numbers.length - 1, numbers);  
    5.   
    6.     System.out.print("after: ");  
    7.     for (int i = 0; i < numbers.length; i++) {  
    8.         System.out.print(numbers[i] + "  ");  
    9.     }  
    10.     System.out.println();  
    11. }  

    输出

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. after: 1  2  3  4  5  6  7    

    另一种实现方式是使用栈代替递归

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. public void sortWithoutRecursion(int left, int right, int... numbers) {  
    2.     LinkedList<Integer> stack = new LinkedList<>();  
    3.     int index;  
    4.     stack.push(left);  
    5.     stack.push(right);  
    6.     while (!stack.isEmpty()) {  
    7.         right = stack.pop();  
    8.         left = stack.pop();  
    9.         index = partition(left, right, numbers);  
    10.         if (left < index - 1) {  
    11.             stack.push(left);  
    12.             stack.push(index - 1);  
    13.         }  
    14.         if (right > index + 1) {  
    15.             stack.push(index + 1);  
    16.             stack.push(right);  
    17.         }  
    18.     }  
    19. }  
    20.   
    21. public int partition(int left, int right, int... numbers) {  
    22.     int temp = numbers[left];  
    23.     while (left < right) {  
    24.         while (numbers[right] >= temp && left < right)  
    25.             right--;  
    26.         numbers[left] = numbers[right];  
    27.         while (numbers[left] <= temp && left < right)  
    28.             left++;  
    29.         numbers[right] = numbers[left];  
    30.     }  
    31.     numbers[left] = temp;  
    32.     return left;  
    33. }  
  • 相关阅读:
    关于input()
    HDU 3746
    HDU 4335 Contest 4
    HDU 4418 高斯消元法求概率DP
    HDU 4339 Contest 4
    HDU 4334 Contest 4
    HDU 4333 Contest 4
    HDU 4332 Contest 4
    HDU 4035
    HDU 4336
  • 原文地址:https://www.cnblogs.com/sa-dan/p/6837012.html
Copyright © 2020-2023  润新知