快速排序

 1 public class Quicksort {
 2 
 3     static int arr[] = { 5, 7, 3, 9, 2, 8, 3, 9, 4, 10 };
 4 
 5     static int maxIndex = arr.length - 1;
 6 
 7     /**
 8      * 值交换
 9      * 
10      * @param x
11      * @param y
12      */
13     private void swap(int x, int y) {
14         int temp = arr[x];
15         arr[x] = arr[y];
16         arr[y] = temp;
17     }
18 
19     /**
20      * 快速排序算法:
21      * 1、挑选出最后一位最为基数;
22      * 2、从左至右依次对基数对比,如果arr[left]大于改值,则推出本次循环;
23      * 3、从右至左依次对基础对比,如果arr[right]小于该值,则退出本次循环;
24      * 4、将left和right交换位置;
25      * 5、比对left是否大于等于right or left小于right; 
26      * 
27      * @author 程序员
28      * @param start 数据起始位置
29      * @param end 数据maxIndex位置
30      * @return void
31      */
32     private void quickSortRecursive(int start, int end) {
33         if (start >= end)  //如果提交的开始位置和结束位一致,则退出递归.
34             return;
35         int mid = arr[end]; //挑选出数据最后一位最为基数;
36         int left = start, right = end - 1;//左从第一位  右需要剔除最后一位(被选中为基数)
37         while (left < right) {  //比对left是否大于等于right or left小于right;
38             while (arr[left] < mid && left < right) //从左至右依次对基数对比,如果arr[left]大于基数,则推出本次循环; 需要避免左起比对,一直比对到最后一位仍然没有大于基数
39                 left++; //如果arr[left]小于基数,则循环一次+1 再比
40             while (arr[right] >= mid && left < right) //从右至左依次对基础对比,如果arr[right]小于基数,则退出本次循环;
41                 right--; ////如果arr[left]大于基数,则循环一次-1 再比
42             swap(left, right);
43         }
44         //如果左右依次对比下标值大于基数,则交换位置(避免选出的值正好是数据中最大的.)
45         if (arr[left] >= arr[end])
46             swap(left, end);
47         else //否则left+1
48             left++;
49 
50         quickSortRecursive(start, left - 1); //选出基数,对基数左边数据分治
51         quickSortRecursive(left + 1, end);//选出基数,对基数右边数据分治
52     }
53 
54     public static void main(String[] args) {
55         new Quicksort().quickSortRecursive(0, maxIndex);
56 
57         for (int value : arr) {
58             System.out.print(value + ",");
59         }
60     }

 

1、需要递归知道数组排序完成,所以,首先加入数组首位和末尾如果是同一位置,退出;

2、选择数组最后一位值哨兵,将除了哨兵外的数组开始比对;

3、循环,如果左起查找index小于右起查找index,说明本次哨兵位置还没有找到,则继续循环,

4、从左开始比对,如果值小于哨兵,则+1继续,直至最后一位(即:从左查找的index不得大于从右查找的index),或值大于哨兵止;

5、从右向左比对,如果值大于哨兵,则-1继续,直至首位,(即:从右查找inedx不得小于从左查找的index),或值小于哨兵止;

6、重复第4、5步骤,直至不满足3步骤条件;

7、比对左起查找index(或右起查找index,此时左起index = 右起index)值,是否小于哨兵,有可能选择的哨兵是本数组中最大的,如果小于哨兵,则左起+1(+1是选择最后一位为哨兵,此时数据也分为2部分,只 是比较畸形,左边为数组除哨兵外的全部数据,右边没有数据),如果大于哨兵则交换位置;

8、递归分别继续拆分数组 起始位至哨兵位-1 和 哨兵位+1至数据最后一位 直至结束;

posted @ 2016-04-10 19:17  刘诏  阅读(215)  评论(0编辑  收藏  举报