问题描述
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