数据结构之递归实现

1. 概念解释:

程序调用自身的编程技巧称为递归( recursion)。递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。

2. 递归条件

边界条件 
递归前进段 
递归返回段 
当边界条件不满足时,递归前进;当边界条件满足时,递归返回。

3. 实例讲解

1) 1,1,2,3,5,8… 斐波拉契数列
 * 0,1,1,2,3,5,8
 * 规律后一个数是前两个数的和 n>=3
 * @param n
 * @return
 */
public static long getFibonacciNumber(long n) throws Exception {
    if(n <= 0){
        throw new Exception("数字不合法");
    }
    if(n == 1){
        return 0;
    }else if(n == 2){
        return 1;
    }
    return getFibonacciNumber(n-1) + getFibonacciNumber(n- 2);
}
2) 1, 3, 6, 10, 15, 21…
/**
 * 1 3 6 10 15
 * 规律是后一个数等于第n个数n+它的前一个数的和,当n > 1时候
 * @param n
 * @return
 */
 public static int getTriangleNumber(int n){
    if(n <= 0){
        return -1;
    }else if(n == 1){
        return 1;
    }else{
        return n + getTriangleNumber(n - 1);
    }
 }
3) 汉诺塔问题

古代有一个梵塔,塔内有三个座A、B、C,A座上有64个盘子,盘子大小不等,大的在下,小的在上。有一个和尚想把这64个盘子从A座移到C座,但每次只能允许移动一个盘子,并且在移动过程中,3个座上的盘子始终保持大盘在下,小盘在上。在移动过程中可以利用B座。


/**
 *
 * @param n 移动盘子数
 * @param from 起始塔座
 * @param mid  中间塔座
 * @param to   目标塔座
 */
public static void moveDish(int n,String from,String mid,String to){

    if(n == 1){
        System.out.println("盘子1从"+from+"塔座移动到"+to+"塔座");
    }else{
        moveDish(n - 1,from,to,mid);
        System.out.println("盘子"+ n +",从"+from+"塔座移动到" + to + "塔座");
        moveDish(n-1,mid,from,to);
    }
}
4) 数组求和 比如 arr[] = [2,6,8];

private int sum(int[] arr,int l){
    if(l == arr.length)
        return 0;
    return arr[l] + sum(arr,l+1);
}
5) 删除链表中等于给定值 val 的所有节点。

示例:

输入: 1->2->6->3->4->5->6, val = 6
输出: 1->2->3->4->5

1. 递归方式实现

public ListNode removeElements3(ListNode head, int val) {
    if(head == null)
        return null;
    //1->2->3->4
    head.next = removeElements3(head.next, val);
    return head.val == val ? head.next : head;
}

2. 带虚拟头节点方式实现

public ListNode removeElements2(ListNode head, int val) {

    //构建一个虚拟头结点
    ListNode dummyHead = new ListNode(-1);
    dummyHead.next = head;
    //1->2->3->4
    ListNode cur = dummyHead;
    while (cur.next != null){
        if(cur.next.val == val){
            ListNode delNode = cur.next;
            cur.next = delNode.next;
            delNode.next = null;
        }else{
            cur = cur.next;
        }
    }
    //这里注意需要返回dummyHead.next
    return dummyHead.next;
}

3. 不带虚拟头节点方式实现

public ListNode removeElements(ListNode head, int val) {

    while(head != null && head.val == val){
        head = head.next;
    }

    //1->2->3->4
    ListNode cur = head;
    while (cur != null && cur.next != null){
        if(cur.next.val == val){
            ListNode delNode = cur.next;
            cur.next = delNode.next;
            delNode.next = null;
        }else{
            cur = cur.next;
        }
    }

    return head;
}

4.联系方式

QQ:1509815887
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值