理解递归(在冒泡排序中应用它)

时间:2010-08-15 06:26:59

标签: recursion

我试图弄清楚如何在程序中使用递归。我理解递归如何在像“阶乘”这样的经典例子中起作用,但我不确定如何将它应用于我自己......

我开始将迭代冒泡排序代码转换为递归代码...... 我在网上搜索了同样的内容......但是我找不到令人信服的解决方案/解释..

冒泡排序的示例迭代代码是:

ARR [N] - GT;包含要排序的元素(1..n)的数组

for(i:1 to n)  
    for(j:1 to n-1)  
      if(arr[j+1]>arr[j])  
         swap(arr[j+1],arr[j]);

如果有人可以暗示如何去做,会感到很有帮助......

16 个答案:

答案 0 :(得分:8)

public void sort(int[] arr, int first, int last){

    if(first < last && last > 0){
        if(arr[first] > arr[first+1]){
            int temp = arr[first];
            arr[first] = arr[first+1];
            arr[first+1] = temp;
        }
        sort(arr, first+1, last);
        sort(arr, first, last-1);
    }
    else
        return;
}

迟了2年,但也许对某人有用

答案 1 :(得分:3)

我不确定Bubblesort是否是练习递归的好算法。将它转换为递归会非常难看,因为它是一个嵌套循环。它看起来像这样:

function pass(i,j,n,arr)
{
  if(arr[i]>arr(j))
    swap(arr[i],arr[j]);

  if(j==n)
  {
    j=0;
    i=i+1;
  }
  if(i==n+1)
    return arr;

  return pass(i,j+1,n,arr);
}

循环相同,只需更长时间定义,使用更多内存。

您应该尝试实现QuickSort。它需要递归,并且在大多数情况下它比BubbleSort快得多。大多数平台已经实现了它,所以你不必自己编写它,但是知道它是如何工作的很好,它有助于理解递归。

如果您愿意,也可以尝试使用递归解决此问题:
你有一个数字表NxM和一个起始坐标(位置)。这是^旅行者^的位置。旅行者可以前往相邻的小区(右,左,上或下),其数量小于他所在的小区。您必须编写一个程序来计算旅行者在这些约束条件下可以通过的最长路径。使用random来生成数组,或手动生成它。

答案 2 :(得分:2)

递归是一种基于归纳证明的设计技术。考虑一个或多个基本(简单)案例来解决您的问题,以及一种或多种方法将问题移近基本案例问题。然后,在算法的每一步,您要么认识到完成(并适当地处理基本情况),要使问题稍微接近基础案例。

冒泡排序只是观察的一个应用,即排序的数组按顺序具有所有相邻的元素对。递归定义,它的工作方式如下:

  1. 基本情况:有一个大小为1(或更小)的数组要排序。当然,它已经分类了。
  2. 感应案例:将最大元素冒泡到阵列顶部。现在有一个单元素较小的数组要进行排序,这样做。
  3. 您可以用您选择的编程语言编写这个想法,然后进行冒泡排序。哦,但你必须定义“泡出最大元素”意味着什么。那么,这是递归设计的另一个机会。不过,我想你明白了。

    更快的排序主要基于对如何在较少工作中更接近目标的观察。例如,快速排序依赖于以下概念:如果对数组进行排序,则存在一些元素P,并且所有小于P的元素都是P的左边,而所有超过P的元素都是P的右边。如果你可以在数组上建立该属性,并选择P,那么你可以在每一步将问题大致减少一半,而不是简单地用一个。

答案 3 :(得分:1)

这是javascript中的递归bubblesort:

function bubbleSortRecursive(array, index1, index2) {
    //define index1 and index2 if user doesn't pass them in
    index1 = typeof index1 == "undefined" ? 0 : index1;
    index2 = typeof index2 == "undefined" ? array.length : index2;

    if (index1 > index2) {
        return array;
    } else if (index1 == index2 - 1) {
        return bubbleSortRecursive(array, 0, index2 - 1);
    } else if (array[index1] > array[index1 + 1]) {
        //bubble the larger value towards the end of the array
        var temp = array[index1];
        array[index1] = array[index1 + 1];
        array[index1+1] = temp;
        return bubbleSortRecursive(array, index1 + 1, index2);
    } else {
        return bubbleSortRecursive(array, index1 + 1, index2);
    }
}

该功能内的前2行允许用户拨打bubbleSortRecursive(array),该功能将定义index1index2

答案 4 :(得分:1)

以下是使用recursively对数组Bubble-Sort进行排序的另一种简单方法。

static void recursive_bubble_sort(int[] Arr, int l)
{// 'Arr' is the array where 'l' is the length of the array

    if (l == 0) {
       return;
    }

    for (int j = 0; j < l - 1; j++) {
        if (Arr[j] > Arr[j + 1]) {
            swap(Arr[j], Arr[j + 1]);
        }
    }

    recursive_bubble_sort(Arr, l - 1);
}

