1.快速排序思想:从一堆数A中找到一个数x,然后把这堆数x分成两堆B,C,B堆的数小于(或小于等于)该数,放在左边,C堆的数大于(或大于等于)该数,放在右边,有可能把该数x单独分开,放在中间。然后对小于(或小于等于)该数的堆B和大于(或大于等于)该数的堆C进行上述相同的操作,直到堆中的数只有一个,不必排序。

2.快速排序随机化:对数x进行随机化选取。即若对a[l]~a[r]进行排序,则从l~r中选择一个数k,使x=a[k]。

3.求Topk(一个数组从小到大排序第k个数),O(n)。

若数x在堆中的位置i等于k,则输出x;若小于x,则从堆A(数小于等于x):a[1]~a[i-1]中找;若大于x,则从堆B(数大于x):a[i+1]~a[n]中找。

设对a[l]~a[r]排一次序需要r-l+1的时间,则最坏时间复杂度:n+n/2+n/4+……+1=2n-1<2n。

快速排序

——PascalCC++ 含解释

1.Pascal:

  1. var n,i:longint;
  2.     a:array [..] of longint;
  3.  
  4. procedure qsort(l,r:longint);
  5. var i,j,x,y:longint;
  6. begin
  7.     i:=l; j:=r; x:=a[(l+r) div ];
  8.     repeat
  9.         while (a[i]<x) do inc(i);
  10.         while (a[j]>x) do dec(j);
  11.         if (i<=j) then
  12.         begin
  13.             y:=a[i];
  14.             a[i]:=a[j];
  15.             a[j]:=y;
  16.             inc(i);
  17.             dec(j);
  18.         end;
  19.     until i>j;
  20.     if (i<r) then qsort(i,r);
  21.     if (j>l) then qsort(j,l);
  22. end;
  23.  
  24. begin
  25.     readln(n);
  26.     for i:= to n do
  27.         read(a[i]);
  28.     qsort(,n);
  29.     for i:= to n do
  30.         write(i,' ');
  31.     writeln;
  32. end.

2.C

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define maxn 100
  4.  
  5. long a[maxn+];
  6.  
  7. void qsort_(long l,long r)
  8. {
  9.     long i,j,x,y;
  10.     i=l; j=r; x=a[(l+r)>>];
  11.     while (i<=j)
  12.     {
  13.         while (a[i]<x) i++;
  14.         while (a[j]>x) j--;
  15.         if (i<=j)
  16.         {
  17.             y=a[i];
  18.             a[i]=a[j];
  19.             a[j]=y;
  20.             i++;
  21.             j--;
  22.         }
  23.     }
  24.     if (i<r) qsort_(i,r);
  25.     if (j>l) qsort_(l,j);
  26. }
  27.  
  28. int main()
  29. {
  30.     long n,i;
  31.     scanf("%ld",&n);
  32.     for (i=;i<=n;i++)
  33.         scanf("%ld",&a[i]);
  34.     qsort_(,n);
  35.     for (i=;i<=n;i++)
  36.         printf("%ld ",a[i]);
  37.     printf("\n");
  38.     return ;
  39. }

3.C++:

  1. #include <iostream>
  2. #define maxn 100
  3. using namespace std;
  4.  
  5. long a[maxn+];
  6.  
  7. void qsort_(long l,long r)
  8. {
  9.     long i,j,x,y;
  10.     i=l; j=r; x=a[(l+r)>>];
  11.     while (i<=j)
  12.     {
  13.         while (a[i]<x) i++;
  14.         while (a[j]>x) j--;
  15.         if (i<=j)
  16.         {
  17.             y=a[i];
  18.             a[i]=a[j];
  19.             a[j]=y;
  20.             i++;
  21.             j--;
  22.         }
  23.     }
  24.     if (i<r) qsort_(i,r);
  25.     if (j>l) qsort_(l,j);
  26. }
  27.  
  28. int main()
  29. {
  30.     long n,i;
  31.     cin>>n;
  32.     for (i=;i<=n;i++)
  33.         cin>>a[i];
  34.     qsort_(,n);
  35.     for (i=;i<=n;i++)
  36.         cout<<a[i]<<" ";
  37.     cout<<endl;
  38.     return ;
  39. }

注释版:

