zoukankan      html  css  js  c++  java
  • 算法之快速排序(递归和非递归)

    快速排序的两种实现方式.递归和非递归

      1 package com.ebiz.sort;
      2 
      3 import java.text.SimpleDateFormat;
      4 import java.util.Arrays;
      5 import java.util.Date;
      6 import java.util.Stack;
      7 
      8 /**
      9  * @author YHj
     10  * @create 2019-08-18 17:42
     11  */
     12 public class Quick {
     13 
     14     public static void main(String[] args) {
     15         int[] arr = new int[8];
     16         for (int i = 0; i < 8; i++) {
     17             arr[i] = (int) (Math.random() * 800000);
     18         }
     19 
     20         String s = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
     21         System.out.println("排序前 = " + s);
     22 
     23         quickSort(arr,0,arr.length-1);
     24 
     25 
     26         String l = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
     27         System.out.println("排序后 = " + l);
     28     }
     29 
     30     /**
     31      * 快速排序(递归)
     32      * <p>
     33      * ①. 从数列中挑出一个元素,称为"基准"(pivot)。
     34      * ②. 重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
     35      * ③. 递归地(recursively)把小于基准值元素的子数列和大于基准值元素的子数列排序。
     36      *
     37      * @param arr  待排序数组
     38      * @param low  左边界
     39      * @param high 右边界
     40      */
     41     public static void quickSort(int[] arr, int low, int high) {
     42         if (arr.length <= 0){
     43             return;
     44         }
     45         if (low >= high) {
     46             return;
     47         }
     48         int left = low;
     49         int right = high;
     50 
     51         int temp = arr[left];   //挖坑1:保存基准的值
     52         while (left < right) {
     53             while (left < right && arr[right] >= temp) {  //坑2:从后向前找到比基准小的元素,插入到基准位置坑1中
     54                 right--;
     55             }
     56             arr[left] = arr[right];
     57             while (left < right && arr[left] <= temp) {   //坑3:从前往后找到比基准大的元素,放到刚才挖的坑2中
     58                 left++;
     59             }
     60             arr[right] = arr[left];
     61         }
     62         arr[left] = temp;   //基准值填补到坑3中,准备分治递归快排
     63         System.out.println("Sorting: " + Arrays.toString(arr));
     64         quickSort(arr, low, left - 1);
     65         quickSort(arr, left + 1, high);
     66     }
     67     /**
     68      * 快速排序(非递归)
     69      *
     70      * ①. 从数列中挑出一个元素,称为"基准"(pivot)。
     71      * ②. 重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
     72      * ③. 把分区之后两个区间的边界(low和high)压入栈保存,并循环①、②步骤
     73      * @param arr   待排序数组
     74      */
     75     public static void quickSortByStack(int[] arr){
     76         if(arr.length <= 0){
     77             return;
     78         }
     79         Stack<Integer> stack = new Stack<Integer>();
     80 
     81         //初始状态的左右指针入栈
     82         stack.push(0);
     83         stack.push(arr.length - 1);
     84         while(!stack.isEmpty()){
     85             int high = stack.pop();     //出栈进行划分
     86             int low = stack.pop();
     87 
     88             int pivotIdx = partition(arr, low, high);
     89 
     90             //保存中间变量
     91             if(pivotIdx > low) {
     92                 stack.push(low);
     93                 stack.push(pivotIdx - 1);
     94             }
     95             if(pivotIdx < high && pivotIdx >= 0){
     96                 stack.push(pivotIdx + 1);
     97                 stack.push(high);
     98             }
     99         }
    100     }
    101 
    102     private static int partition(int[] arr, int low, int high){
    103         if(arr.length <= 0) {
    104             return -1;
    105         }
    106         if(low >= high) {
    107             return -1;
    108         }
    109         int l = low;
    110         int r = high;
    111 
    112         int pivot = arr[l];    //挖坑1:保存基准的值
    113         while(l < r){
    114             while(l < r && arr[r] >= pivot){  //坑2:从后向前找到比基准小的元素,插入到基准位置坑1中
    115                 r--;
    116             }
    117             arr[l] = arr[r];
    118             while(l < r && arr[l] <= pivot){   //坑3:从前往后找到比基准大的元素,放到刚才挖的坑2中
    119                 l++;
    120             }
    121             arr[r] = arr[l];
    122         }
    123         arr[l] = pivot;   //基准值填补到坑3中,准备分治递归快排
    124         return l;
    125     }
    126 
    127 
    128 }
  • 相关阅读:
    寒假学习进度七
    寒假学习进度六
    寒假学习进度五
    mysql 数据库第一天
    HTML 标签&总结
    事件对象
    js的事件流的概念
    jquery 的位置信息
    小米导航 案例
    jquery 的文档操作
  • 原文地址:https://www.cnblogs.com/jiushixihuandaqingtian/p/11449371.html
Copyright © 2011-2022 走看看