天天看点

14-奇偶数排序问题描述方法1-1次快排-两头往中间搜索方法2-1次快排-前后指针往后搜索

问题描述

给定一个整数数组,请调整数组中数的顺序,使得所有奇数位于数组的前半分,>所有的偶数位于数组的后半部分,要求时间复杂度为O(n)。

方法1-1次快排-两头往中间搜索

结合快速排序的思想:一次快排能将小于中轴元素的值全放左边,大于中轴元素的值全放右边,那么推而言之,一次快排,也可以让所有奇数位于前半部分,所有偶数位于后半部分。

下面的代码用的方法是一次快排中的“两头往中间搜索”的方法。

/***********************************************
Author:tmw
date:2017-11-23
update: 2018-6-30
************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define swap(a,b,t) (t=a,a=b,b=t)

/**
* @param *array         为存储int型数据的数组
* @param array_len      为数组长度
* @param (*func)(int)   为一种通用方法,决定按照什么规则排序array数组,接收数据为int型--实现功能解耦
*/
int* reorder(int *array , int array_len, bool (*func)(int))
{
    //输入合法性检查
    if(!array||array_len==)
        return NULL;
    int low = ;
    int high = array_len-;
    int temp;

    while( low < high )
    {
        while( low < high && !func(array[high]) )//后半部分为偶数
            high--;

        while( low < high && func(array[low]) )
            low++;

        if( low < high )
            swap(array[low],array[high],temp);
    }
    return array;
}
/**
* 是奇数,返回true
*/
bool isOdd(int n)
{
    return n% !=  ? true : false;
}

/**
* 实现所有奇数在偶数的前面
*/
void odd_even_sort_method(int* array, int array_len)
{
    reorder(array,array_len,isOdd);
}
           

测试代码及结果如下:

int main()
{
    printf("测试代码!\n");
    int i;

    int a1[] = {,,,,,,,,-,-};
    printf("原数组为:");
    for(i=;i<;i++)
        printf("%d ",a1[i]);
    printf("\n");
    printf("奇偶排序后为:");
    odd_even_sort_like_qsort(a1,);
    for(i=;i<;i++)
        printf("%d ",a1[i]);
    printf("\n");

    int a2[] = {,,,,,,,-,-,,-,,,-,,};
    printf("原数组为:");
    for(i=;i<;i++)
        printf("%d ",a2[i]);
    printf("\n");
    printf("奇偶排序后为:");
    odd_even_sort_like_qsort(a2,);
    for(i=;i<;i++)
        printf("%d ",a2[i]);
    printf("\n");

    return ;
}
           
14-奇偶数排序问题描述方法1-1次快排-两头往中间搜索方法2-1次快排-前后指针往后搜索

方法2-1次快排-前后指针往后搜索

前后指针往后搜索

算法准备:

  • 定义两个游标–front和back,一前一后,front指向数组的第一个元素,back指向第一个元素的前一个元素;
  • 定义一个游标–rear 指向数组的最后一个元素。

算法基本思想:

rear作为中枢元素,若front指向的元素为奇数,则游标前移,back游标不动;若front指向的元素为偶数,则back游标前移,back指向的元素与front指向的元素交换。直到front游标挪动到rear的前一位判定完是偶数(或者交换完是偶数)之后,back游标前移一位,back指向的元素与rear的中枢元素交换。

下面的代码用的方法是一次快排中的“前后指针往后搜索”的方法

关于第2种快排实现–前后指针往后快排的方法,见july《编程之法》P46-47

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

#define swap(x,y,z) (z=x,x=y,y=z)
int* odd_even_sort_like_qsort_2(int *array , int array_len)
{
    int front,back,rear,temp;
    front = ;
    back = -;//数组元素从0开始存起
    rear = array_len - ;

    while( front < rear )
    {
        while( array[front]% ==  && front < rear )
            front++;
        //当array[front]值为奇数时:交换
        if( array[front]%!= )
        {
            back++;
            swap(array[back],array[front],temp);
            front++;
        }
    }
    //此时,front==rear
    back++;
    swap(array[back],array[front],temp);
    return array;
}
           

测试代码和结果与上面一致,这里就不做赘述了。

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