排序算法之快速排序

  快速排序算法是一个运算性能比较好的算法。其原理如下:

  在一组给定的数据中,选取一个值作为分界点,将其他比该分界点值小的数据放在分界点左侧,比分界点值大的数据放在分界点右侧,然后递归处理左右两侧的数据,直至所有的数据有序为止。

  具体算法如下:

  首先假设有一组数据:23  45  12  78  31  8  21  56  123  66

  其下标值为:            1   2    3    4    5   6    7    8     9  10 

  我们在这里每次都取数据中第一个数据作为分界点(但是这种选取方法有不足之处,如果数据基本有序,则耗费时间较多,即每次第一个数据自成一个分组,其余数据为另一个分组)。然后从第二个数据向右遍历,直至找到一个大于分界点的数据为止,记录下该位置,然后从最后一个数据向左遍历,直至找到一个小于分界点的数据为止,记录下该位置,然后比较这两个数据的下标值,如果从左遍历的下标值小于从右遍历的下标值,则交换这两个数据,并继续从刚才记录的位置继续寻找符合要求的数据,否则(即从左遍历的下标值大于从右遍历的下标值),则将从右遍历的那个下标值与分界点进行交换。此时分界点左侧的数据全部小于分界点,分界点右侧的数据全部大于分界点,然后将分界点左右两侧的数据分别看成一组数据,递归使用此方法,即可完成排序。

  说的比较繁琐,看下面的例子就明白了:

  设分界点的下标为k,分界点右侧第一个数据下标为i,最后一个数据下标为j。

  初始数据及下标情况如下:

  23  45  12  78  31  8  21  56  123  66

  k      i                                            j

  从 i 开始向右遍历,找到一个45大于23,然后从 j 开始向左遍历,66大于23,不符合,继续向左遍历,直到找到一个21小于23符合

  23  45  12  78  31  8  21  56  123  66

  k      i                         j

  比较i,j的位置,i在j的左侧,即i小于j,则交换i,j位置的数据,如下所示:

  23  21  12  78  31  8  45  56  123  66

  k      i                         j

  然后继续移动i,j的位置,找到符合条件的数据,并交换位置

  23  21  12  78  31    8  45  56  123  66

  k                 i           j

  23  21  12   8   31  78  45  56  123  66

  k                 i           j

  然后继续移动

  23  21  12    8  31  78  45  56  123  66

  k                 j     i

  此时j在i的左侧了,即j小于i了,则将分界点即k位置的数据与j交换  

  [ 8  21  12  ]  23 [ 31  78  45  56  123  66]

   k                   j     i

  至此第一趟排序已经完成,我们可以看到在分界点23左侧的数据已经全部小于23,右侧的数据已经全部大于23,然后再递归处理23左右两侧的数据,在这里我就不多解释了。

  Java代码如下:

import java.util.Random;

public class QuickSort {
    public static void  getQuickSort(int[] arr ,int L,int R) {
        if(L<R) {//递归结束标志
            int mid = L;//k
            int left = L+1;//i
            int right = R;//j
            while(true) {
                while(left<arr.length&&arr[left]<arr[mid]) {//向右遍历
                    left++;
                }
                while(right>0&&arr[right]>arr[mid]) {//向左遍历
                    right--;
                }
                if(left>right) {//i>j跳出循环
                    break;
                }
                swap(arr,left,right);//交换i、j数据的位置
                left++;
                right--;
            }
            swap(arr,mid,right);//交换分界点和j的位置
            getQuickSort(arr,L,right-1);//递归调用
            getQuickSort(arr,right+1,R);
        }
    }
    public static void swap(int[] arr,int left,int right){//交换数据
        int temp;
        temp = arr[left];
        arr[left] = arr[right];
        arr[right] = temp;
    }
    public static void main(String[] args) {
        int[] array = new int[10];
        //int[] array = {23,45,12,78,31,8,21,56,123,66};
        Random ran = new Random();
        for(int i = 0;i<array.length;i++) {
            array[i] = ran.nextInt(100);
        }
        System.out.println("未排序的数据如下所示:");
        for(int j = 0;j<array.length;j++) {
            System.out.print(array[j]+" ");
        }
        getQuickSort(array,0,array.length-1);
        System.out.println("已排序的数据如下所示:");
        for(int j = 0;j<array.length;j++) {
            System.out.print(array[j]+" ");
        }
    }
}

 

posted @ 2017-08-22 14:21  哈密瓜小王子  阅读(286)  评论(0编辑  收藏  举报