iOS编程——Swift实现常见的递归算法1

今天用swift实现了一些常见的递归函数,给大家分享下:


1.n的阶乘,这个就不赘述了


代码:

    func recursive(n: UInt) -> UInt{
        if n == 0{
            return 1
        } else {
            var result = n * recursive(n - 1)
            return result
        }
    }

测试代码:5的阶乘

        var result = recursive(5)
        println("result = \(result)")

结果:

result = 120


2.汉诺塔,源于印度的一种益智玩具,其实跟咱们中国的九连环玩法是一个道理的,题如下:
《iOS编程——Swift实现常见的递归算法1》 



分析: 假设珠子从上到下依次为a,b,c,d….   辅助杆为2号杆
1个珠子:把a从1号杆直接移到3号杆;
2个珠子:先把a从1号杆移到2号杆,然后把b移到3号杆,再把a移到3号杆;
3个珠子:先把ab从1号杆移到2号杆(要借助3号杆,因为只能大珠子在下),然后把c从1号杆移到3号杆,然后把ab从2号杆移到3号杆(借助1号杆)
n个珠子:先把n-1从1号移到2号(要借助3号,因为只能大珠子在下),然后把n从1号杆移到3号杆,然后把n-1从2号杆移到3号杆(要借助1号杆)


明显这也是一个递归问题
代码:


声明所需的总步数:

    var step = 0

每移动一个珠子调用的函数:

    func move(index: UInt, from: String, to: String){
        step++
        println("第\(step)步:把第\(index)个珠子从\(from)号杆移到\(to)号杆。")
    }

汉诺塔函数:

    func hanoi(n: UInt, from: String, to: String, depend: String){
        if n == 1{
            move(1, from: from, to: to)
        } else{
            hanoi(n - 1, from: from, to: depend, depend: to)
            move(n, from: from, to: to)
            hanoi(n - 1, from: depend, to: to, depend: from)
        }
    }

测试代码:上题中有3个珠子,n为3,from为1号杆,to为3号杆,借助杆depend为2号杆

        hanoi(3, from: "1", to: "3", depend: "2")

结果:

第1步:把第1个珠子从1号杆移到3号杆。
第2步:把第2个珠子从1号杆移到2号杆。
第3步:把第1个珠子从3号杆移到2号杆。
第4步:把第3个珠子从1号杆移到3号杆。
第5步:把第1个珠子从2号杆移到1号杆。
第6步:把第2个珠子从2号杆移到3号杆。
第7步:把第1个珠子从1号杆移到3号杆。





3.全序列: 总共有n的阶乘个排列


分析:

    1.试想,我们只有两个数字:12.要对它进行全排列,第一种方式就是12本身,第二种,将12交换,变为21即可。这提示了我们一种交换的思路。

    2.但这概括的并不全面。试想,我们要对123进行全排列。我们可以采用将1固定,“23”进行全排列,将“2”固定,对“13”进行全排列。将“3”固定,对“12”进行全排列。

    这其实就是首部为”1“,然后是“2”,然后是“3”,不就是第二位后边的数依次和第一位进行交换么?这是典型的递归的思路。

    3.但是,这样也不全面,我们每次交换要将排列恢复成为原始的“123”,因为这个算法求排列的时候,前后并没有依赖性,其参考物只有“123”这个原始的第一个排列。否则,如果我们不恢复的话,就会出现,虽然数量与正确解法相同,但是会有重复的排列的现象。


代码:

交换函数swap

    //传入参数如果需要修改,需要添加inout
    func swap<T>(inout array: [T], index1: Int, index2: Int){
        var temp = array[index1]
        array[index1] = array[index2]
        array[index2] = temp
    }

全序列排序函数,传入参数为数组,开始位置和结束位置

    func allRange<T>(inout array: [T], start: Int, end: Int){
        
        //start end相等表示替换到了最后一个值,排序完成
        if start == end{
            println(array)
        } else{
            for (var i = start; i <= end; i++){
                //先用第一个数跟后面的交换
                swap(&array, index1: start, index2: i)
                //递归第一个数后面的
                allRange(&array, start: start + 1 , end: end)
                //还原为初始数组
                swap(&array, index1: start, index2: i)
            }
        }
    }

测试代码:数组为[“1”, “2”, “3”, “4”]

        var stringArray = ["1", "2", "3", "4"];
        allRange(&stringArray, start: 0, end: stringArray.count - 1)

4.斐波那契数列 (一个数等于它前面两个数的和)

一般而言,兔子在出生两个月后,就有繁殖能力,一对兔子每个月能生出一对小兔子来。如果所有兔子都不死,那么n个月以后可以繁殖多少对兔子?

    

分析如下:(记得算上老兔子每个月都能生小兔子)

   第一个月小兔子没有繁殖能力,所以还是一对;

    两个月后,生下一对小兔子,总数共有两对;

    三个月以后,老兔子又生下一对,因为小兔子还没有繁殖能力,总数共是三对;

    如此类推:11235813。。。

《iOS编程——Swift实现常见的递归算法1》


代码:

    func fib(#month: UInt) -> UInt{
        
        if month == 0{
            return 1
        } else if month == 1{
            return 1
        } else {
            var cout = fib(month: month - 1) + fib(month: month - 2)
            return cout
        }
    }




测试代码:12个月会有多少只兔子?

        var allCount = fib(month: 12)
        println("总共有兔子\(allCount)对。")


今天先到此为止,稍后我会继续写下去,有写的不对的地方请大家多多指出,大家共同进步,谢谢。




    原文作者:递归算法
    原文地址: https://blog.csdn.net/wc455287693/article/details/47025909
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