zoukankan      html  css  js  c++  java
  • 快速排序java实现

    快速排序是基于分治策略的一个排序算法。其基本思想是,对于输入的字数组a[p:r]

    按以下3个步骤进行排序:

    1、分解(divide):以a[p]为基准元素将a[p:r]划分成3a[p:q-1]a[q]a[q+1:r],使得a[p:q-1]中任何元素小于等于a[q]a[q+1:r]中任何元素大于等于a[q]。下标q在划分过程中确定。

    2、递归求解(conquer):通过递归调用快速排序算法,分别对a[p:q-1]a[q+1:r]进行排序。

    3、合并(merge):由于对a[p:q-1]a[q+1:r]的排序是就地进行的,所以在a[p:q-1]a[q+1:r]都已经排好序后不需要执行任何计算,a[p:r]就已经排好序。(其实就是对数组进行分解之后,a[q]就是最终数组的a[q],也就是说每一次分解都会确定有序数组中的一个元素,一直递归直至最后只剩一个元素就不需要再分解,这个元素就是最终结果)。

     1 public class QuickSort {
     2     
     3     public static int a[]= {1,4,3,8,6,0,2,5};
     4     
     5     public static void qSort(int p,int r){
     6         if(p<r){
     7             int q = partition(p,r);        //a[q]是最后排序的结果
     8             qSort(p,q-1);  //对左半段排序
     9             qSort(q+1,r);  //对右半段排序
    10         }
    11     }
    12     
    13     private static int partition(int p, int r) {
    14         int i=p,
    15                 j=r+1;
    16         int x=a[p];
    17         //将小于x的元素交换到左边区域
    18         //将大于x的元素交换到右边区域
    19         while(true){
    20             while(a[++i]<x&&i<r) ; //++i,所以是对[p+1,r]排序,最后要将p插进来
    21             while(a[--j]>x) ;
    22             if(i>=j) break;
    23             swap(a,i,j);
    24         }
    25         /*
    26          * a[j]之所以和a[p]交换,而不是和a[i]交换,是因为上面的循环结束后,a[j]<=a[p]<=a[i]
    27          * 而p是第一个元素(即是分组后的左半部分(小于等于p的部分))
    28          */
    29         a[p]=a[j]; 
    30         a[j]=x;
    31         return j;
    32     }
    33 
    34     private static void swap(int[] a, int i, int j) {
    35         int temp=a[i];
    36         a[i] = a[j];
    37         a[j] = temp;
    38     }
    39 
    40     public static void main(String[] args) {
    41         qSort(0,a.length-1);
    42         for(int i=0;i<a.length;i++)
    43             System.out.print(a[i]+" ");
    44     }
    45 
    46 }

    其实之前一直不明白partition最后为什么要将a[j]与a[p]的值交换,后来才想明白,因为partition是以a[p]为基准分两组的,

    最后的结果中左半部分小于等于a[p],右半部分大于等于a[p],

    也就是说,最后的有序数组中,a[p]是位于左右半部分中间的,所以将a[p]插入到他们中间,

    之所以选择j而不是i的原因是:while(true)循环之后,a[j]<=a[p]<=a[i],而a[p]是整个数组的第一个元素(左半部分),

    所以交换后仍然能保证左半部分比a[p]小,右半部分比a[p]大。

  • 相关阅读:
    c语言7-4
    c语言 7-4
    dfs
    dfs
    二进制搜索
    BFS
    搜索多层图
    八皇后
    线段树-周长并
    线段树
  • 原文地址:https://www.cnblogs.com/eleven24/p/4243850.html
Copyright © 2011-2022 走看看