Internal Sorting: Quicksort-2: Sorting by Exchanging

本文详细介绍了快速排序算法,包括动画演示、复杂度分析、算法流程、数据表和Java实现。特别指出,选择中间元素作为枢轴可以提高已排序或相同元素数组的排序效率。
摘要由CSDN通过智能技术生成

Quicksort-2:快速排序-2


Animation

quick sort
Animated visualization of the quicksort algorithm. The horizontal lines are pivot values.


这里写图片描述
Full example of quicksort on a random set of numbers. The shaded element is the pivot. It is always chosen as the last element of the partition. However, always choosing the last element in the partition as the pivot in this way results in poor performance ( O(n2) ) on already sorted arrays, or arrays of identical elements. Since sub-arrays of sorted / identical elements crop up a lot towards the end of a sorting procedure on a large set, versions of the quicksort algorithm which choose the pivot as the middle element run much more quickly than the algorithm described in this diagram on large sets of numbers.


Complexity

ClassSorting algorithm
Data structureArray
Worst case performance O(n2)
Best case performance O(nlogn) (simple partition) or O(n) (three-way partition and equal keys)
Average case performance O(nlogn)
Worst case space complexity O(n) auxiliary (naive), O(logn) auxiliary (Sedgewick 1978)

Algorithm Q

Algorithm Q (Quicksort). Records R1,...,RN are rearranged in place; after
sorting is complete their keys will be in order, K1<=...<=KN . An auxiliary
stack with at most lgN entries is needed for temporary storage. This algorithm
follows the quicksort partitioning procedure described in the text above, with
slight modifications for extra efficiency:
a) We assume the presence of artificial keys K0= and KN+1=+ such
that

K0<=Ki<=KN+1 for 1<=i<=N . (13)

(Equality is allowed.)
b) Subfiles of M or fewer elements are left unsorted until the very end of the
procedure; then a single pass of straight insertion is used to produce the final
ordering. Here M>=1 is a parameter that should be chosen as described in
the text below. (This idea, due to R. Sedgewick, saves some of the overhead
that would be necessary if we applied straight insertion directly to each small
subfile, unless locality of reference is significant.)
c) Records with equal keys are exchanged, although it is not strictly necessary
to do so. (This idea, due to R. C. Singleton, keeps the inner loops fast and
helps to split subfiles nearly in half when equal elements are present; see
exercise 18.)
Q1. [Initialize.] If N<=M , go to step Q9. Otherwise set the stack empty, and
set l1,rN .
Q2. [Begin new stage.] (We now wish to sort the subfile Rl...Rr ; from the
nature of the algorithm, we have r>=l+M , and Kl1<=Ki<=Kr+1 for
l<=i<=r .) Set il,jr+1 ; and set KKl . (The text below discusses
alternative choices for K that might be better.)

Kk<=K for l1<=k<=i,K<=Kk for j<=k<=r+1 ; (14)

