如何使用递归创建排序方法?

时间:2014-04-14 20:11:38

标签: java recursion

我正在学习递归,并且我被指示制作一个对数组进行排序的递归方法。到目前为止,我有这个:

public static void sort(int [] a, int i) {
    if(i == a.length - 1){
        System.out.println(a[i]);
    }
    if(i < a.length) {
        if(a[i] > a[i+1]) {
            int temp = a[i+1];
            a[i+1] = a[i];
            a[i] = temp;
            sort(a,i++);
        }
        printArray(a); 
    }
}

现在我知道这是错的,因为我仍然不太明白如何在编程中使用递归。如果有人可以帮我解决这个方法,我会很感激,但是如何在我的编程中使用递归的解释会很棒。提前谢谢。

3 个答案:

答案 0 :(得分:3)

要编写递归算法,您需要按照以下思路思考:如何通过解决同一问题的一个或多个较小实例来解决问题?对于类似&#34;排序N个整数数组&#34;的问题,较小的问题可能是N-1个整数的数组,或者它可能是两个N / 2整数数组(粗略地)或其他可能性。

由于您没有提供任何其他提示,最简单的事情是:好的,我有一个N个整数数组。让我们说我排序了最后的N-1个整数,这样我的数组看起来就像

------------------------------------------------|
| a[0]         | a[1] | a[2] | ...... | a[N-1]  |
------------------------------------------------|
| out of order | ......... all sorted ......... | 

如果你能做到这一点,那么因为你只有一个无序元素,你应该能够弄清楚如何交换元素以在正确的位置获得a[0]

所以现在方法的大纲如下所示:

void sort(int[] a, int i) {   // sort the elements from a[i] to a[N-1]
    if (i <= a.length - 2) {
        // Solve the smaller problem recursively.  But if the smaller problem is
        // only 0 or 1 elements, there's nothing else to do.
        sort (a, i + 1);      
    }
    // At this point, we've sorted elements from a[i+1] to a[N-1].  Now a[i] is
    // out of order; write logic that exchanges elements to get a[i] in the right
    // place.
}

另一种可能的方法:不是先排序N-1个元素,而是找到最小的元素,将其移动到数组的开头,这样你的数组就像

--------------------------------------------|
| a[0]     | a[1] | a[2] | ...... | a[N-1]  |
--------------------------------------------|
| in order | ........ out of order ........ | 

然后以递归方式调用该方法,将N-1个元素a[1]排序为a[N-1],然后您就完成了。

我认为你开始走上正轨;你只需要以正确的方式可视化问题,这需要一些练习。

答案 1 :(得分:1)

合并排序有助于递归,因为它涉及将数组分成两半,直到每个部分包含两个项目,然后对小块进行排序并将它们合并在一起。 http://en.wikipedia.org/wiki/Merge_sort

答案 2 :(得分:0)

来自Wikipedia

  

计算机科学中的递归是一种方法,其中问题的解决方案取决于对同一问题的较小实例的解决方案(而不是迭代)。该方法可以应用于许多类型的问题,递归是计算机科学的核心思想之一。

递归是了解如何在编程中使用的一个很好的工具。它的主要思想是将大量难以处理的想法或行动分解为更小的更易消化的想法或行动。虽然排序是递归的一个很好的例子,但我想向你展示我最喜欢的递归,递归字符串匹配的例子。

如果您有一个键,您的字符串与包含通配符的字符串匹配,则递归是将潜在匹配分解为更容易匹配的问题的好方法。

如果我们的密钥为a*b?c(其中*可以表示任意数量的字符,而?是任何单个字符),我们要检查azyxbwc以查看如果它们适合键,那么一旦你掌握了它,这个过程就非常简单了(我将为这个例子编写一个粗略的伪代码)。

Enter Function with key='a*b?c' and input='azyxbwc'
Retrieve first letter of key --> 'a'
Retrieve first letter of input --> 'a'
Does 'a' == 'a'  --> true
If true, call function with remaining key & input