1.Pascal:

  1. var n,i:longint;
  2.     a:array [..] of longint;
  3.  
  4. procedure qsort(l,r:longint);
  5. //对a[l]~a[r]的数进行排序
  6. var i,j,x,y:longint;
  7. begin
  8. //x为a[l]~a[r]中的一个数
  9. i:=l; j:=r; x:=a[(l+r) div ];
  10. //i逐渐增加,j逐渐减少,最终i>=j,结束while循环
  11. //保证能有限次结束循环:if (i<=j) {i=i+1; j=j-1;} 如果i<=j,i增加,j减少
  12.     //而while (a[i]<x) i++; while (a[j]>x) j=j-; 也是i增加,j减少的操作
  13.     repeat
  14.         //执行完下面一条语句后,a[l]~a[i-]的数都小于等于x(i=l另当别论),而a[i]大于等于x。而为什么是小于等于而不是小于,后面有解释。       
  15. while (a[i]<x) do inc(i);
  16.         //执行完下面一条语句后,a[j+]~a[r]的数都大于等于x(j=r另当别论),而a[j]小于等于x。而为什么是大于等于而不是大于,后面有解释。
  17.         while (a[j]>x) do dec(j);
  18.         //*一开始i=l,j=r,i<=j,后来i增加,j减少,因为执行完上面两条语句后,a[l]~a[i-]的数都小于等于x,而a[i]大于等于x;a[j+]~a[r]的数都大于等于x,而a[j]小于等于x,
  19.             //所以执行完上面两条语句后,i<=j+,j>=i-。而第一次执行while循环时,不可能出现i>l,j<r的情况(最坏情况是i or j遇到a[i or j]=x而停止)
  20.                 //然后if循环语句i=i+,j=j-,使得i<=j+<=l,j>=i->=l,不存在i>r,j<l的情况
  21.  
  22.         //等号不可缺少,否则当i=j,a[i/j]=x时,程序不再有i,j变化的操作,导致死循
  23.         if (i<=j) then
  24.         begin
  25.             //a[i]与a[j]的交换:使得交换后a[i]<=x,a[j]>=x,这就是上面小于等于和大于等于的原因
  26.             y:=a[i];
  27.             a[i]:=a[j];
  28.             a[j]:=y;
  29.             //下面两条语句不可缺少,注意不要遗漏
  30.             //执行完下面两条语句后,a[l]~a[i-]的数都小于等于x,a[i]是否大于等于x还未确定,需要下一次while循环使得 那时的i满足a[i]大于等于x。
  31.                 //a[j+]~a[r]的数都大于等于x,a[j]是否小于等于x还未确定,需要下一次while循环使得 那时的j满足a[j]小于等于x。
  32.             inc(i);
  33.             dec(j);
  34.         end;
  35. until i>j;
  36.     //上述while循环执行完后,a[l]~a[i-]的值都小于等于x,a[j+]~a[r]的值都小于等于x
  37.         //所以上述while (i<=j) 必须包含等号,否则若while (i<j) ,最后i=j,不知道a[i/j]和x的大小关系
  38.  
  39.     //因为每次i都只增加1,每次j只减少1,if循环的代码if (i<=j) {i++; j--;},所以最后i=j+或i=j+
  40.         //当出现i=j+情况,只可能为:执行完两个while语句(while (a[i]<x) i++;,while (a[j]>x) j=j-;)后,i=j
  41.             //根据a[i]大于等于x,a[j]小于等于x,(此时i=j),判断出a[i]=x
  42.                 //然后 if循环的代码if (i<=j) {i=i+1; j=j-1;},使得i=j+
  43.  
  44.                 //以下情况不可能出现:两个while语句执行完之前,i=j;两个while语句执行完之后,i=j+。
  45.                     //因为不可能a[i]<x和a[j]>x同时成立,
  46.                     //当a[i]<x,执行i++,然后a[i+]>=x(a[j+]~a[r]的数都大于等于x,此时i+=j+),结束i的增加;
  47.                     //当a[j]>x,执行j--,然后a[j-]<=x(a[l]~a[i-]的数都小于等于x,此时j-=i-),结束j的减少
  48.  
  49.         //当i=j+时
  50.             //i=j+,qsort_(i,r):对a[j+]~a[r]进行排序(a[j+]~a[r]的值都小于等于x)
  51.             //j=i-,qsort_(l,j):对a[l]~a[i-]进行排序(a[l]~a[i-]的值都小于等于x)
  52.             //qsort_(i,r),qsort_(l,j)执行完后,a[l]~a[j]排好序,且值小于等于x(当前);a[j+]~a[r]排好序,且值小于等于x(当前)
  53.             //即a[l]~a[r]可以分成两部分,a[l]~a[j]小于等于x,a[j+]~a[r]大于等于x,且两部分已排好顺序,所以a[l]~a[r]也排好顺序
  54.  
  55.         //当i=j+时
  56.             //a[i-]=a[j+]=x
  57.             //a[l]~a[r]可以分成三部分,a[l]~a[j]小于等于x,a[j+]~a[r]大于等于x,且两部分已排好顺序,两部分中间的数a[j+]=x,所以a[l]~a[r]也排好顺序
  58.  
  59.         //上述就是qsort_(i,r),qsort_(l,j),而不是qsort_(l,i),qsort_(j,r)的原因,不要打错了
  60.     if (i<r) then qsort(i,r);
  61.     if (j>l) then qsort(j,l);
  62. end;
  63.  
  64. begin
  65.     readln(n);
  66.     for i:= to n do
  67.         read(a[i]);
  68.     qsort(,n);
  69.     for i:= to n do
  70.         write(i,' ');
  71.     writeln;
  72. end.