对于递归解决方案,必须更新长度,以便函数始终与数组中的其余项一起使用。

答案 5 :(得分:0)

因为我发现这个问题是第一个例子之一,我想提供另一种方法来进行递归,而不需要额外的参数:

function bubblesort (input: some integer array):
  if input is empty:
    return input
  else:
    do one bubble sort run for input
    subarray = bubblesort(unsorted part of input)
    return subarray append sorted part of input

通过这种方式,我们将为每次调用分段整理整个数组。

为什么会这样?因为每个冒泡排序运行,我们将至少将最大元素放到最右边的索引中 我们知道直到最后一次交换的所有元素都处于未知状态,所有元素都在最后一次交换之后被排序。

可以在那里找到Java中的实现(数组/列表参数修改/不):https://codereview.stackexchange.com/questions/24006/recursive-bubble-sort-in-java/24133#24133

答案 6 :(得分:0)

#include <stdio.h>
#include <stdlib.h>

void sort(int *arr, int first, int last){

    if(first < last && last > 0){
        if(arr[first] > arr[first+1]){
            int temp = arr[first];
            arr[first] = arr[first+1];
            arr[first+1] = temp;
        }
        sort(arr, first+1, last);
        sort(arr, first, last-1);
    }
    else
        return;
}
int main(void) {

    int data [] = { 3, 5 , 6, 2, 1, 10, 4};
    int len = sizeof(data)/sizeof(int);
    int i = 0;
    sort(data,0,len-1);
    for(i=0;i<len;i++)
        printf("%d ",data[i]);

    return EXIT_SUCCESS;
}

答案 7 :(得分:0)

这是我的答案。它与VladimFromUa的答案(冒泡排序的递归变体)基本相同,但是只有在检测到数组被重新排序时才执行额外的运行,而不是执行固定数量的运行。在上一次运行中。

下面是另外两个不同之处:

1.通过在递归调用中偏移数组的地址来删除索引数组中起始点的参数。 2.检查&#34; if(first&lt; last&amp;&amp;&last; 0&gt; 0)&#34;在弗拉德或&#34;如果(--p_length == 1)&#34;在我的代码中,在递归调用之前更好地执行,这将导致数组长度为1,因为它对堆栈的调用少了一次。

为方便起见,我添加了一些代码来从命令行读取输入并打印未排序和排序的数组。

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

typedef enum { FALSE, TRUE } boolean_t;

void
swap_int(int *a, int *b) {

    int temp = *a;

    *a = *b;
    *b = temp;
}

boolean_t
sort_array(int p_array[], int p_length) {

    boolean_t result;

    if (p_array[0] > p_array[1]) {
        swap_int(p_array, p_array + 1);
        result = TRUE;
    } else {
        result = FALSE;
    }

    if (--p_length == 1) {
        return result;
    }

    result |= sort_array(p_array + 1, p_length);

    if (result) {
        sort_array(p_array, p_length);
    }

    return result;
}

void
print_array_int(int p_array[], int p_length) {

    int n;

    for (n = 0; n < p_length - 1; n++) {
        printf("%d, ", p_array[n]);
    }

    printf("%d\n", p_array[n]);
}

int
main(int argc, char **argv) {

    int *array;
    int array_length = argc - 1;
    int n;

    array = malloc(array_length * sizeof(*array));

    for (n = 0; n < array_length; n++) {
        sscanf(argv[n + 1], "%d", array + n);
    }

    printf("\nUnsorted array:\n");
    print_array_int(array, array_length);
    sort_array(array, array_length);
    printf("\nSorted array:\n");
    print_array_int(array, array_length);

return 0;
}

答案 8 :(得分:0)

这种解决方案怎么样:

package recursive.bubble;

public class RecursiveBubble {

    public static boolean sort(int []arr){
        if(!bubbleSorted(arr, 0)){
            return sort(arr);
        }
        return true;
    }
    public static boolean bubbleSorted(int []a,int index){    
        if(a.length<2){
            return true;
        }
        if(index==a.length-2){
            if(a[index+1]<a[index]){
                swap(a,index,index+1);
                return false;
            }
            return true;
        }
        boolean isSorted=false;
        if(a[index]<=a[index+1]){
            isSorted=true;
        }else{
            swap(a,index,index+1);
        }
        return isSorted && bubbleSorted(a, index+1);
    }
    private static void swap(int[] a, int index, int i) {
        int tmp=a[index];
        a[index]=a[i];
        a[i]=tmp;
    }
    public static void main(String[] args) {
        int []a={4,5,6,2,2,3,9,1,8};
        if(sort(a))
        for (int i = 0; i < a.length; i++) {
            System.out.println(a[i]);
        }
    }
}

答案 9 :(得分:0)