and l<=i<j .) Increase i by 1; then if Ki<K , repeat this step. (Since
Kj>=K , the iteration must terminate with i<=j .)
Q4. [Compare K:Kj .] Decrease j by 1; then if K<Kj , repeat this step. (Since
K>=Ki1 , the iteration must terminate with j>=i1 .)
Q5. [Test i:j .] (At this point, (14) holds except for k=i and k=j ; also
Ki>=K>=Kj , and r>=j>=i1>=l .) If j<=i , interchange RlRj and
go to step Q7.
Q6. [Exchange.] Interchange RiRj and go back to step Q3.
Q7. [Put on stack.] (Now the subfile Rl...Rj...Rr has been partitioned so
that Kk<=Kj for l1<=k<=j and Kj<=Kk for j<=k<=r+1 . If
rj>=jl>M , insert (j+1,r) on top of the stack, set rj1 , and go
to Q2. lf jl>rj>M , insert (l,j1) on top of the stack, set lj+1 ,
and go to Q2. (Each entry (a,b) on the stack is a request to sort the subfile
Ra...Rb at some future time.) Otherwise if rj>M>=jl , set lj+1
and go to Q2; or if jl>M>=rj , set rj1 and go to Q2.
Q8. [Take off stack.] If the stack is nonempty, remove its top entry (l,r) , set
ll,rr , and return to step Q2.
Q9. [Straight insertion sort.] For j=2,3,...,N , if Kj1>Kj do the following
operations: Set KKj,RRj,ij1 ; then set Ri+1Ri and
ii1 one or more times until Ki<=K ; then set Ri+1R . (This
is Algorithm 5.2.1S, modified as suggested in exercise 5.2.1-10 and answer
5.2.1-33. Step Q9 may be omitted if M=1 . Caution: The final straight
insertion might conceal bugs in steps Q1-Q8; don’t trust an implementation
just because it gives the correct answers!) |


Flow diagram

Quicksort-2:Sorting by Exchanging:Internal Sorting


Data table

这里写图片描述


Java program

In this program, R1,…,RN were simplified to K1,…,KN.

/**
 * Created with IntelliJ IDEA.
 * User: 1O1O
 * Date: 12/3/13
 * Time: 10:01 PM
 * :)~
 * Quicksort-2:Sorting by Exchanging:Internal Sorting
 */
public class Main {

    public static void main(String[] args) {
        int N = 16;
        int[] K = new int[18];
        int[] L = new int[5];   /*Space at most Math.floor(Math.log(N)/Math.log(2))*/
        int[] R = new int[5];   /*Space at most Math.floor(Math.log(N)/Math.log(2))*/
        int len = 0;
        int M = 4;
        int temp;

        /*Prepare the data*/
        K[0] = -10000;              /*Negative Infinity*/
        K[1] = 503;
        K[2] = 87;
        K[3] = 512;
        K[4] = 61;
        K[5] = 908;
        K[6] = 170;
        K[7] = 897;
        K[8] = 275;
        K[9] = 653;
        K[10] = 426;
        K[11] = 154;
        K[12] = 509;
        K[13] = 612;
        K[14] = 677;
        K[15] = 765;
        K[16] = 703;
        K[17] = 10000;              /*Positive Infinity*/

        /*Output unsorted Ks*/
        System.out.println("Unsorted Ks:");
        for(int i=1; i<=N; i++){
            System.out.println(i+":"+K[i]);
        }
        System.out.println();

        /*Kernel of the Algorithm!*/
        int l;
        int r;
        int i;
        int j;
        int Key;
        boolean stackEmpty = false;

        if(N > M){
            len = 0;
            l = 1;
            r = N;

            do{
                i = l;
                j = r+1;
                Key = K[l];

                do{
                    do{
                        i++;                  /*Q3*/
                    }while (K[i] < Key);

                    do{
                        j--;                    /*Q4*/
                    }while (Key < K[j]);

                    if(j <= i){                      /*Q5*/
                        temp = K[l];
                        K[l] = K[j];
                        K[j] = temp;

                        if(r-j >= j-l && j-l > M){                /*Q7*/
                            len++;
                            L[len] = j+1;
                            R[len] = r;
                            r = j-1;
                            break;
                        }else if(j-l > r-j && r-j > M){
                            len++;
                            L[len] = l;
                            R[len] = j-1;
                            l = j+1;
                            break;
                        }else if(r-j > M && M >= j-l){
                            l = j+1;
                            break;
                        }else if(j-l > M && M >= r-j){
                            r = j-1;
                            break;
                        }
                        if(len != 0){                   /*Q8*/
                            l = L[len];
                            r = R[len];
                            len--;
                        }else {
                            stackEmpty = true;
                        }
                        break;
                    }else {
                        temp = K[i];                /*Q6*/
                        K[i] = K[j];
                        K[j] = temp;
                    }
                }while (true);
            }while (!stackEmpty);

            for(j=2; j<=N; j++){               /*Q9*/
                if(K[j-1] > K[j]){
                    Key = K[j];
                    i = j-1;
                    do{
                        K[i+1] = K[i];
                        i--;
                        if(i == 0){
                            break;
                        }
                    }while (K[i] > Key);
                    K[i+1] = Key;
                }
            }
        }else {
            for(j=2; j<=N; j++){                 /*Q9*/
                if(K[j-1] > K[j]){
                    Key = K[j];
                    i = j-1;
                    do{
                        K[i+1] = K[i];
                        i--;
                        if(i == 0){
                            break;
                        }
                    }while (K[i] > Key);
                    K[i+1] = Key;
                }
            }
        }

        /*Output sorted Ks*/
        System.out.println("Sorted Ks:");
        for(i=1; i<=N; i++){
            System.out.println(i+":"+K[i]);
        }
    }
}

Outputs

Unsorted Ks:
1:503
2:87
3:512
4:61
5:908
6:170
7:897
8:275
9:653
10:426
11:154
12:509
13:612
14:677
15:765
16:703

Sorted Ks:
1:61
2:87
3:154
4:170
5:275
6:426
7:503
8:509
9:512
10:612
11:653
12:677
13:703
14:765
15:897
16:908

Reference

<< The art of computer programming: Sorting and Searching >> VOLUME 3, DONALD E. KNUTH
https://en.wikipedia.org/wiki/Quicksort

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值