排序––快速排序(二)

根据排序––快速排序(一)的描述,现准备写一个快速排序的主体框架:算法

一、首先须要设置一个枢轴元素即setPivot(int i);框架

二、而后根据枢轴元素进行划分,将比枢轴元素大的排在右边,小的排在左边; .net

三、分别对枢轴元素左边和右边的序列重复1和2的步骤进行划分,这是一个递归过程,整个代码框架很简单:blog

public void sort(int from, int to) {
        if (from >= to) {
            return;
        }
        setPivot(from);
        int partitionPos = partition(from, to);
        sort(from, partitionPos - 1);
        sort(partitionPos + 1, to);
  }排序

  每一个子序列返回的条件是from >= to,因为枢轴元素是随机选择的,因此有如下几种划分状况:递归

一、轴枢元素正好能将序列分红均匀的两半,若是是奇数个元素那么子序列退出的条件是from==to,若是是偶数个元素如2个,那么会出现from>to的状况。get

二、轴枢元素不能将序列分红均匀的两半,最极端的状况是轴枢元素将划分的序列老是比它大或者小,此时一样会出现from>to的状况。it

实际上无论轴枢元素是否能将序列分红均匀的两半,只要序列的个数是偶数个必定会出现from>to的状况!io

目前只描述了最终划分结果可能出现的状况,尚未说明如何划分,下面给出一个划分的方案:循环

    假设给定序列七、六、五、四、三、二、1,并选择4为枢轴,则示例代码以下:

int   partition(int from, int to) {   
        int right = to;
        int left = from;
        while (true) {
            while (comparePivot(right) > 0) {
                right--;
            }

            while (comparePivot(left) < 0) {
                left++;
            }
            if (left == right) {
                break;
            }
            swap(left, right);
        }

        return left;
    }

     验证一下:7和1进行交换,序列变成一、六、五、四、三、二、7;left=0;right=6;

                      6和2进行交换,序列变成一、二、五、四、三、六、7;left=1;right=5;

                      5和3进行交换,序列变成一、二、三、四、五、六、7;left=2;right=4;

                      left=3;right=3;退出循环

                      而后分别调用sort(0,2),sort(4,6),对于sort(0,2)的排序过程以下:

                       假设选取2为枢轴,因为原始序列已经有序,right=1;left=1;退出循环。 最后的两个递归是sort(0,0)以及sort(2,2),这两个递归会因为from==to条件直接退出。

                      sort(4,6)也是相似的状况。

                    最后整个序列就是有序序列,由此看来该程序貌似正确,可是此状况比较特殊,为了能适应通常的状况,还需改进。其实正确的快速排序代码量不多,可是要把各类状况分析到位,写一个正确的快速排序代码我的认为起码没有其它排序算法那么简单。

相关文章
相关标签/搜索