2.C

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define maxn 100
  4.  
  5. long a[maxn+];
  6.  
  7. void qsort_(long l,long r)
  8. {
  9.     //对a[l]~a[r]的数进行排序
  10.     long i,j,x,y;
  11.     //x为a[l]~a[r]中的一个数
  12.     i=l; j=r; x=a[(l+r)>>];
  13.     //i逐渐增加,j逐渐减少,最终i>=j,结束while循环
  14.     //保证能有限次结束循环:if (i<=j) {i=i+1; j=j-1;} 如果i<=j,i增加,j减少
  15.         //而while (a[i]<x) i++; while (a[j]>x) j=j-1; 也是i增加,j减少的操作
  16.     while (i<=j)
  17.     {
  18.         //执行完下面一条语句后,a[l]~a[i-1]的数都小于等于x(i=l另当别论),而a[i]大于等于x。而为什么是小于等于而不是小于,后面有解释。
  19.         while (a[i]<x) i++;
  20.         //执行完下面一条语句后,a[j+1]~a[r]的数都大于等于x(j=r另当别论),而a[j]小于等于x。而为什么是大于等于而不是大于,后面有解释。
  21.         while (a[j]>x) j--;
  22.         //*一开始i=l,j=r,i<=j,后来i增加,j减少,因为执行完上面两条语句后,a[l]~a[i-1]的数都小于等于x,而a[i]大于等于x;a[j+1]~a[r]的数都大于等于x,而a[j]小于等于x,
  23.             //所以执行完上面两条语句后,i<=j+1,j>=i-1。而第一次执行while循环时,不可能出现i>l,j<r的情况(最坏情况是i or j遇到a[i or j]=x而停止)
  24.                 //然后if循环语句i=i+1,j=j-1,使得i<=j+1<=l,j>=i-1>=l,不存在i>r,j<l的情况
  25.  
  26.         //等号不可缺少,否则当i=j,a[i/j]=x时,程序不再有i,j变化的操作,导致死循环
  27.         if (i<=j)
  28.         {
  29.             //a[i]与a[j]的交换:使得交换后a[i]<=x,a[j]>=x,这就是上面小于等于和大于等于的原因
  30.             y=a[i];
  31.             a[i]=a[j];
  32.             a[j]=y;
  33.             //下面两条语句不可缺少,注意不要遗漏
  34.             //执行完下面两条语句后,a[l]~a[i-1]的数都小于等于x,a[i]是否大于等于x还未确定,需要下一次while循环使得 那时的i满足a[i]大于等于x。
  35.                 //a[j+1]~a[r]的数都大于等于x,a[j]是否小于等于x还未确定,需要下一次while循环使得 那时的j满足a[j]小于等于x。
  36.             i++;
  37.             j--;
  38.         }
  39.     }
  40.     //上述while循环执行完后,a[l]~a[i-1]的值都小于等于x,a[j+1]~a[r]的值都小于等于x
  41.         //所以上述while (i<=j) 必须包含等号,否则若while (i<j) ,最后i=j,不知道a[i/j]和x的大小关系
  42.  
  43.     //因为每次i都只增加1,每次j只减少1,if循环的代码if (i<=j) {i++; j--;},所以最后i=j+1或i=j+2
  44.         //当出现i=j+2情况,只可能为:执行完两个while语句(while (a[i]<x) i++;,while (a[j]>x) j=j-1;)后,i=j
  45.             //根据a[i]大于等于x,a[j]小于等于x,(此时i=j),判断出a[i]=x
  46.                 //然后 if循环的代码if (i<=j) {i=i+1; j=j-1;},使得i=j+2
  47.  
  48.                 //以下情况不可能出现:两个while语句执行完之前,i=j;两个while语句执行完之后,i=j+2。
  49.                     //因为不可能a[i]<x和a[j]>x同时成立,
  50.                     //当a[i]<x,执行i++,然后a[i+1]>=x(a[j+1]~a[r]的数都大于等于x,此时i+1=j+1),结束i的增加;
  51.                     //当a[j]>x,执行j--,然后a[j-1]<=x(a[l]~a[i-1]的数都小于等于x,此时j-1=i-1),结束j的减少
  52.  
  53.         //当i=j+1时
  54.             //i=j+1,qsort_(i,r):对a[j+1]~a[r]进行排序(a[j+1]~a[r]的值都小于等于x)
  55.             //j=i-1,qsort_(l,j):对a[l]~a[i-1]进行排序(a[l]~a[i-1]的值都小于等于x)
  56.             //qsort_(i,r),qsort_(l,j)执行完后,a[l]~a[j]排好序,且值小于等于x(当前);a[j+1]~a[r]排好序,且值小于等于x(当前)
  57.             //即a[l]~a[r]可以分成两部分,a[l]~a[j]小于等于x,a[j+1]~a[r]大于等于x,且两部分已排好顺序,所以a[l]~a[r]也排好顺序
  58.  
  59.         //当i=j+2时
  60.             //a[i-1]=a[j+1]=x
  61.             //a[l]~a[r]可以分成三部分,a[l]~a[j]小于等于x,a[j+2]~a[r]大于等于x,且两部分已排好顺序,两部分中间的数a[j+1]=x,所以a[l]~a[r]也排好顺序
  62.  
  63.         //上述就是qsort_(i,r),qsort_(l,j),而不是qsort_(l,i),qsort_(j,r)的原因,不要打错了
  64.     if (i<r) qsort_(i,r);
  65.     if (j>l) qsort_(l,j);
  66. }
  67.  
  68. int main()
  69. {
  70.     long n,i;
  71.     scanf("%ld",&n);
  72.     for (i=;i<=n;i++)
  73.         scanf("%ld",&a[i]);
  74.     //不能使用qsort名称,因为c函数库有qsort函数
  75.     //不用向qsort函数一样一般把数组初始下标设为0
  76.     qsort_(,n);
  77.     for (i=;i<=n;i++)
  78.         printf("%ld ",a[i]);
  79.     printf("\n");
  80.     return ;
  81. }

