BST树遍历O(n)时间复杂度+O(1)空间复杂度

问题描述

BST树的遍历问题常常遇到,前序、中序、后序等。如果用递归的话,是非常方便的,其时间复杂度是O(n),空间复杂度是O(log n)级别。PS:stackoverflow问答网站上有一个问题指出,这类问题的复杂度不应该直接说是O(log n),因为编译器会进行一些优化,比如修改成尾递归等。不过我们这里暂时不考虑优化,从程序逻辑上来讲,BST递归遍历认为是O(log n)的复杂度。

OK,那么如果改进遍历方法,使得空间复杂度只有O(1)呢?

解决方案

解决方法中,是针对每个叶节点,将其右指针指向后继节点。这是核心思想。

         4
        /         2    6
      / \  /      1   3 5  7

比如上述图中,将1的右指针指向2,将3的右指针指向4,5的右指针指向6. 具体代码如下

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>

using namespace std;

struct Node {
    int value;
    Node *left, *right;
    Node(int v): value(v), left(NULL), right(NULL) {}
};

class Solution {
public:
    void solve() {
        // build up a BST tree
        Node *root = new Node(4);
        root->left = new Node(2);
        root->left->left = new Node(1);
        root->left->right = new Node(3);
        root->right = new Node(6);
        root->right->left = new Node(5);
        root->right->right = new Node(7);
        root->right->right->right = new Node(8);
        // in order traversal
        inorder_traversal(root);
    }
    // use o(lg n) time, use o(1) space
    void inorder_traversal(Node *root) {
        Node *curr = root;
        while (curr) {
            if (curr->left) {
                Node *p = curr->left;
                while (p->right != NULL && p->right != curr) p = p->right;
                if (p->right == NULL) {
                    // make new link, which is the key point!
                    p->right = curr;
                    curr = curr->left;
                } else {
                    // p->right == curr
                    printf("%d ", curr->value);
                    p->right = NULL;
                    curr = curr->right;
                }
            } else {
                // for the leaf nodes
                printf("%d ", curr->value);
                curr = curr->right;
            }
        }
    }
};

int main() {
    Solution solution;
    solution.solve();
    return 0;
}
时间: 2024-10-07 20:17:03

BST树遍历O(n)时间复杂度+O(1)空间复杂度的相关文章

有序单链表转BST树+时间复杂度要求O(n)

问题描述 针对有序的数组或链表,要转为相对平衡的BST树时,通常有多种做法. 1. 对于有序的数组A,转为BST时,取数组中间元素A[m],转为根,然后递归转换A[1..m-1], A[m+1 .. n]即可.时间复杂度 T(n) = 2 * T(n/2) + O(1),得出T(n) = O(n) 2. 针对有序的链表,如果依据上述方法,也可以进行.然而要取到A[m]的话,则需要遍历n/2长度的数组,因此需要额外O(n)的时间来取到A[m].因此时间复杂度为T(n) = 2 * T(n/2) +

A1135 | 红黑树判断:审题、根据“先序遍历”和“BST树”的条件生成后序遍历、递归判断

对A1135这题有心里阴影了,今天终于拿下AC.学习自柳神博客:https://www.liuchuo.net/archives/4099 首先读题很关键: There is a kind of balanced binary search tree named red-black tree in the data structure------ 红黑树首先应该是一棵BST树,不然从何谈起维护二分查找结构? 所以第一步就应该根据先序遍历以及BST树的特性来判断是否是一棵BST树,然后根据这两个条

BST树

http://www.cnblogs.com/bizhu/archive/2012/08/19/2646328.html 4. 二叉查找树(BST) Technorati 标记: 二叉查找树,BST,二叉查找树合并 4.1 BST数据结构定义 使用C++语言,如果需要使用BST,那么不用重新造轮子了,C++语言里的map, set等STL容器应该可以满足需求了(虽然STL里这些容器大多是以红黑树作为其底层实现),如果你需要使用小/大根堆(也叫优先队列,特殊的.自平衡的BST),STL也能满足你的

POJ 2309 BST 树状数组基本操作

Description Consider an infinite full binary search tree (see the figure below), the numbers in the nodes are 1, 2, 3, .... In a subtree whose root node is X, we can get the minimum number in this subtree by repeating going down the left node until t

jquery:树遍历

.children() 获得元素集合中每个匹配元素的子元素,选择器选择性筛选. <!DOCTYPE html> <html> <head> <style> body { font-size:16px; font-weight:bolder; } p { margin:5px 0; } </style> <script src="http://code.jquery.com/jquery-latest.js"><

06. 父子节点(树)遍历写法小结

原文:06. 父子节点(树)遍历写法小结 对于树/图的遍历,通常有2种算法来实现:迭代(Iteration)和递归(Recursion),迭代是利用循环反复取值/赋值的过程:递归则是反复自己调用自己来获得最终结果.SQL Server里的递归有32层嵌套限制,目的在于防止代码进入死循环,除非使用提示OPTION (MAXRECURSION 0). 测试数据: if OBJECT_ID('city') is not null drop table city GO create table city

BST树、B树、B+树、B*树

1. BST树 即二叉搜索树: 1.所有非叶子结点至多拥有两个儿子(Left和Right): 2.所有结点存储一个关键字: 3.非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树: 如: B树的搜索,从根结点开始,如果查询的关键字与结点的关键字相等,那么就命中:否则,如果查询关键字比结点关键字小,就进入左儿子:如果比结点关键字大,就进入右儿子:如果左儿子或右儿子的指针为空,则报告找不到相应的关键字. 如果B树的所有非叶子结点的左右子树的结点数目均保持差不多(平衡),那么B树的

python 树遍历

使用python实现的树遍历,包括宽度优先和深度优先 ef dfs(): tree = { 'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F', 'G'], 'D': ['H', 'I'], 'E': [], 'F': [], 'G': [], 'H': [], 'I': [] } leaf = [] to_crawl = deque(['A']) while to_crawl: current = to_crawl.popleft() print curre

(转)递归树求递归算法的时间复杂度

本文转载:http://www.cnblogs.com/wu8685/archive/2010/12/21/1912347.html 递归算法时间复杂度的计算方程式一个递归方程: 在引入递归树之前可以考虑一个例子: T(n) = 2T(n/2) + n2 迭代2次可以得: T(n) = n2 + 2(2T(n/4) + (n/2) 2) 还可以继续迭代,将其完全展开可得: T(n) = n2 + 2((n/2) 2 + 2((n/22)2 + 2((n/23) 2 + 2((n/24) 2 +-