试设计递归算法dfs traverse_二叉树与分治算法

5399396e5cd639f5dd26de074366de48.png

二叉树

问题1,如果一颗二叉树,有N个节点,那么它的高度用Big O表示是多少呢?

答案是O(N),因为链表也是一颗独特的二叉树 1 -> 2 -> 3 -> 4 -> 5

二叉树的三种遍历

对于二叉树遍历,它的深度优先搜索DFS,有三种遍历策略,是以遍历root的三种策略命名的

  1. 前序遍历(左右)
  2. 中序遍历(左右)
  3. 后续遍历(左右)

具体遍历,参考之前的文章《树的三种DFS策略(前序、中序、后序)遍历》

递归思想

能否使用递归实现,有一个非常重要的判断标准,就是递归的深度。

现代Linux操作系统,stack大小也只有8M,可以通过ulimit -a查看

不论内存有多大,对于程序来说,有个很小的递归上线,深度大概10K左右。

python更小,只有1K层,左右。有兴趣可以文末链接

递归的三要素

  1. 递归的定义
  2. 递归的拆解
  3. 递归的出口

递归的技巧

对于不能返回多个值的语言,可以定一个类,封装多个值返回

时间复杂度分析

通过O(N)的时间,把N的问题变成N/2的问题, 典型的是归并排序

  T(N) = O(N) + 2 * T(N/2)       = O(N) + 2 * (O(N/2) + 2 * T(N/4)) = O(N) + O(N) + 4 * T(N / 4)        = O(N) + O(N) + 4 * (O(N/4) + 2 * T(N/8)) = O(N) + O(N) + O(N) + 8 * T(N/8)       ...       = O(N) + O(N) + O(N) ... + N * (N/ N) = O(N) + O(N) + O(N) + ... + N * O(1)       = O(N * logN) + O(N)       = O(N * logN)

通过O(1)的时间,把N的问题变成N/2的问题, 典型是二叉树上的分治算法

  T(N) = O(1) + 2 * T(N/2)       = O(1) + 2 * (O(1) + 2 * T(N/4)) = O(1) + 2 * O(1) + 4 * T(N / 4)        = O(1) + 2 * (N) + 4 * (O(1) + 2 * T(N/8)) = O(1) + 2 * O(1) + 4 * O(1) + 8 * T(N/8)       ...       = O(1) + 2 * O(1) + 4 * O(1) ... + N * (N/ N) = (2 ^ 0 + 2 ^ 1 + 2 ^ 2 + ... + 2 ^ (logN - 1)) * O(1) + N * O(1)       = (1 + 2 + 4 + ... + N) * O(1) + N * O(1)       = (2N - 1) * O(1) + N * O(1) = O(3N - 1)       = O(N)

递归的两种方式

问题:给出一棵二叉树,返回其节点值的前序遍历

分治算法(Divide and Conquer)

特点:

  1. 结果 = 当前值 + 左子树返回值 + 右子树返回值
  2. Bottom-up
def preorderTraversal(self, root):    return self.traverse(root)    def traverse(self, root): # 递归的定义    if root is None:        return [] # 递归的出口          results = []     # 递归的拆解-Start    lefts = self.traverse(root.left)    rights = self.traverse(root.right)        results.append(root.val)    results.extend(lefts)    results.extend(rights)        return results    # 递归的拆解-End

遍历算法(Traverse)

特点:

  1. 结果 = 一个全局变量results,从根一层层搜集结果
  2. Top-down
def preorderTraversal(self, root):    results = []    self.traverse(root, results)    return results    def traverse(self, root, results): # 递归的定义    if root is None:        return # 递归的出口    # 递归的拆解-Start    results.append(root.val)    self.traverse(root.left, results)    self.traverse(root.right, results)    # 递归的拆解-End

二叉搜索树BST

问题2, 如果一颗二叉搜索树(BST), 有N个节点,那么它的高度用Big O表示是多少呢?

没有提到平衡,BST的高度也有可能是O(N), 例如下图高度=N/2

常用的平衡二叉树有红黑树

      4    3   5  2       61           7

二叉搜索树BST特点

  1. 左子树都小于root的值(不推荐把等于放在这里)
  2. 右子树都大于root的值(也可以等于)

BST必要不充分特点

对于BST,进行中序遍历,结果是一个不下降序列

参考:

《程序语言递归深度》 https://rosettacode.org/wiki/Findlimitof_recursion

--End--

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值