3.C++

  1. #include <iostream>
  2. #define maxn 100
  3. using namespace std;
  4.  
  5. long a[maxn+];
  6.  
  7. void qsort_(long l,long r)
  8. {
  9.     //对a[l]~a[r]的数进行排序
  10.     long i,j,x,y;
  11.     //x为a[l]~a[r]中的一个数
  12.     i=l; j=r; x=a[(l+r)>>];
  13.     //i逐渐增加,j逐渐减少,最终i>=j,结束while循环
  14.     //保证能有限次结束循环:if (i<=j) {i=i+1; j=j-1;} 如果i<=j,i增加,j减少
  15.         //而while (a[i]<x) i++; while (a[j]>x) j=j-1; 也是i增加,j减少的操作
  16.     while (i<=j)
  17.     {
  18.         //执行完下面一条语句后,a[l]~a[i-1]的数都小于等于x(i=l另当别论),而a[i]大于等于x。而为什么是小于等于而不是小于,后面有解释。
  19.         while (a[i]<x) i++;
  20.         //执行完下面一条语句后,a[j+1]~a[r]的数都大于等于x(j=r另当别论),而a[j]小于等于x。而为什么是大于等于而不是大于,后面有解释。
  21.         while (a[j]>x) j--;
  22.         //*一开始i=l,j=r,i<=j,后来i增加,j减少,因为执行完上面两条语句后,a[l]~a[i-1]的数都小于等于x,而a[i]大于等于x;a[j+1]~a[r]的数都大于等于x,而a[j]小于等于x,
  23.             //所以执行完上面两条语句后,i<=j+1,j>=i-1。而第一次执行while循环时,不可能出现i>l,j<r的情况(最坏情况是i or j遇到a[i or j]=x而停止)
  24.                 //然后if循环语句i=i+1,j=j-1,使得i<=j+1<=l,j>=i-1>=l,不存在i>r,j<l的情况
  25.  
  26.         //等号不可缺少,否则当i=j,a[i/j]=x时,程序不再有i,j变化的操作,导致死循环
  27.         if (i<=j)
  28.         {
  29.             //a[i]与a[j]的交换:使得交换后a[i]<=x,a[j]>=x,这就是上面小于等于和大于等于的原因
  30.             y=a[i];
  31.             a[i]=a[j];
  32.             a[j]=y;
  33.             //下面两条语句不可缺少,注意不要遗漏
  34.             //执行完下面两条语句后,a[l]~a[i-1]的数都小于等于x,a[i]是否大于等于x还未确定,需要下一次while循环使得 那时的i满足a[i]大于等于x。
  35.                 //a[j+1]~a[r]的数都大于等于x,a[j]是否小于等于x还未确定,需要下一次while循环使得 那时的j满足a[j]小于等于x。
  36.             i++;
  37.             j--;
  38.         }
  39.     }
  40.     //上述while循环执行完后,a[l]~a[i-1]的值都小于等于x,a[j+1]~a[r]的值都小于等于x
  41.         //所以上述while (i<=j) 必须包含等号,否则若while (i<j) ,最后i=j,不知道a[i/j]和x的大小关系
  42.  
  43.     //因为每次i都只增加1,每次j只减少1,if循环的代码if (i<=j) {i++; j--;},所以最后i=j+1或i=j+2
  44.         //当出现i=j+2情况,只可能为:执行完两个while语句(while (a[i]<x) i++;,while (a[j]>x) j=j-1;)后,i=j
  45.             //根据a[i]大于等于x,a[j]小于等于x,(此时i=j),判断出a[i]=x
  46.                 //然后 if循环的代码if (i<=j) {i=i+1; j=j-1;},使得i=j+2
  47.  
  48.                 //以下情况不可能出现:两个while语句执行完之前,i=j;两个while语句执行完之后,i=j+2。
  49.                     //因为不可能a[i]<x和a[j]>x同时成立,
  50.                     //当a[i]<x,执行i++,然后a[i+1]>=x(a[j+1]~a[r]的数都大于等于x,此时i+1=j+1),结束i的增加;
  51.                     //当a[j]>x,执行j--,然后a[j-1]<=x(a[l]~a[i-1]的数都小于等于x,此时j-1=i-1),结束j的减少
  52.  
  53.         //当i=j+1时
  54.             //i=j+1,qsort_(i,r):对a[j+1]~a[r]进行排序(a[j+1]~a[r]的值都小于等于x)
  55.             //j=i-1,qsort_(l,j):对a[l]~a[i-1]进行排序(a[l]~a[i-1]的值都小于等于x)
  56.             //qsort_(i,r),qsort_(l,j)执行完后,a[l]~a[j]排好序,且值小于等于x(当前);a[j+1]~a[r]排好序,且值小于等于x(当前)
  57.             //即a[l]~a[r]可以分成两部分,a[l]~a[j]小于等于x,a[j+1]~a[r]大于等于x,且两部分已排好顺序,所以a[l]~a[r]也排好顺序
  58.  
  59.         //当i=j+2时
  60.             //a[i-1]=a[j+1]=x
  61.             //a[l]~a[r]可以分成三部分,a[l]~a[j]小于等于x,a[j+2]~a[r]大于等于x,且两部分已排好顺序,两部分中间的数a[j+1]=x,所以a[l]~a[r]也排好顺序
  62.  
  63.         //上述就是qsort_(i,r),qsort_(l,j),而不是qsort_(l,i),qsort_(j,r)的原因,不要打错了
  64.     if (i<r) qsort_(i,r);
  65.     if (j>l) qsort_(l,j);
  66. }
  67.  
  68. int main()
  69. {
  70.     long n,i;
  71.     cin>>n;
  72.     for (i=;i<=n;i++)
  73.         cin>>a[i];
  74.     //不能使用qsort名称,因为c函数库有qsort函数
  75.     //不用向qsort函数一样一般把数组初始下标设为0
  76.     qsort_(,n);
  77.     for (i=;i<=n;i++)
  78.         cout<<a[i]<<" ";
  79.     cout<<endl;
  80.     return ;
  81. }

