关闭

快速排序浅谈——(解题报告)HDU1157和POJ2388---Who's in the Middle

标签: 快速排序排序算法
390人阅读 评论(0) 收藏 举报
分类:

快速排序(快排)作为排序算法中较为常用和重要的一种,有其重要的地位,但初学可能有些晦涩,本文将较为详细的结合Who’s in the Middle这道题来讲讲快速排序的奥秘!

首先是快排的简单介绍,它是由冒泡排序改进而来,基本思想是:(百科)通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

各种常用排序算法

快排的算法复杂度是 O(N*logN) 关于算法复杂度请戳这里 [百科] (http://baike.baidu.com/link?url=4RvZP-1ePAh0AnmNchDTLsVW94amkPwyjZk0pxykADbGcAjyfkb_7IMCQZAFj-9W0BdmfUV289N_Zuh0wrHtAa)

还得知道快排并不是一种稳定的排序方式,由于每次都需要和基准元素交换,因此原来的顺序就可能被打乱。如序列为 5 3 3 4 3 8 9 10 11会将3的顺序打乱。所以说,快速排序是不稳定的!

接下来就是基本思路了:
1)设置两个变量i、j,排序开始的时候:i=0,j=N-1;

2) 注意其中最为关键的就是基准元素,一般是每个递归的第一个元素。所以以第一个数组元素作为关键数据,赋值给key,即key=A[0];

3)从j开始向前搜索,即由后开始向前搜索(j–),找到第一个小于key的值A[j],将A[j]和A[i]互换;

4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]互换;

5)重复第3、4步,直到i=j; (3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[i]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。找到符合条件的值,进行交换的时候i, j指针位置不变。另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束)

下面是较详细的一段代码指导:

void quicksort(int a[],int left,int right)
{
    int i,j,key,low,high;//key是基准
    low=left;
    high=right;
    key=a[left];//以最左边的数为基准
    if (left<right)//如果传递进来的还有元素
    {
       while (low<high)
    {
    while ((low<high)&&(a[high]>=key))    //找到小于基准的数(为什么右边先动,如果第一次左边先动找到了大于key的位置,那它应该放在右边的哪里呢,显然不知道,而右边先动,一旦找到小于key的就和基准换位置,反正最后还要将基准塞进一个新位置)         
    {
         high--;
    }

    a[low]=a[high];     //小于的那个数应该是属于基准数左边的(如果第一次循环就正好代替了基准数,这也是使用key保留的原因)

    while ((low<high)&&(a[low]<=key))     //这里说明为什么要含等号,因为我们假设3,2,3.如果没有等号,第一次循坏跳过,第二次循环也跳过,然而low仍小于high,死循环!(而加了=,第一次就是2,此时2,2,3,第二次也是2,此时2,2,3,最后替换key,
    {
         low++;     //找到大于基准的数
    }
    a[high]=a[low];      //他应该是属于右边的,还记得刚才high的值小于key被保存在左边了吗,现在正好把原来小的值覆盖掉换成大于基准的数

    }     //以上就是将所有大于key的数放在右边,小于key的数放在左边
    a[low]=key;     //最后一定是剩下key的值没有 
    quicksort(a,left,low-1);    //注意是left而不是0!!!
    quicksort(a,low+1,right);
  }
}

可以将下面的例子带入验证!

例子

接下来是HDU1157这道题!

Who’s in the Middle
Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u
Submit

Status
Description
FJ is surveying his herd to find the most average cow. He wants to know how much milk this ‘median’ cow gives: half of the cows give as much or more than the median; half give as much or less.

Given an odd number of cows N (1 <= N < 10,000) and their milk output (1..1,000,000), find the median amount of milk given such that at least half the cows give the same amount of milk or more and at least half give the same or less.
Input
* Line 1: A single integer N

  • Lines 2..N+1: Each line contains a single integer that is the milk output of one cow.
    Output
  • Line 1: A single integer that is the median milk output.
    Sample Input
    5
    2
    4
    1
    3
    5
    Sample Output
    3
    Hint
    INPUT DETAILS:

Five cows with milk outputs of 1..5

OUTPUT DETAILS:

1 and 2 are below 3; 4 and 5 are above 3.

解题思路:
使用一次快排,然后输出中间元素;
注意这里也可以使用sort-cmp函数进行排序、具体方法和情况将在接下来的二次快排的题目中使用!
给出链接!!![] (http://blog.csdn.net/why850901938/article/details/49983201)
代码如下:

#include <stdio.h>

void quicksort(int *a,int left,int right)
{   

    if(left>=right)
    {
        return ;
    }
    int i,j,key;
    i=left;
    j=right;
    key=a[i];
    while(i<j)
    {
    while(i<j&&key<=a[j])
    {
        j--;
    }
    a[i]=a[j];
    while(i<j&&key>=a[i])
    {
        i++;
    }
    a[j]=a[i];
    }
    a[i]=key;
    quicksort(a,left,i-1);
    quicksort(a,i+1,right);


}

int main()
{
    int a[10001],k,n;
    while(scanf("%d",&n)!=EOF)
    {
    for(k=0;k<n;k++)
    scanf("%d",&a[k]);
    quicksort(a,0,n-1);
    printf("%d\n",a[n/2]);


}return 0;
}

仅代表个人观点,有参照百科和他人博客和思路,不喜勿喷!

miku美图一张~~~

1
0
查看评论

hdu1157 Who's in the Middle

Problem Description FJ is surveying his herd to find the most average cow. He wants to know how much milk this 'median' cow gives: half of ...
  • sinat_39591298
  • sinat_39591298
  • 2017-09-29 21:49
  • 107

HDU1157 Who's in the Middle

Who's in the Middle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission...
  • u012846486
  • u012846486
  • 2014-08-27 22:22
  • 734

HDU1157:Who's in the Middle

Problem Description FJ is surveying his herd to find the most average cow. He wants to know how much milk this 'median' cow gives: half of th...
  • libin56842
  • libin56842
  • 2013-02-24 18:27
  • 2107

poj2388Who's in the Middle(快速排序)

Who’s in the Middle Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 42776 Accepted: 24737 DescriptionFJ is surveying his her...
  • qq_32792879
  • qq_32792879
  • 2017-07-16 20:54
  • 61

浅谈快速排序

谈起快速排序,大家都不陌生了,如果现在我让你
  • g96968586
  • g96968586
  • 2014-04-20 19:33
  • 717

解题报告Who's in the Middle

Who's in the Middle Time Limit:1000MS     MemoryLimit:65536KB    Description FJ is surveying his herd to fin...
  • u013447891
  • u013447891
  • 2014-01-18 10:40
  • 336

黑马程序员--浅谈快速排序

----------- android培训、java培训、java学习型技术博客、期待与您交流! ---------      快速排序其实是冒泡排序的改进,它十分经典,对于锻炼我们的算法思想也很有帮助。     ...
  • u014182629
  • u014182629
  • 2015-12-18 14:41
  • 229

Who's in the Middle(水题,谁在中间)

Who's in the Middle   Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3732 Accep...
  • qaz135135135
  • qaz135135135
  • 2016-07-20 20:11
  • 485

hdu1157解题报告

思路:题目的意思就是求中位数。 编程语言:C语言 代码如下: #include void qsort(int *a, int l, int r) {  int x = a[l];  int i = l, j = r;  if (l >= r) re...
  • wangbaixin
  • wangbaixin
  • 2014-01-19 19:19
  • 416

HDU1157 POJ2388 Who's in the Middle【第k大数+中位数+水题】

Who's in the Middle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s):...
  • tigerisland45
  • tigerisland45
  • 2016-08-09 05:22
  • 816
    个人资料
    • 访问:115895次
    • 积分:2454
    • 等级:
    • 排名:第17751名
    • 原创:141篇
    • 转载:9篇
    • 译文:0篇
    • 评论:3条