[Java] java快速排序算法 →→→→→进入此内容的聊天室

来自 , 2021-01-05, 写在 Java, 查看 109 次.
URL http://www.code666.cn/view/ef575e88
  1. /**
  2.  * 快速排序
  3.  *
  4.  * 在当前无序区R[1..H]中任取一个数据元素作为比较的"基准"(不妨记为X),用此基准将当前无序区划分为左右两个较小的无序区:
  5.  * R[1..I-1]和R[I+1..H],且左边的无序子区中数据元素均小于等于基准元素,右边的无序子区中数据元素均大于等于基准元素,
  6.  * 而基准X则位于最终排序的位置上,即R[1..I-1]≤ X.Key≤R[I+1..H](1≤I≤H),当R[1..I-1]和R[I+1..H]均非空时,
  7.  * 分别对它们进行上述的划分过程,直至所有无序子区中的数据元素均已排序为止。
  8.  */
  9.  
  10. public class QuickSort {
  11.  
  12.         /**
  13.          * 排序算法的实现,对数组中指定的元素进行排序
  14.          *
  15.          * @param array
  16.          *            待排序的数组
  17.          * @param from
  18.          *            从哪里开始排序
  19.          * @param end
  20.          *            排到哪里
  21.          * @param c
  22.          *            比较器
  23.          */
  24.         // 定义了一个这样的公有方法sort,在这个方法体里面执行私有方法quckSort(这种方式值得借鉴)。
  25.         public void sort(Integer[] array, int from, int end) {
  26.                 quickSort(array, from, end);
  27.         }
  28.  
  29.         /**
  30.          * 递归快速排序实现
  31.          *
  32.          * @param array
  33.          *            待排序数组
  34.          * @param low
  35.          *            低指针
  36.          * @param high
  37.          *            高指针
  38.          * @param c
  39.          *            比较器
  40.          */
  41.         private void quickSort(Integer[] array, int low, int high) {
  42.                 /*
  43.                  * 如果分区中的低指针小于高指针时循环;如果low=higth说明数组只有一个元素,无需再处理; 如果low >
  44.                  * higth,则说明上次枢纽元素的位置pivot就是low或者是higth,此种情况 下分区不存,也不需处理
  45.                  */
  46.                 if (low < high) {
  47.                         // 对分区进行排序整理
  48.  
  49.                         // int pivot = partition1(array, low, high);
  50.                         int pivot = partition2(array, low, high);
  51.                         // int pivot = partition3(array, low, high);
  52.  
  53.                         /*
  54.                          * 以pivot为边界,把数组分成三部分[low, pivot - 1]、[pivot]、[pivot + 1, high]
  55.                          * 其中[pivot]为枢纽元素,不需处理,再对[low, pivot - 1]与[pivot + 1, high]
  56.                          * 各自进行分区排序整理与进一步分区
  57.                          */
  58.                         quickSort(array, low, pivot - 1);
  59.                         quickSort(array, pivot + 1, high);
  60.                 }
  61.  
  62.         }
  63.  
  64.         /**
  65.          * 实现一
  66.          *
  67.          * @param array
  68.          *            待排序数组
  69.          * @param low
  70.          *            低指针
  71.          * @param high
  72.          *            高指针
  73.          * @param c
  74.          *            比较器
  75.          * @return int 调整后中枢位置
  76.          */
  77.         private int partition1(Integer[] array, int low, int high) {
  78.                 Integer pivotElem = array[low];// 以第一个元素为中枢元素
  79.                 // 从前向后依次指向比中枢元素小的元素,刚开始时指向中枢,也是小于与大小中枢的元素的分界点
  80.                 int border = low;
  81.  
  82.                 /*
  83.                  * 在中枢元素后面的元素中查找小于中枢元素的所有元素,并依次从第二个位置从前往后存放
  84.                  * 注,这里最好使用i来移动,如果直接移动low的话,最后不知道数组的边界了,但后面需要 知道数组的边界
  85.                  */
  86.                 for (int i = low + 1; i <= high; i++) {
  87.                         // 如果找到一个比中枢元素小的元素
  88.                         if ((array[i].compareTo(pivotElem)) < 0) {
  89.                                 swap(array, ++border, i);// border前移,表示有小于中枢元素的元素
  90.                         }
  91.                 }
  92.                 /*
  93.                  * 如果border没有移动时说明说明后面的元素都比中枢元素要大,border与low相等,此时是
  94.                  * 同一位置交换,是否交换都没关系;当border移到了high时说明所有元素都小于中枢元素,此
  95.                  * 时将中枢元素与最后一个元素交换即可,即low与high进行交换,大的中枢元素移到了 序列最 后;如果 low <minIndex<
  96.                  * high,表 明中枢后面的元素前部分小于中枢元素,而后部分大于
  97.                  * 中枢元素,此时中枢元素与前部分数组中最后一个小于它的元素交换位置,使得中枢元素放置在 正确的位置
  98.                  */
  99.                 swap(array, border, low);
  100.                 return border;
  101.         }
  102.  
  103.         /**
  104.          * 实现二
  105.          *
  106.          * @param array
  107.          *            待排序数组
  108.          * @param low
  109.          *            待排序区低指针
  110.          * @param high
  111.          *            待排序区高指针
  112.          * @param c
  113.          *            比较器
  114.          * @return int 调整后中枢位置
  115.          */
  116.         private int partition2(Integer[] array, int low, int high) {
  117.                 int pivot = low;// 中枢元素位置,我们以第一个元素为中枢元素
  118.                 // 退出条件这里只可能是 low = high
  119.                 while (true) {
  120.                         if (pivot != high) {// 如果中枢元素在低指针位置时,我们移动高指针
  121.                                 // 如果高指针元素小于中枢元素时,则与中枢元素交换
  122.                                 if ((array[high].compareTo(array[pivot])) < 0) {
  123.                                         swap(array, high, pivot);
  124.                                         // 交换后中枢元素在高指针位置了
  125.                                         pivot = high;
  126.                                 } else {// 如果未找到小于中枢元素,则高指针前移继续找
  127.                                         high--;
  128.                                 }
  129.                         } else {// 否则中枢元素在高指针位置
  130.                                 // 如果低指针元素大于中枢元素时,则与中枢元素交换
  131.                                 if ((array[low].compareTo(array[pivot])) > 0) {
  132.                                         swap(array, low, pivot);
  133.                                         // 交换后中枢元素在低指针位置了
  134.                                         pivot = low;
  135.                                 } else {// 如果未找到大于中枢元素,则低指针后移继续找
  136.                                         low++;
  137.                                 }
  138.                         }
  139.                         if (low == high) {
  140.                                 break;
  141.                         }
  142.                 }
  143.                 // 返回中枢元素所在位置,以便下次分区
  144.                 return pivot;
  145.         }
  146.  
  147.         /**
  148.          * 实现三
  149.          *
  150.          * @param array
  151.          *            待排序数组
  152.          * @param low
  153.          *            待排序区低指针
  154.          * @param high
  155.          *            待排序区高指针
  156.          * @param c
  157.          *            比较器
  158.          * @return int 调整后中枢位置
  159.          */
  160.         private int partition3(Integer[] array, int low, int high) {
  161.                 int pivot = low;// 中枢元素位置,我们以第一个元素为中枢元素
  162.                 low++;
  163.                 // ----调整高低指针所指向的元素顺序,把小于中枢元素的移到前部分,大于中枢元素的移到后面部分
  164.                 // 退出条件这里只可能是 low = high
  165.  
  166.                 while (true) {
  167.                         // 如果高指针未超出低指针
  168.                         while (low < high) {
  169.                                 // 如果低指针指向的元素大于或等于中枢元素时表示找到了,退出,注:等于时也要后移
  170.                                 if ((array[low].compareTo(array[pivot])) >= 0) {
  171.                                         break;
  172.                                 } else {// 如果低指针指向的元素小于中枢元素时继续找
  173.                                         low++;
  174.                                 }
  175.                         }
  176.  
  177.                         while (high > low) {
  178.                                 // 如果高指针指向的元素小于中枢元素时表示找到,退出
  179.                                 if ((array[high].compareTo(array[pivot])) < 0) {
  180.                                         break;
  181.                                 } else {// 如果高指针指向的元素大于中枢元素时继续找
  182.                                         high--;
  183.                                 }
  184.                         }
  185.                         // 退出上面循环时 low = high
  186.                         if (low == high) {
  187.                                 break;
  188.                         }
  189.  
  190.                         swap(array, low, high);
  191.                 }
  192.  
  193.                 // ----高低指针所指向的元素排序完成后,还得要把中枢元素放到适当的位置
  194.                 if ((array[pivot].compareTo(array[low])) > 0) {
  195.                         // 如果退出循环时中枢元素大于了低指针或高指针元素时,中枢元素需与low元素交换
  196.                         swap(array, low, pivot);
  197.                         pivot = low;
  198.                 } else if ((array[pivot].compareTo(array[low])) <= 0) {
  199.                         swap(array, low - 1, pivot);
  200.                         pivot = low - 1;
  201.                 }
  202.  
  203.                 // 返回中枢元素所在位置,以便下次分区
  204.                 return pivot;
  205.         }
  206.  
  207.         /**
  208.          * 交换数组中的两个元素的位置
  209.          *
  210.          * @param array
  211.          *            待交换的数组
  212.          * @param i
  213.          *            第一个元素
  214.          * @param j
  215.          *            第二个元素
  216.          */
  217.         public void swap(Integer[] array, int i, int j) {
  218.                 if (i != j) {// 只有不是同一位置时才需交换
  219.                         Integer tmp = array[i];
  220.                         array[i] = array[j];
  221.                         array[j] = tmp;
  222.                 }
  223.         }
  224.  
  225.         /**
  226.          * 测试
  227.          *
  228.          * @param args
  229.          */
  230.         public static void main(String[] args) {
  231.                 Integer[] intgArr = { 5, 9, 1, 4, 2, 6, 3, 8, 0, 7 };
  232.                 QuickSort quicksort = new QuickSort();
  233.                 quicksort.sort(intgArr, 0, intgArr.length - 1);
  234.                 for (Integer intObj : intgArr) {
  235.                         System.out.print(intObj + " ");
  236.                 }
  237.         }
  238. }
  239.  

回复 "java快速排序算法"

这儿你可以回复上面这条便签

captcha