另外:

qsort的另外一种写法

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define maxn 100
  4.  
  5. long a[maxn+];
  6.  
  7. void quicksort(long l,long r)
  8. {
  9. long i,j,x,y;
  10. x=a[r];
  11. i=l-;
  12. for (j=l;j<r;j++)
  13. //若数小于等于x,交换到a[l]~a[r]段的左方
  14. if (a[j]<=x)
  15. {
  16. i++;
  17. y=a[i];
  18. a[i]=a[j];
  19. a[j]=y;
  20. }
  21. y=a[i+];
  22. a[i+]=a[r];
  23. a[r]=y;
  24. //a[l]~a[i]为小于等于x的数
  25. if (l<i)
  26. quicksort(l,i);
  27. //a[i+1]=x
  28. //a[i+2]~a[r]为大于x的数
  29. if (i+<r)
  30. quicksort(i+,r);
  31. }
  32.  
  33. int main()
  34. {
  35. long n,i;
  36. scanf("%ld",&n);
  37. for (i=;i<=n;i++)
  38. scanf("%ld",&a[i]);
  39. quicksort(,n);
  40. for (i=;i<=n;i++)
  41. printf("%ld ",a[i]);
  42. printf("\n");
  43. return ;
  44. }
  45. /*
  46. 5
  47. 2 4 3 1 5
  48. */

