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

8 篇文章 0 订阅
2 篇文章 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美图一张~~~

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值