Java:递归 - 用递归实现冒泡,选择排序

本文通过递归方式详细介绍了如何实现冒泡排序和选择排序。在递归冒泡排序中,解释了为何参数loop看似递增实则递减,并探讨了递归函数的返回值问题及其解决方案。同时,对于递归选择排序,提供了实现思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

不能用for/while,使用递归实现冒泡

和for/while一样,只是迭代的参数都要写成传参否则会丢失状态

下面的代码loop表示每次的冒泡遍历次数,执行时依次递减。

1. 递归冒泡代码:

/*
   * a recursive way of bubbleSort
   *@param arr
   *the input array of int
   *@param i
   *the current index of arr
   *@param loop
   *maximum loops needed for each traverse,started at arr.length-1
   *,ended at 1
   *@param swap
   *an indicator which shall be false when starting the sort
   *, showing if a swap happens
   */
  public static void bubbleSort(int[] arr, int i, int loop, boolean swap){
    if(loop>=1){
      if(i<loop){
        if (arr[i]>arr[i+1]){
          int tmp =arr[i+1];
          arr[i+1]= arr[i];
          arr[i] = tmp;
          swap = true;
        }
        //inner loop
        bubbleSort(arr,++i,loop,swap);
      }else{
        if (!swap){
          return;
        }
        //reset i and swap,redo outer loop with one less time
        bubbleSort(arr,0,--loop,false);
        System.out.println(loop);
      }
    }
  }

测试:

int[] arr = {41,21,5,78,13,12,41,1,4,3,4,7,9,9,10,84,72,17,85,100,1,66,23};
bubbleSort(arr,0,arr.length-1,false);
System.out.println("/n"+Arrays.toString(arr));

输出:

3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
[1, 1, 3, 4, 4, 5, 7, 9, 9, 10, 12, 13, 17, 21, 23, 41, 41, 66, 72, 78, 84, 85, 100]

思考:输出看起来loop是递增的,但是按照写的代码顺序执行,参数loop不应该是递减的么?

bubbleSort(arr,0,--loop,false);
System.out.println(loop);

可以这样思考,虚拟机栈执行bubbleSort(arr,0,–loop,false)时,后面的执行语句都在栈底中断未执行,此时递归函数又压入了一系列执行语句…操作栈按先进后出的方式执行,当然最后输出的是最先压入未被执行的语句。

总结:在递归函数方法体内,出现在递归函数后面的语句会倒序输出结果。

引申问题:递归函数若有返回值,会返回第一次递归函数的。

由于递归函数最后一次递归的返回值会被之前的不断覆盖,我们得到的往往不是想要的返回值。

比如我们想要用递归累加一个数a,loop次:

  public static int accumulation(int a, int loop){
    if(loop>0){
      a = a*2;
      accumulation(a,--loop);
    }else{
      return a;
    }
    return a;
  }

上面的函数是错误的,让a=1,不管参数loop怎么变,返回值总是2
怎么办呢?
其实就是找个对象存这个数,可以是基本类型,也可以是引用类,但作用域一定是大于函数传参的。

解决方案:递归函数若有返回值,该返回值为成员(全局)变量

  public class Accumulation{
  	 private static int result = 0;
	
	 public static int accumulation(int a, int loop){
    	 if(loop>0){
     		a = a*2;
     		accumulation(a,--loop);
     	}else{
     		result = a;
      		return result;
    	}
    	return result;
  	}
  }

a=1,loop=10,上面的函数返回就是1024了。

当然,如果只是测试函数输入输出,也可以main函数内另设静态引用变量比如一个Collection实现类,函数增加这个传参去存这个递归输出(Object和Integer等包装类不行)。

2. 递归选择排序代码:

有了递归冒泡的经验,选择就写得顺畅多了:
选择排序递归需要传递的参数:待排数组,遍历起始下标,遍历次数,最小值下标

  public static void selectSort(int arr[],int i,int loop,int min){
    if(loop>0){
      if(i<arr.length-1){
        if(arr[min]>arr[i+1]){
          min = i+1;
        }
        selectSort(arr,++i,loop,min);
      }else{
        i = arr.length-loop-1;
        int tmp = arr[i];
        arr[i] = arr[min];
        arr[min] = tmp;
        selectSort(arr,++i,--loop,i);
      }
    }
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值