qsort随机化

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #define maxn 100
  5.  
  6. long a[maxn+];
  7.  
  8. void qsort_(long l,long r)
  9. {
  10. long i,j,x,y;
  11. i=l; j=r; x=a[rand()%(r-l+)+l];
  12. while (i<=j)
  13. {
  14. while (a[i]<x) i++;
  15. while (a[j]>x) j--;
  16. if (i<=j)
  17. {
  18. y=a[i];
  19. a[i]=a[j];
  20. a[j]=y;
  21. i++;
  22. j--;
  23. }
  24. }
  25. if (i<r) qsort_(i,r);
  26. if (j>l) qsort_(l,j);
  27. }
  28.  
  29. int main()
  30. {
  31. srand(time(NULL));
  32. long n,i;
  33. scanf("%ld",&n);
  34. for (i=;i<=n;i++)
  35. scanf("%ld",&a[i]);
  36. qsort_(,n);
  37. for (i=;i<=n;i++)
  38. printf("%ld ",a[i]);
  39. printf("\n");
  40. return ;
  41. }
  42. /*
  43. 5
  44. 2 4 3 1 5
  45. */
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #define maxn 100
  5.  
  6. long a[maxn+];
  7.  
  8. void quicksort(long l,long r)
  9. {
  10. long i,j,x,y;
  11. //从a[l]~a[r]随机选择一个数
  12. i=l+rand()%(r-l+);
  13. x=a[i];
  14. a[i]=a[r];
  15. a[r]=x;
  16. //此时x=a[r]
  17. i=l-;
  18. for (j=l;j<r;j++)
  19. //若数小于等于x,交换到a[l]~a[r]段的左方
  20. if (a[j]<=x)
  21. {
  22. i++;
  23. y=a[i];
  24. a[i]=a[j];
  25. a[j]=y;
  26. }
  27. y=a[i+];
  28. a[i+]=a[r];
  29. a[r]=y;
  30. //a[l]~a[i]为小于等于x的数
  31. if (l<i)
  32. quicksort(l,i);
  33. //a[i+1]=x
  34. //a[i+2]~a[r]为大于x的数
  35. if (i+<r)
  36. quicksort(i+,r);
  37. }
  38.  
  39. int main()
  40. {
  41. srand(time(NULL));
  42. long n,i;
  43. scanf("%ld",&n);
  44. for (i=;i<=n;i++)
  45. scanf("%ld",&a[i]);
  46. quicksort(,n);
  47. for (i=;i<=n;i++)
  48. printf("%ld ",a[i]);
  49. printf("\n");
  50. return ;
  51. }
  52. /*
  53. 5
  54. 2 4 3 1 5
  55. */

