zoukankan      html  css  js  c++  java
  • 算法

    要点:分而治之,选取基准数,建立左右两个游标,两侧游标向基准数靠拢,交换元素,使左侧元素小于/大于基准数,右侧大于/小于基准数。并对左右部分进行递归。

      1 import java.util.Random;
      2 
      3 public class QuickSort<T extends Comparable> {
      4 
      5     public void sort(T[] arr, int left, int right) {
      6         if (left < right) {
      7             int originLeft = left;
      8             int originRight = right;
      9             // 基准数
     10             int index = new Random().nextInt(right - left) + left;
     11             T base = arr[index];
     12             System.out.println("基准数:" + base + ",区间:");
     13             for (int i = 0; i < 11; i++) {
     14                 if (i >= left && i <= right) {
     15                     System.out.print("*");
     16                     continue;
     17                 }
     18                 System.out.print(" ");
     19             }
     20             System.out.println();
     21             // 相等就不交换,否则会不稳定
     22             if (arr[index] != arr[left]) {
     23                 arr[index] = arr[left];
     24                 arr[left] = base;
     25             }
     26             while (left < right) {
     27                 while (arr[right].compareTo(base) >= 0 && left < right) {
     28                     printArr(arr, " => 右标移动");
     29                     right--;
     30                     printSign(right, "右标 ←");
     31                 }
     32                 if (left < right) {
     33                     printArr(arr, " => 发生赋值");
     34                     printSign(left, "左标位置");
     35                     printSign(right, "右标位置");
     36                     arr[left] = arr[right];
     37                     printArr(arr, " => 右赋值给左");
     38                     left++;
     39                     printSign(left, "左标 →");
     40                 }
     41                 while (arr[left].compareTo(base) < 0 && left < right) {
     42                     printArr(arr, " => 左标移动");
     43                     left++;
     44                     printSign(left, "左标 →");
     45                 }
     46                 if (left < right) {
     47                     printArr(arr, " => 发生赋值");
     48                     printSign(left, "左标位置");
     49                     printSign(right, "右标位置");
     50                     arr[right] = arr[left];
     51                     printArr(arr, " => 左赋值给右");
     52                     right--;
     53                     printSign(right, "右标 ←");
     54                 }
     55             }
     56             arr[left] = base;
     57             printArr(arr, " => 基准数交换");
     58             System.out.println("- - - - - - - - - - - - - - - - - - - - ");
     59             sort(arr, originLeft, left - 1);
     60             sort(arr, left + 1, originRight);
     61         }
     62     }
     63 
     64     private void printArr(T[] arr, String message) {
     65         for (T n : arr) {
     66             System.out.print(n);
     67         }
     68         System.out.print(message);
     69         System.out.println();
     70     }
     71 
     72     private void printSign(int index, String message) {
     73         String[] arr = new String[]{" ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "};
     74         arr[index] = "^";
     75         for (String s : arr) {
     76             System.out.print(s);
     77         }
     78         System.out.print(" => " + message);
     79         System.out.println();
     80     }
     81 
     82     public static void main(String[] args) {
     83         Integer[] arr = new Integer[]{1, 3, 8, 7, 6, 9, 5, 4, 3, 2, 0};
     84         QuickSort as = new QuickSort();
     85         as.sort(arr, 0, arr.length - 1);
     86     }
     87 
     88     /**
     89      * 基准数:5,区间:
     90      * ***********
     91      * 53876914320 => 发生赋值
     92      * ^           => 左标位置
     93      *           ^ => 右标位置
     94      * 03876914320 => 右赋值给左
     95      *  ^          => 左标 →
     96      * 03876914320 => 左标移动
     97      *   ^         => 左标 →
     98      * 03876914320 => 发生赋值
     99      *   ^         => 左标位置
    100      *           ^ => 右标位置
    101      * 03876914328 => 左赋值给右
    102      *          ^  => 右标 ←
    103      * 03876914328 => 发生赋值
    104      *   ^         => 左标位置
    105      *          ^  => 右标位置
    106      * 03276914328 => 右赋值给左
    107      *    ^        => 左标 →
    108      * 03276914328 => 发生赋值
    109      *    ^        => 左标位置
    110      *          ^  => 右标位置
    111      * 03276914378 => 左赋值给右
    112      *         ^   => 右标 ←
    113      * 03276914378 => 发生赋值 => 顺序未改变,稳定
    114      *    ^        => 左标位置
    115      *         ^   => 右标位置
    116      * 03236914378 => 右赋值给左
    117      *     ^       => 左标 →
    118      * 03236914378 => 发生赋值
    119      *     ^       => 左标位置
    120      *         ^   => 右标位置
    121      * 03236914678 => 左赋值给右
    122      *        ^    => 右标 ←
    123      * 03236914678 => 发生赋值
    124      *     ^       => 左标位置
    125      *        ^    => 右标位置
    126      * 03234914678 => 右赋值给左
    127      *      ^      => 左标 →
    128      * 03234914678 => 发生赋值
    129      *      ^      => 左标位置
    130      *        ^    => 右标位置
    131      * 03234919678 => 左赋值给右
    132      *       ^     => 右标 ←
    133      * 03234919678 => 发生赋值
    134      *      ^      => 左标位置
    135      *       ^     => 右标位置
    136      * 03234119678 => 右赋值给左
    137      *       ^     => 左标 →
    138      * 03234159678 => 基准数交换
    139      * - - - - - - - - - - - - - - - - - - - -
    140      * 基准数:4,区间:
    141      * ******
    142      * 43230159678 => 发生赋值
    143      * ^           => 左标位置
    144      *      ^      => 右标位置
    145      * 13230159678 => 右赋值给左
    146      *  ^          => 左标 →
    147      * 13230159678 => 左标移动
    148      *   ^         => 左标 →
    149      * 13230159678 => 左标移动
    150      *    ^        => 左标 →
    151      * 13230159678 => 左标移动
    152      *     ^       => 左标 →
    153      * 13230159678 => 左标移动
    154      *      ^      => 左标 →
    155      * 13230459678 => 基准数交换 => 顺序未改变,稳定
    156      * - - - - - - - - - - - - - - - - - - - -
    157      * 基准数:3,区间:
    158      * *****
    159      * 33210459678 => 发生赋值
    160      * ^           => 左标位置
    161      *     ^       => 右标位置
    162      * 03210459678 => 右赋值给左
    163      *  ^          => 左标 →
    164      * 03210459678 => 发生赋值
    165      *  ^          => 左标位置
    166      *     ^       => 右标位置
    167      * 03213459678 => 左赋值给右
    168      *    ^        => 右标 ←
    169      * 03213459678 => 发生赋值
    170      *  ^          => 左标位置
    171      *    ^        => 右标位置
    172      * 01213459678 => 右赋值给左
    173      *   ^         => 左标 →
    174      * 01213459678 => 左标移动
    175      *    ^        => 左标 →
    176      * 01233459678 => 基准数交换 => 顺序未改变,稳定
    177      * - - - - - - - - - - - - - - - - - - - -
    178      * 基准数:1,区间:
    179      * ***
    180      * 10233459678 => 右标移动
    181      *  ^          => 右标 ←
    182      * 10233459678 => 发生赋值
    183      * ^           => 左标位置
    184      *  ^          => 右标位置
    185      * 00233459678 => 右赋值给左
    186      *  ^          => 左标 →
    187      * 01233459678 => 基准数交换
    188      * - - - - - - - - - - - - - - - - - - - -
    189      * 基准数:9,区间:
    190      *        ****
    191      * 01233459678 => 发生赋值
    192      *        ^    => 左标位置
    193      *           ^ => 右标位置
    194      * 01233458678 => 右赋值给左
    195      *         ^   => 左标 →
    196      * 01233458678 => 左标移动
    197      *          ^  => 左标 →
    198      * 01233458678 => 左标移动
    199      *           ^ => 左标 →
    200      * 01233458679 => 基准数交换
    201      * - - - - - - - - - - - - - - - - - - - -
    202      * 基准数:6,区间:
    203      *        ***
    204      * 01233456879 => 右标移动
    205      *         ^   => 右标 ←
    206      * 01233456879 => 右标移动
    207      *        ^    => 右标 ←
    208      * 01233456879 => 基准数交换
    209      * - - - - - - - - - - - - - - - - - - - -
    210      * 基准数:8,区间:
    211      *         **
    212      * 01233456879 => 发生赋值
    213      *         ^   => 左标位置
    214      *          ^  => 右标位置
    215      * 01233456779 => 右赋值给左
    216      *          ^  => 左标 →
    217      * 01233456789 => 基准数交换
    218      * - - - - - - - - - - - - - - - - - - - -
    219      *
    220      * 分治法,递归
    221      * => 遍历次数:与基准数选择和数据分布有关
    222      * => 时间复杂度:O(nlogn)
    223      * => 稳定性:稳定
    224      *
    225      */
    226 
    227 }
  • 相关阅读:
    Python Ethical Hacking
    Python Ethical Hacking
    Python Ethical Hacking
    Python Ethical Hacking
    Python Ethical Hacking
    Python Ethical Hacking
    Python Ethical Hacking
    Arctic Network POJ
    Truck History POJ
    QS Network ZOJ
  • 原文地址:https://www.cnblogs.com/SamNicole1809/p/12793745.html
Copyright © 2011-2022 走看看