荷兰国旗

问题描述

现有n个红白蓝三种不同个颜色的球,乱序排在一起,请通过两两交换任意两个球,使得从左到右的球依次是红球、白球、篮球。

方法1-无差别2次快排

可以将红白蓝三种球分别标号为1、2、3,相当于1、2、3是乱序的,
需要将它们排列成1..1、2….2、3…3 照此情况,两次无差别的快排(不关心元素的特殊性–只有1、2、3三个元素,只需要它们从小到大排列出来)完全是可以办到的。

下面的代码是 无差别交换式快排 的实现:

/************************
Author:tmw
date:2017-11-24
************************/
#include <stdio.h>
#include <stdlib.h>

#define swap(x,y,t) (t=x,x=y,y=t)

int fast_sort_swap_no_different( int* array , int low , int high )
{
    int target = array[low];
    int temp;
    while(low<high)
    {
        while(array[high]>=target &&low<high)
            high--;
        swap(array[high],array[low],temp);
        while(array[low]<=target && low<high)
            low++;
        swap(array[low],array[high],temp);
    }
    return low;
}
int* fast_sort( int* array , int low , int high )
{
    int mid;
    if( low < high )
    {
        mid = fast_sort_swap_no_different(array,low,high);

        fast_sort(array,low,mid-1);
        fast_sort(array,mid+1,high);
    }
    return array;
}

测试代码:

int main()
{
    printf("测试程序!\n");
    int i;
    int* res;res=(int*)malloc(100*sizeof(int));

    int a1[13] = {0,2,1,1,1,2,0,0,2,0,1,1,2};
    printf("原数组为:");
    for(i=0;i<13;i++)
        printf("%d ",a1[i]);
    printf("\n");
    printf("排列后的数组为:");
    res = fast_sort(a1,0,12);
    for(i=0;i<13;i++)
        printf("%d ",res[i]);

    return 0;
}

测试结果:

这里写图片描述


方法2-有差别快排

无差别的快排总感觉没有很好地利用题目给出的条件:只有红球白球和黑球,对应数字就是只有0,1,2,因此,可以专门针对只有三种元素的情况设计一种有差别的快排算法:

设计三种指针:front current rear
算法开始,front和current游标都指向数组的首,rear游标指向数组的尾
1)当current游标所指向的元素为0时,与front游标所指元素交换,front++ current++;
2)当current游标所指向的元素为1时,不交换,current++;
3)当current游标所指向的元素为2时,与rear游标所指向的元素交换,rear–。


有差别快排代码如下:

/******************
Author:tmw
date:2017-11-24
******************/
#include <stdio.h>
#include <stdlib.h>

#define swap(x,y,t) (t=x,x=y,y=t)

int* Dutch_flag_like_fast_sort( int* array , int array_len )
{
    int front,current,rear,temp;
    front = current = 0;
    rear = array_len - 1;
    while(current<=rear)
    {
        if( array[current] == 0 )
        {
            swap(array[current],array[front],temp);
            current++;front++;
        }
        else if( array[current] == 1 )
            current++;
        else
        {
            swap( array[current],array[rear],temp);
            rear--;
        }
    }
    return array;
}

测试代码及结果与上面的方法一样,这里不赘述了。


梦想还是要有的,万一实现了呢~~~ヾ(◍°∇°◍)ノ゙

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值