Topk:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define maxn 100
  4.  
  5. //O(n)
  6. //设对a[l]~a[r]排一次序需要r-l+1的时间,
  7. //则最坏时间复杂度:n+n/2+n/4+……+1=2n-1<2n
  8. //使用这种方法的quicksort是因为这种方法能知道取的数x排序后在数组中的位置
  9.  
  10. long a[maxn+],n,k,pos=;
  11.  
  12. void quicksort(long l,long r)
  13. {
  14. //a[l]~a[r]排序
  15. long i,j,x,y;
  16. x=a[r];
  17. i=l-;
  18. for (j=l;j<r;j++)
  19. if (a[j]<=x)
  20. {
  21. i++;
  22. y=a[i];
  23. a[i]=a[j];
  24. a[j]=y;
  25. }
  26. i++;
  27. y=a[i];
  28. a[i]=a[r];
  29. a[r]=y;
  30. //a[l]~a[i-1]为小于等于x的数
  31. //a[i]=x
  32. //a[i+1]~a[r]为大于x的数
  33. if (i==k)
  34. {
  35. printf("%ld\n",x);
  36. exit();
  37. }
  38. else if (i<k)
  39. quicksort(i+,r);
  40. else
  41. quicksort(l,i-);
  42. }
  43.  
  44. int main()
  45. {
  46. long i;
  47. scanf("%ld%ld",&n,&k);
  48. for (i=;i<=n;i++)
  49. scanf("%ld",&a[i]);
  50. quicksort(,n);
  51. return ;
  52. }
  53. /*
  54. 5 1/2/3/4/5
  55. 5 2 4 3 1
  56. */

库中的快速排序函数,是随机化快速排序,且加了一些较复杂的优化,时间效率较高,时间紧张时用(contest)

