zoukankan      html  css  js  c++  java
  • qsort代码(pascal/c/c++)与思想及扩展(随机化,TopK)

     

    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 [1..100] 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 2];
     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:=1 to n do
    27         read(a[i]);
    28     qsort(1,n);
    29     for i:=1 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+1];
     6  
     7 void qsort_(long l,long r)
     8 {
     9     long i,j,x,y;
    10     i=l; j=r; x=a[(l+r)>>1];
    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=1;i<=n;i++)
    33         scanf("%ld",&a[i]);
    34     qsort_(1,n);
    35     for (i=1;i<=n;i++)
    36         printf("%ld ",a[i]);
    37     printf("
    ");
    38     return 0;
    39 }

    3.C++:

     1 #include <iostream>
     2 #define maxn 100
     3 using namespace std;
     4  
     5 long a[maxn+1];
     6  
     7 void qsort_(long l,long r)
     8 {
     9     long i,j,x,y;
    10     i=l; j=r; x=a[(l+r)>>1];
    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=1;i<=n;i++)
    33         cin>>a[i];
    34     qsort_(1,n);
    35     for (i=1;i<=n;i++)
    36         cout<<a[i]<<" ";
    37     cout<<endl;
    38     return 0;
    39 }

    注释版:

    1.Pascal:

     1 var n,i:longint;
     2     a:array [1..100] 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 2];
    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-1; 也是i增加,j减少的操作
    13     repeat
    14         //执行完下面一条语句后,a[l]~a[i-1]的数都小于等于x(i=l另当别论),而a[i]大于等于x。而为什么是小于等于而不是小于,后面有解释。       
    15 while (a[i]<x) do inc(i);
    16         //执行完下面一条语句后,a[j+1]~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-1]的数都小于等于x,而a[i]大于等于x;a[j+1]~a[r]的数都大于等于x,而a[j]小于等于x,
    19             //所以执行完上面两条语句后,i<=j+1,j>=i-1。而第一次执行while循环时,不可能出现i>l,j<r的情况(最坏情况是i or j遇到a[i or j]=x而停止)
    20                 //然后if循环语句i=i+1,j=j-1,使得i<=j+1<=l,j>=i-1>=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-1]的数都小于等于x,a[i]是否大于等于x还未确定,需要下一次while循环使得 那时的i满足a[i]大于等于x。
    31                 //a[j+1]~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-1]的值都小于等于x,a[j+1]~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+1或i=j+2
    40         //当出现i=j+2情况,只可能为:执行完两个while语句(while (a[i]<x) i++;,while (a[j]>x) j=j-1;)后,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+2
    43  
    44                 //以下情况不可能出现:两个while语句执行完之前,i=j;两个while语句执行完之后,i=j+245                     //因为不可能a[i]<x和a[j]>x同时成立,
    46                     //当a[i]<x,执行i++,然后a[i+1]>=x(a[j+1]~a[r]的数都大于等于x,此时i+1=j+1),结束i的增加;
    47                     //当a[j]>x,执行j--,然后a[j-1]<=x(a[l]~a[i-1]的数都小于等于x,此时j-1=i-1),结束j的减少
    48  
    49         //当i=j+150             //i=j+1,qsort_(i,r):对a[j+1]~a[r]进行排序(a[j+1]~a[r]的值都小于等于x)
    51             //j=i-1,qsort_(l,j):对a[l]~a[i-1]进行排序(a[l]~a[i-1]的值都小于等于x)
    52             //qsort_(i,r),qsort_(l,j)执行完后,a[l]~a[j]排好序,且值小于等于x(当前);a[j+1]~a[r]排好序,且值小于等于x(当前)
    53             //即a[l]~a[r]可以分成两部分,a[l]~a[j]小于等于x,a[j+1]~a[r]大于等于x,且两部分已排好顺序,所以a[l]~a[r]也排好顺序
    54  
    55         //当i=j+256             //a[i-1]=a[j+1]=x
    57             //a[l]~a[r]可以分成三部分,a[l]~a[j]小于等于x,a[j+2]~a[r]大于等于x,且两部分已排好顺序,两部分中间的数a[j+1]=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:=1 to n do
    67         read(a[i]);
    68     qsort(1,n);
    69     for i:=1 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+1];
     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)>>1];
    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=1;i<=n;i++)
    73         scanf("%ld",&a[i]);
    74     //不能使用qsort名称,因为c函数库有qsort函数
    75     //不用向qsort函数一样一般把数组初始下标设为0
    76     qsort_(1,n);
    77     for (i=1;i<=n;i++)
    78         printf("%ld ",a[i]);
    79     printf("
    ");
    80     return 0;
    81 }

    3.C++

     1 #include <iostream>
     2 #define maxn 100
     3 using namespace std;
     4  
     5 long a[maxn+1];
     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)>>1];
    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=1;i<=n;i++)
    73         cin>>a[i];
    74     //不能使用qsort名称,因为c函数库有qsort函数
    75     //不用向qsort函数一样一般把数组初始下标设为0
    76     qsort_(1,n);
    77     for (i=1;i<=n;i++)
    78         cout<<a[i]<<" ";
    79     cout<<endl;
    80     return 0;
    81 }

    另外:

    qsort的另外一种写法

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #define maxn 100
     4 
     5 long a[maxn+1];
     6 
     7 void quicksort(long l,long r)
     8 {
     9     long i,j,x,y;
    10     x=a[r];
    11     i=l-1;
    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+1];
    22     a[i+1]=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+2<r)
    30         quicksort(i+2,r);
    31 }
    32 
    33 int main()
    34 {
    35     long n,i;
    36     scanf("%ld",&n);
    37     for (i=1;i<=n;i++)
    38         scanf("%ld",&a[i]);
    39     quicksort(1,n);
    40     for (i=1;i<=n;i++)
    41         printf("%ld ",a[i]);
    42     printf("
    ");
    43     return 0;
    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+1];
     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+1)+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=1;i<=n;i++)
    35         scanf("%ld",&a[i]);
    36     qsort_(1,n);
    37     for (i=1;i<=n;i++)
    38         printf("%ld ",a[i]);
    39     printf("
    ");
    40     return 0;
    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+1];
     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+1);
    13     x=a[i];
    14     a[i]=a[r];
    15     a[r]=x;
    16     //此时x=a[r]
    17     i=l-1;
    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+1];
    28     a[i+1]=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+2<r)
    36         quicksort(i+2,r);
    37 }
    38 
    39 int main()
    40 {
    41     srand(time(NULL));
    42     long n,i;
    43     scanf("%ld",&n);
    44     for (i=1;i<=n;i++)
    45         scanf("%ld",&a[i]);
    46     quicksort(1,n);
    47     for (i=1;i<=n;i++)
    48         printf("%ld ",a[i]);
    49     printf("
    ");
    50     return 0;
    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+1],n,k,pos=0;
    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-1;
    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
    ",x);
    36         exit(0);
    37     }
    38     else if (i<k)
    39         quicksort(i+1,r);
    40     else
    41         quicksort(l,i-1);
    42 }
    43 
    44 int main()
    45 {
    46     long i;
    47     scanf("%ld%ld",&n,&k);
    48     for (i=1;i<=n;i++)
    49         scanf("%ld",&a[i]);
    50     quicksort(1,n);
    51     return 0;
    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

  • 相关阅读:
    .net常用框架总结
    微信小程序 语音转换
    nginx+redis实现session共享 .NET分布式架构
    Redis 安装及注册服务
    WebApi跨域
    Uri各个属性取值测试
    一些常用的FFMPEG命令集合
    动态规划重学习笔记
    给自己的电脑时间进行精准校时
    [NOI题库][POJ2536][匈牙利算法][二分图最大匹配]Gopher II
  • 原文地址:https://www.cnblogs.com/cmyg/p/6815037.html
Copyright © 2011-2022 走看看