Algorithm 使用递归进行排序
我有下面的函数对无序数组进行排序,使其前面有偶数,后面有奇数。有没有一种不使用任何循环就能完成的方法Algorithm 使用递归进行排序,algorithm,recursion,sorting,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
//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);
}
}
}
//前面是0,后面是array.length-1;
排列阵列(前、后);
公共静态void arrangeArray(int-front,int-back)
{
如果你想做的是
arrangeArray(front, back, bool recursed=false) {
if (recursed) {
arrangeArray(front, back/2, true);
return arrangeArray(back/2, back, true);
}
// Do stuff here.
}
对于没有循环的代码来说,这相当简单:
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);
}
}
void合并排序(整数低,整数高)
{
如果(lo当您执行递归时,您有一个基本步骤和一个递归步骤
在这种情况下,基本条件是当前面=向后时,因为你从边缘开始并在中间结束。当你到达中间时,你知道它已经完成了。
在执行递归步骤之前,您必须进行一些排序。您一次只执行一个步骤的排序,因此现在只处理array[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);
}
它未经测试,可能不适用于边缘条件,但这是一个良好的开端:)这不是简单的:
//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);
}
}
}
//前面是0,后面是array.length-1;
排列阵列(前、后);
公共静态void arrangeArray(int-front,int-back)
{
如果(front!=back | | front我可以推荐这个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和正数的比较器函数并使用它。下面的内容应该很有指导意义。这是一个递归的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);
}
}
我不认为合并排序的结构是这个问题的正确结构。这是在中间进行的,没有分而治之,只是纯迭代递归。查尔斯:如何在中间分裂数组,使用两个半部上的递归,然后合并它们,而不是分而治之的算法?我是SA。这个问题不需要分治(合并排序),分治问题通常用O(nlogn)来解决,这个问题可以用O(n)来解决哦,我假设它不需要数字在它们之间排序,只需要前面的偶数一半(不一定排序)后面还有一些奇怪的。@Charles Ma:是的,你从我这里得到了+1。嵌套三元运算符的滥用:P@Stephen:我不同意。之所以三元运算符是右关联的,是因为它允许这种表达式级别if-else
类似于构造。我同意Stephen的观点。因为你可以不用括号来编写它sn并不意味着你应该这么做。表达式x^a+b^c+d定义得很好,但是那些不知道优先级规则的人会感到非常困惑。嗯……如果你用record=false来调用它,它什么也不做。如果你用recursed=true来调用它,它将永远递归。