c:qsort c:sort(#include <algorithm>)

http://www.cnblogs.com/cmyg/p/6810800.html

qsort代码(pascal/c/c++)与思想及扩展(随机化,TopK)的更多相关文章

  1. CWMP开源代码研究5——CWMP程序设计思想

    声明:本文涉及的开源程序代码学习和研究,严禁用于商业目的. 如有任何问题,欢迎和我交流.(企鹅号:408797506) 本文介绍自己用过的ACS,其中包括开源版(提供下载包)和商业版(仅提供安装包下载 ...

  2. 【spring cloud】对接口调用者提供API使用的安全验证微服务【这里仅通过代码展示一种设计思想】【后续可以加入redis限流的功能,某段时间某个IP可以访问API几次】

    场景: 公司的微服务集群,有些API 会对外提供接口,供其他厂商进行调用.这些公开的API接口,由一个OpenAPI微服务统一提供给大家. 那么所有的调用者在调用公开API接口的时候,需要验证是否有权 ...

  3. Java基础进阶:APi使用,Math,Arrarys,Objects工具类,自动拆装箱,字符串与基本数据类型互转,递归算法源码,冒泡排序源码实现,快排实现源码,附重难点,代码实现源码,课堂笔记,课后扩展及答案

    要点摘要 Math: 类中么有构造方法,内部方法是静态的,可以直接类名.方式调用 常用: Math.abs(int a):返回参数绝对值 Math.ceil(double a):返回大于或等于参数的最 ...

  4. Java基础进阶:内部类lambda重点摘要,详细讲解成员内部类,局部内部类,匿名内部类,Lambda表达式,Lambda表达式和匿名内部类的区别,附重难点,代码实现源码,课堂笔记,课后扩展及答案

    内部类lambda重点摘要 内部类特点: 内部类可以直接访问外部类,包括私有 外部类访问内部类必须创建对象 创建内部对象格式: 外部类.内部类 对象名=new外部类().new内部类(); 静态内部类 ...

  5. Java基础进阶:继承重点摘要,继承详解,方法重写注意事项,方法重载与重写的区别,抽象类,代码块, 附重难点,代码实现源码,课堂笔记,课后扩展及答案

    继承重点摘要 *继承的特点: 子类在初始化之前,一定要先完成父类数据的初始化 子类在初始化之前,一定要先访问父类构造,完成父类数据的初始化 系统在每一个构造方法中默认隐藏了一句super(); 如果我 ...

  6. Java基础进阶:学生管理系统数组方式分包源码实现,教师管理系统集合和数组两种方式源码实现,图书馆管理系统源码实现,现附重难点,代码实现源码,课堂笔记,课后扩展及答案

    1.案例驱动模式 1.1案例驱动模式概述 (理解) 通过我们已掌握的知识点,先实现一个案例,然后找出这个案例中,存在的一些问题,在通过新知识点解决问题 1.2案例驱动模式的好处 (理解) 解决重复代码 ...

  7. idea 添加代码自动提示支持,已PHP扩展 swoole 为例

    1,下载代码支持包 => swoole-ide-helper-en => https://github.com/eaglewu/swoole-ide-helper.git 2,如果安装了 ...

  8. Java基础进阶:多态与接口重点摘要,类和接口,接口特点,接口详解,多态详解,多态中的成员访问特点,多态的好处和弊端,多态的转型,多态存在的问题,附重难点,代码实现源码,课堂笔记,课后扩展及答案

    多态与接口重点摘要 接口特点: 接口用interface修饰 interface 接口名{} 类实现接口用implements表示 class 类名 implements接口名{} 接口不能实例化,可 ...

  9. 架构师修练 I - 超级代码控

    可实现的是架构,空谈是概念 So don't tell me the concepts show me the code!  “不懂编码的架构师不是好架构师” 好架构师都是超级代码控.   代码是最好 ...

随机推荐

  1. SpringBoot笔记--Jackson

    SpringUtil.getBean<GenericConversionService>().addConverter(Date2LocalDateTimeConverter()) var ...

  2. Linux服务器更换主板后,网卡识别失败的处理方法

    1)现象说明公司IDC机房里的一台线上服务器硬件报警,最后排查发现服务器主板坏了,随即联系厂商进行更换主板,最后更换后,登录服务器,发现网卡绑定及ip信息都在,但是ip却ping不通了,进一步排查,重 ...

  3. Nginx基于TCP/UDP端口的四层负载均衡(stream模块)配置梳理

    通过我们会用Nginx的upstream做基于http/https端口的7层负载均衡,由于Nginx老版本不支持tcp协议,所以基于tcp/udp端口的四层负载均衡一般用LVS或Haproxy来做.至 ...

  4. 移动app rem

    (function (doc, win) { var docEl = doc.documentElement, resizeEvt = 'orientationchange' in window ? ...

  5. 2-Twenty Second Scrum Meeting-20151222

    任务安排 成员 今日完成 明日任务 闫昊 服务器关闭,开发停滞……  …… 唐彬 服务器关闭,开发停滞……  …… 史烨轩  服务器关闭,开发停滞……  …… 余帆   路径保存 路径整合 金哉仁   ...

  6. 关于五子棋游戏java版

    一 题目简介:关于五子棋游戏 二 源码的github链接   https://github.com/marry1234/test/blob/master/五子棋游戏 三.所设计的模块测试用例.测试结果 ...

  7. solr6.2单机版安装

    1安装solr服务,先安装jdk和tomcat 2去官网(http://archive.apache.org/dist/lucene/solr/)下载solr压缩包,最新版本是6.4.1,下载解压后, ...

  8. CentOS7 安装 Jenkins

    1. 安装java环境, 自己的虚拟机里面前期已经安装好了 检查一下: [root@centos74 ~]# java -versionopenjdk version "1.8.0_131& ...

  9. CSS 居中(拿来主义自用)

    居中是我们使用css来布局时常遇到的情况.使用css来进行居中时,有时一个属性就能搞定,有时则需要一定的技巧才能兼容到所有浏览器,本文就居中的一些常用方法做个简单的介绍. 注:本文所讲方法除了特别说明 ...

  10. calico实现docker容器内部的网络链接

    calico官网 https://www.projectcalico.org// calico介绍 http://www.sdnlab.com/17161.html calico网络 环境 系统   ...