Enter Function with key='*b?c' and input='zyxbwc'
Retrieve first letter of key --> '*'
Retrieve second letter of key --> 'b' //if first is a wildcard, get a second
Retrieve first letter of input --> 'z'
Does '*' == 'z'  --> false
Does 'b' == 'z'  --> false
Is '*' a wildcard --> true
If true, call function with remaining key & input //key keeps wild b/c second letter didn't match

Enter Function with key='*b?c' and input='yxbwc'
Retrieve first letter of key --> '*'
Retrieve second letter of key --> 'b' //if first is a wildcard, get a second
Retrieve first letter of input --> 'y'
Does '*' == 'y'  --> false
Does 'b' == 'y'  --> false
Is '*' a wildcard --> true
If true, call function with remaining key & input

Enter Function with key='*b?c' and input='xbwc'
Retrieve first letter of key --> '*'
Retrieve second letter of key --> 'b' //if first is a wildcard, get a second
Retrieve first letter of input --> 'x'
Does '*' == 'x'  --> false
Does 'b' == 'x'  --> false
Is '*' a wildcard --> true
If true, call function with remaining key & input

Enter Function with key='*b?c' and input='bwc'
Retrieve first letter of key --> '*'
Retrieve second letter of key --> 'b' //if first is a wildcard, get a second
Retrieve first letter of input --> 'b'
Does '*' == 'x'  --> false
Does 'b' == 'b'  --> true
If true, call function with remaining key & input //when you match the letter after the wildcard you send the key with both the wildcard and matching letter removed
//Also, a key note here, in more complex cases, you may need to keep iterating on the wildcard even after the first match for the following letter is found

Enter Function with key='?c' and input='wc'
Retrieve first letter of key --> '?'
Retrieve first letter of input --> 'w'
If true, call function with remaining key & input // I've defined ? to match any single character, it just goes through with removing the a letter from key and input

Enter Function with key='c' and input='c'
Retrieve first letter of key --> 'c'
Retrieve first letter of input --> 'c'
Does 'c' == 'c'  --> true
If true, call function with remaining key & input

Enter Function with key='' and input=''
Return true

抱歉这个巨大的例子,但是为了真正理解递归,我认为这很重要。你会注意到,我的“输入”变得更小,每一步都让我更接近解决我的问题。这就是递归背后的整个想法。

现在通过递归进行排序。我更喜欢bubble sort,所以这就是我今天选择在这里展示的内容。冒泡排序很整洁,因为它是通过递归和迭代实现的。这是我的例子:

public class test {
    public static void main (String[] args) {
        int[] a = {1,4,2,2,1};
        a = sort(a);
        for (int i = 0; i < a.length; i++) {
            System.out.println("" + a[i]);
        }
    }
    public static int[] sort(int[] a) {
        int temp;
        boolean sorted = true;
        int[] ret = a;
        for (int i = 0; i < a.length - 1; i++) {
            if (ret[i] > ret[i+1]) {
                temp = ret[i];
                ret[i] = ret[i+1];
                ret[i+1] = temp;
                sorted = false;
            }
        }
        if (sorted) {
            return ret;
        } else {
            return sort(ret);
        }
    }
}

让我们来看看这里发生了什么:

  1. 我们从1,4,2,2,1开始使用我们的数组。
  2. 第一次通过排序功能后,我们最终得到1,2,2,1,4
  3. 我们更改了排序(所以我们没有排序),我们必须再次调用该函数。
  4. 我们第二次1,2,2,1,4,我们最终得到1,2,1,2,4
  5. 我们更改了排序(所以我们没有排序),我们必须再次调用该函数。
  6. 我们第三次1,2,1,2,4,我们最终得到1,1,2,2,4
  7. 我们更改了排序(所以我们没有排序),我们必须再次调用该函数。
  8. 我们第四次1,1,2,2,4,我们最终得到1,1,2,2,4
  9. 我们没有改变顺序(我们已经排序了!)。返回已排序的数组。
  10. 我希望这能帮助你理解递归。如果您想进一步澄清我提到的内容,请随时写评论。