<<大话数据结构>>第4章-栈与队列

本文原创文章,转载注明出处,博客地址 https://segmentfault.com/u/to... 第一时间看后续精彩文章。以为好的话,顺手分享到朋友圈吧,感谢支持。segmentfault

栈的应用-递归

递归函数定义

咱们把一个直接调用本身或经过一系列的调用语句间接地调用本身的函数,称作递归函数数组

迭代和递归的区别

迭代代码,实现斐波那契额数列

//版本1:迭代版本
func Fbi1(i int) int {

    switch i {
    case 0:
        return 0
    case 1:
        return 1
    default:
        arr := make([]int, i+1, i+1)
        arr[0] = 0
        arr[1] = 1
        for j := 2; j <= i; j++ {
            arr[j] = arr[j-1] + arr[j-2]
        }
        return arr[i]
    }
}

递归代码

//版本2:递归版本
func Fbi2(i int) int {
    switch i {
    case 0:
        return 0
    case 1:
        return 1
    default:
        //递归调用
        return Fbi2(i-1) + Fbi2(i-2)
    }
}
  1. 迭代使用的是循环结构,递归使用的是选择结构
  2. 递归使程序的结构更清晰、更简洁、更容易理解,从而减小读懂代码的时间
  3. 可是大量的递归调用会创建函数的副本,会耗费大量的时间和内存,迭代则不须要反复调用函数和占用额外的内存

视不一样状况选择不一样的代码实现方式函数

编译器使用栈实现递归

递归过程分为前行和退回阶段,编译器使用栈实现递归;前行阶段,每一层递归,函数的局部变量、参数值以及返回地址都被压入栈,在退回阶段,位于栈顶的局部变量、参数值和返回地址被弹出,恢复了调用的状态code

队列的定义

  1. 队列(Queue)是只容许在一端进行插入操做,而在另外一端进行删除操做的线性表
  2. 先进先出(First In First Out),简称FIFO

循环队列

咱们把队列的这种头尾相接的顺序存储结构称为循环队列递归

链队列

队列的链式存储结构,就是线性表的单链表,只能尾进头出队列

循环队列与链队列比较

  1. 循环队列是事先申请好空间,使用期间不释放;链队列,每次申请和释放阶段存在一些时间开销
  2. 循环队列必须有一个固定长度,有存储元素个数和空间浪费的问题;空间上,链队列更加灵活

总结:能够肯定队列长度最大值的状况下,建议用循环队列,若是没法预估队列长度,则用链队列内存

总结回顾

  • 对于栈来讲,若是两个相同数据类型的栈,则能够用数组的两端做栈底来让两个栈共享数据,能够最大化利用数组的空间
  • 循环队列使得队头和队尾能够在数组中循环变化,避免数组插入数据和删除时须要移动数据的时间损耗,使得原本插入和删除是O(n)的时间复杂度变成O(1)
相关文章
相关标签/搜索