使用递归进行排序

时间:2010-04-27 01:02:59

标签: algorithm recursion sorting

我有以下函数将无序数组排序为前面有偶数,后面有奇数。有没有办法在不使用任何循环的情况下完成它?

//front is 0, back =array.length-1;
arrangeArray (front, back);

public static void arrangeArray (int front, int back)
{
    if (front != back || front<back)
    {
        while (numbers [front]%2 == 0)
            front++;


        while (numbers[back]%2!=0)
            back--;


        if (front < back)
        {
            int oddnum = numbers [front];
            numbers[front]= numbers[back];
            numbers[back]=oddnum;

            arrangeArray (front+1, back-1);
        }
    }
}

6 个答案:

答案 0 :(得分:3)

对于没有循环的代码,

Mergesort相当简单:

void mergesort(int lo, int hi)
{
    if (lo<hi)
    {
        int m=(lo+hi)/2;
        mergesort(lo, m);
        mergesort(m+1, hi);
        merge(lo, m, hi);
    }
}

我会让它为读者做一个偶数/奇怪的练习:)

(听起来像是家庭作业)

答案 1 :(得分:2)

当你进行递归时,你有一个基本步骤和一个递归步骤。

在这种情况下,基本条件是当前面==后面,因为你从边缘开始并最终在中间。当你到达中间时,你知道它已经完成了。

在执行递归步骤之前,您必须进行一些排序。你只是一次一步地进行排序,所以现在只处理数组[front]和array [back]的元素。在将它们安排到正确的位置后,进行递归调用。

你最终会得到这样的东西:

public static void arrangeArray (int front, int back)
{
   if(front >= back) return;
   int f = numbers[front];
   int b = numbers[back];
   if(f%2 == 0) {
      front++;
   } else {
      numbers[back] = f;
      back--;
   }
   if (b%2 == 0) {
      numbers[front] = b;
      front++;
   } else {
      back--;
   }  
   arrangeArray(front, back);                                         
}

它未经测试,可能不适用于边缘条件,但它是一个良好的开端:)

答案 2 :(得分:2)

不会那么简单:

//front is 0, back =array.length-1; 
arrangeArray (front, back); 

public static void arrangeArray (int front, int back) 
{ 
    if (front != back || front<back)
    { 
        if (numbers [front]%2 == 0) 
            arrangeArray (front+1, back); 
        else
        if (numbers[back]%2!=0) 
            arrangeArray (front, back-1); 
        else
        if (front < back) 
        { 
            int oddnum = numbers [front]; 
            numbers[front]= numbers[back]; 
            numbers[back]=oddnum; 

            arrangeArray (front+1, back-1); 
        } 
    } 
} 

答案 3 :(得分:1)

我可以推荐这个Python片段来激发高层次的思考吗?

compare = lambda x,y: x - y if x%2 == y%2 else y%2 - x%2
>>> sorted([3,4,2,1,5,6,7,90,23,44], cmp=compare)
[1, 3, 5, 7, 23, 2, 4, 6, 44, 90]

我认为需要构建一个比较器函数,它返回负数,0和正数并使用它。

答案 4 :(得分:0)

你想做的是

arrangeArray(front, back, bool recursed=false) {
    if (recursed) {
        arrangeArray(front, back/2, true);
        return arrangeArray(back/2, back, true);
    }
    // Do stuff here.
}

答案 5 :(得分:0)

以下内容应具有指导意义。这是一个递归O(N)解决方案,重新排列前面的偶数和后面的奇数,但除此之外不做任何排序。

static boolean isEven(int n) {
    return (n & 1) == 0;
}
static boolean isOdd(int n) {
    return !isEven(n);
}
static int[] swapped(int[] nums, int i, int j) {
    int t = nums[i];
    nums[i] = nums[j];
    nums[j] = t;
    return nums;
}
static int[] arrange(int[] nums, int lo, int hi) {
    return
        (lo >= hi) ? nums :
        (isEven(nums[lo])) ? arrange(nums, lo + 1, hi) :
        (isOdd(nums[hi])) ? arrange(nums, lo, hi - 1) :
        arrange(swapped(nums, lo, hi), lo + 1, hi - 1);
}   
static void evenOddSort(int... nums) {
    System.out.println(java.util.Arrays.toString(
        arrange(nums, 0, nums.length - 1)
    ));
}   
public static void main(String[] args) {
    evenOddSort(1,3,5,7,2,4,6);
} // prints "[6, 4, 2, 7, 5, 3, 1]"

我认为三元运算符可以更自然地使递归流动,但如果你对它的工作方式不太满意,你可以使用传统的if-else

static int[] arrange(int[] nums, int lo, int hi) {
    if (lo >= hi) {
        return nums;
    } else if (isEven(nums[lo])) {
        return arrange(nums, lo + 1, hi);
    } else if (isOdd(nums[hi])) {
        return arrange(nums, lo, hi - 1);
    } else {
        return arrange(swapped(nums, lo, hi), lo + 1, hi - 1);
    }
}