证明中序遍历O(n)

算法导论12.1 什么是二叉搜索树



二叉搜索树应满足的性质

设x是二叉搜索树中的一个结点。如果y是x左子树中的一个结点,那么y.key <= x.key。如果y是右子树中的一个结点,那么y.key >= y.key。(这里是可以取等于的)

例如:

     3
    / \   2   4  / \  1   2 

可以容许相同的数。

中序遍历,因为根的遍历在左右子树之间,顾名中序,也就是左根右。

如上,中序遍历应该是:12234

那么后续遍历就是左右根:12243

前序遍历就是根左右:32124



可以给出中序遍历的递归式伪码:

inorderTree(x)
    if (x != NIL)
        inorderTree(x.left);
        print x.key;
        inorderTree(x.right);

现在来证明中序遍历是O(n)的。

T(n)表示n个节点中序遍历所需要时间。那么T(0) = c,c为常数,因为要判断x是否为NIL的常数时间。

首先,最起码要遍历n个结点,所以下限为Ω(n)。只要再证明上限O(n)那么它就是O(n)的复杂度了。

以下证上限:

因为有左右子树,设左子树有k个结点,那么右子树就有n-k-1个。

就有了递推式:

T(n) <= T(k) + T(n-k-1) + d

d类似常数c,是其他的常数操作。因为加了d,所以就用小于等于。

那么证明T(n) = O(n)是等价于证明如下式子成立的:

T(n) <= (c+d)*n + c

T(0) = c 显然成立,数学归纳法:

可以把红色部分的式子代入到前面那个式子的右边把右边的T(k) 和 T(n-k-1)替换掉就有了

T(n) <= ((c+d)*k + c) + ((c+d)*(n-k-1)) + c) + d = (c + d)*n + c

真神奇,可见红色部分成立,那么T(n)上限就是O(n)。

综合上下限,所以T(n)的复杂度是O(n)。

时间: 2024-12-12 21:38:13

证明中序遍历O(n)的相关文章

算法学习 - 表达树的建立(后缀表达式法),树的先序遍历,中序遍历,后序遍历

表达树就是根据后缀表达式来建立一个二叉树. 这个二叉树的每个叶子节点就是数,真祖先都是操作符. 通过栈来建立的,所以这里也会有很多栈的操作. 树的先序遍历,中序遍历,后序遍历的概念我就不讲了,不会的自行百度,不然也看不懂我的代码. 下面是代码: // // main.cpp // expressionTree // // Created by Alps on 14-7-29. // Copyright (c) 2014年 chen. All rights reserved. // #includ

前序遍历和中序遍历树构造二叉树

例子 题目来自LintCode, 给出中序遍历:[1,2,3]和前序遍历:[2,1,3]. 返回例如以下的树: 2 / 1 3 代码实现 /** * Definition of TreeNode: * class TreeNode { * public: * int val; * TreeNode *left, *right; * TreeNode(int val) { * this->val = val; * this->left = this->right = NULL; * } *

根据前序、中序遍历重构二叉树

1 public class ReconstructBinaryTree { 2 public static void main(String[] args) { 3 new ReconstructBinaryTree().reConstructBinaryTree(new int[] { 1, 2, 4, 4 7, 3, 5, 6, 8 }, new int[] { 4, 7, 2, 1, 5, 3, 8, 6 }); 5 } 6 7 public TreeNode reConstructBi

根据二叉树的前序遍历和中序遍历重建二叉树

题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 1 /** 2 * Definition for binary tree 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(

LeetCode 94:Binary Tree Inorder Traversal(中序遍历)

Given a binary tree, return the inorder traversal of its nodes' values. For example: Given binary tree {1,#,2,3}, 1 \ 2 / 3 return [1,3,2]. 题目要求对二叉树进行非递归的中序遍历,所谓前序遍历即,先访问左子树.再访问根节点.然后是右子树.通常采用递归的方法,题目要求采用非递归的方法实现.算法如下: 1)如果根节点非空,将根节点加入到栈中. 2)如果栈不空,取栈

leetcode | 二叉树的前序遍历、中序遍历、后续遍历的非递归实现

Binary Tree Preorder Traversal:https://leetcode.com/problems/binary-tree-preorder-traversal/ Binary Tree Inorder Traversal :https://leetcode.com/problems/binary-tree-inorder-traversal/ Binary Tree Postorder Traversal:https://leetcode.com/problems/bin

Java数据结构系列之——树(4):二叉树的中序遍历的递归与非递归实现

package tree.binarytree; import java.util.Stack; /** * 二叉树的中序遍历:递归与非递归实现 * * @author wl * */ public class BiTreeInOrder { // 中序遍历的递归实现 public static void biTreeInOrderByRecursion(BiTreeNode root) { if (root == null) { return; } biTreeInOrderByRecursi

新手学习算法----二叉树(将一个二叉查找树按照中序遍历转换成双向链表)

题目:将一个二叉查找树按照中序遍历转换成双向链表. 给定一个二叉查找树: 4 / 2 5 / 1 3 返回 1<->2<->3<->4<->5. 思路:如果对于当前节点,把右子树转换成双向链表,然后把左子树转换成双向链表,转换的时候我们都标记了链表的头节点和尾节点,那么只需要将当前节点和左子树的尾部相连,和右子树的头部相连即可. Java代码:这个是借鉴九章里面的解题法.但是对于左右子树转换成二叉树也不是很理解,还待需要继续分析. /** * Definit

二叉查找树的前序遍历,后序遍历和中序遍历互求算法模板

面试的痛 前几天去阿里面试,一时忘记了二叉树的前序遍历中序遍历和后序遍历的概念,已经想死了. 然后最近去腾讯面试,被问到怎么已知前序遍历/后序遍历 + 中序遍历,求后序遍历/前序遍历,看来这种问题很喜欢考. 其实这个问题想清楚了很简单,只要把这三个概念理解透彻就可以做出来了,比如前序遍历的第一个值一定是根节点,然后这个根节点对应到中序遍历里面,在中序遍历的这个值的两边的值,一定在以此节点为根节点的两个子树上,同理,后序遍历也一样. 已知前序遍历和后序遍历是不能求唯一的中序遍历树的. #inclu