【算法导论-010】快速排序(quickSort)

1、算法思想
《算法导论》170页第7章QuickSort,不再赘述。
2、java实现
参考:《算法导论》171页伪码,注意,这里的 partition( int [] array,  int  start,  int  end)函数不是原始版本
public class QuickSortTest {
 
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO 自动生成的方法存根
        int[] array = { 2, 2, -20, 2, 100, -1, 1, 0, 3 };
        quickSort(array, 0, array.length - 1);
 
        for (int i : array) {
            System.out.println(i);
        }
 
    }
 
    public static void quickSort(int[] array, int start, int end) {
        if (start < end) {
            int middle = partition(array, start, end);
            quickSort(array, start, middle - 1);
            quickSort(array, middle + 1, end);
        }
    }
 
    /*
     * 以最后一个元素值为pivot元素,从前往后移动i和j两个指针,i后j前,如果当前元素大于pivot元素,i不动,j递增1;如果当前元素小于pivot元素
     * ,i增1,交换array[i](大于pivot元素)和array[j](小于pivot元素); 移动完毕后将array[i +
     * 1]与array[end]交换,即保证了i+1左侧元素都小于array[i + 1],右侧都大于array[i + 1]
     */
    public static int partition(int[] array, int start, int end) {
        int privotElement = array[end];
        int i = start - 1;
        for (int j = start; j <= end - 1; j++) {
            if (array[j] <= privotElement) {
                i++;
          /*如果i、j指向同一个元素或者指向不同元素但是元素值相同,不用交换(在算法导论171页中的伪码中多一层判断)*/

                if (i != j && array[i] != array[j]) {
                    array[i] ^= array[j];
                    array[j] ^= array[i];
                    array[i] ^= array[j];
                }
            }
 
        }
        /*交换基准元素与array[i + 1]*/
        if (array[i + 1] != array[end]) {
            array[i + 1] ^= array[end];
            array[end] ^= array[i + 1];
            array[i + 1] ^= array[end];
        }
        return i + 1;
    }
 
}
3、 快速排序的随机化版
   参考:《 算法导论》179页伪码
/*随机选取pivot元素*/
    public static int randomizedPartition(int[] array, int start, int end) {
        int randomNumber=new Random().nextInt(end-start)+start;
        if (array[randomNumber]!=array[end]) {
            array[randomNumber]^=array[end];
            array[end]^=array[randomNumber];
            array[randomNumber]^=array[end];
        }
        return partition(array, start, end);
    }
***********************************************************************************************************
仅仅修改:
public static void quickSort(int[] array, int start, int end) {
        if (start < end) {
//          int middle = partition(array, start, end);
           <span style="color:#009900;"><strong> int middle=randomizedPartition(array, start, end);</strong></span>
            quickSort(array, start, middle - 1);
            quickSort(array, middle + 1, end);
        }
    }
4、 partition( int [] array,  int  start,  int  end)原始版本

 思路:《算法导论》185页 

 /*原始的partition过程*/
    public static int  originalPartition(int[] array, int start, int end) {
        int privotElement = array[start];
        while (start<end) {
            /*end--之后可能导致start>end*/
            while (start<end&&array[end]>=privotElement) {
            end--;
            }
            array[start]=array[end];
            /*end--之后可能导致start>end,start++之后也可能导致start>end*/
            while (start<end&&array[start]<=privotElement) {
            start++;
            }
            array[end]=array[start];
           
        }
        array[start]=privotElement;
        return start;
    }
5、非递归版本的快速排

/*非递归版本,使用一个stack来记录待排序的边界*/

    public static void quickSort2 (int[] arrayint startint end) {

        Stack<Integer> stack =new Stack<Integer>();

        if (start<end) {

            int middle=originalPartition(arraystartend);

            if (start<middle-1) {

                stack.push(start);

                stack.push(middle-1);

            }

            if (middle+1<end) {

                stack.push(middle+1);

                stack.push(end);

            }

            while (!stack.empty()) {

                int currentEnd=stack.pop();

                int currentStart=stack.pop();

                middle=originalPartition(arraycurrentStartcurrentEnd);

                if (currentStart<middle-1) {

                    stack.push(currentStart);

                    stack.push(middle-1);

                }

                if (middle+1<currentEnd) {

                    stack.push(middle+1);

                    stack.push(currentEnd);

                }

            }

           

        }

       

    }





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值