def bubble_sort(l):
    for i, num in enumerate(l):
        try:
            if l[i+1] < num:
                l[i] = l[i+1]
                l[i+1] = num
                bubble_sort(l)
        except IndexError:
            pass
    return l

答案 10 :(得分:0)

#include <stdio.h>
void bubbleSort(int *,int ,int ,int );
void swap(int *, int *);
void printArray(int *,int);

int main()
{
    int n,c;

    printf("Enter number of elements\n");
    scanf("%d", &n);

    int array[n];

    printf("Enter %d integers\n", n);

    for (c = 0; c < n; c++)
        scanf("%d", &array[c]);

    printf("Before Sorting:\n");
    printArray(array,n);

    bubbleSort(array,0,0,n);

    printf("After Soring:\n");
    printArray(array,n);

 }

 void bubbleSort(int *array,int i,int j,int n)
 {
     if(j==n-i-1)
     {
         i = i+1;
         j = 0;
     }
     if(i==n-1)
         return;

     if(array[j]>array[j+1])
         swap(&array[j],&array[j+1]);

     j++;
     bubbleSort(array,i,j,n);
 }

 void swap(int *p,int *q)
 {
     int t = *q  ;
     *q = *p;
     *p = t;
 }

 void printArray(int *array,int n)
 {
     int c=0;
     for (c = 0; c < n; c++)
        printf("%d ", array[c]);
    printf("\n");
 }

答案 11 :(得分:0)

这是scala功能代码。一切都是不变的。这是尾递归。所以堆栈应该没问题

def sort(initial: List[Int], result: List[Int] = Nil): List[Int] = {

  def getBiggest(list: List[Int], rest: List[Int] = Nil): (List[Int], Int) = list match {
    case x1 :: x2 :: tail =>
      if(x1 > x2)
        getBiggest(x1 :: tail, x2 :: rest)
      else
        getBiggest(x2 :: tail, x1 :: rest)
    case x :: Nil => (rest, x)
  }

  initial match {
    case _ :: _ :: _ =>
      getBiggest(initial) match {
        case (rest, biggest) => sort(rest, biggest :: result)
      }
    case x :: Nil => x :: result
    case Nil => Nil
  }
}

答案 12 :(得分:0)

这是另一个带有es6 / 7语法的javascript递归版本,例如默认参数参数:

let unsorted = [4, 2, 4, 99, 1, 1, 5];

const bubSort = (arr, end = 0) => {
  // base case
  if (end >= arr.length) {
    return arr;
  }

  // bubble sort, goes through once
  for (let i = 0; i < arr.length - 1; i++) {
    if (arr[i] > arr[i + 1]) {
      // swap!
      let hold = arr[i + 1];
      arr[i + 1] = arr[i];
      arr[i] = hold;
    }
  }

  // down the rabbit hole; updating `end` is a small optimization
  return bubSort(arr, ++end);
}

const sorted = bubSort(unsorted);
console.log(sorted);

答案 13 :(得分:0)

  if ("serviceWorker" in navigator) {
    navigator.serviceWorker.ready
      .then(registration => {
        registration.unregister();
      })
      .catch(error => console.log("ServiceWorker Warning: ", error));
  }

source from

答案 14 :(得分:0)

Golang:

// BubbleSortRecursive ...
func BubbleSortRecursive(data []int) {

    i := 0
    max := len(data)

    bubbleSortRecursive(data, i, max)
}

func bubbleSortRecursive(data []int, i, max int) {

    fmt.Printf("data = %v, i = %v, max = %v\n", data, i, max)

    if i == max-1 {
        max--
        i = 0
    }

    if i < max-1 {
        if data[i] > data[i+1] {
            data[i], data[i+1] = data[i+1], data[i]
        }
        bubbleSortRecursive(data, i+1, max)
    }
}

答案 15 :(得分:-2)

import tkinter as tk
from tkinter import ttk

root = tk.Tk()

# Base size
normal_width = 1920
normal_height = 1080

# Get screen size
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()

# Get percentage of screen size from Base size
percentage_width = screen_width / (normal_width / 100)
percentage_height = screen_height / (normal_height / 100)

# Make a scaling factor, this is bases on average percentage from
# width and height.
scale_factor = ((percentage_width + percentage_height) / 2) / 100

# Set the fontsize based on scale_factor,
# if the fontsize is less than minimum_size
# it is set to the minimum size
fontsize = int(14 * scale_factor)
minimum_size = 8
if fontsize < minimum_size:
    fontsize = minimum_size

# Create a style and configure for ttk.Button widget
default_style = ttk.Style()
default_style.configure('New.TButton', font=("Helvetica", fontsize))

frame = ttk.Frame(root)
button = ttk.Button(frame, text="Test", style='New.TButton')

frame.grid(column=0, row=0)
button.grid(column=0, row=0)

root.mainloop()