007's Studio.

算法导论练习10.4-5二叉树遍历

字数统计: 618阅读时长: 2 min
2019/08/08 Share

10.4-5 给定一个n结点的二叉树,写出一个$O(n)$时间的非递归过程,将该树的每一个结点的关键字输出。要求除该树本身的存储空间外只能使用固定量的额外存储空间,且中过程中不得修改该树,即使是暂时的修改也不允许。

要完成$O(1))$的空间内遍历该树,需要每个结点需要能访问其父节点进行回溯。

1
2
3
4
5
6
7
struct Tree
{
Tree *parent;
Tree *left;
Tree *right;
int key;
};

中序遍历:

  1. 访问左孩子
  2. 访问右孩子
  3. 从左孩子返回,访问根节点,进入右孩子访问
  4. 从右孩子返回,整棵树访问完成,回溯直到为根节点或该结点是父节点的左孩子

下面是测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include<iostream>
#include<stack>
using namespace std;
#define NIL -1
struct Tree
{
Tree* left;
Tree* right;
Tree* parent;
int key;
Tree():left(nullptr),right(nullptr),parent(nullptr){}
};
void print(const Tree* t)
{
cout << t->key << " ";
}
void createTree(Tree *&t)
{
int key;
cin >> key;
if(key==NIL){
t=nullptr;
return;
}
t=new Tree();
t->key=key;
createTree(t->left);
createTree(t->right);
//存在子结点,更细父指针
if(t->left)
t->left->parent=t;
if(t->right)
t->right->parent=t;
}
// 递归版本
void inorder_travel(Tree *h)
{
if(h)
{
inorder_travel(h->left);
print(h);
norder_travel(h->right);
}
}

// 使用stack非递归版本,结点不需要parent指针
void inorder_byStack(Tree*h)
{
stack<Tree*> sta;
Tree *p=h;
while(p || !sta.empty())
{
while(p)
{
sta.push(p);
p=p->left;
}
p=sta.top();sta.pop();
print(p);
p=p->right;
}
}
// 没有使用栈的版本,通过h和pre之间的关系进行遍历。
// 回溯需要parent指针。
void inorder_noStack(Tree* h)
{
if(!h)return;
//pre作为前驱,判断从左孩子还是右孩子返回
Tree* pre=nullptr;
while(true)
{
//找到左结点
if(pre!=h->left)
{
while(h->left)
h=h->left;
}
print(h);
//存在右结点则进入
if(h->right){
h=h->right;
continue;
}
//右孩子返回时,回溯直到根结点的父节点或是父节点的左孩子
do{
pre=h;
h=h->parent;
if(h==nullptr)
return;
}while(pre==h->right);
}
}
int main()
{
Tree* head;
createTree(head);
inorder_travel(head);
cout << endl;
inorder_byStack(head);
cout << endl;
inorder_noStack(head);
}

测试数据:
1 2 4 7 -1 -1 -1 5 8 -1 -1 -1 3 6 -1 9 -1 -1 -1

树的形状是:

中序遍历结果:
7 4 2 8 5 1 6 9 3

原文作者:007havegone

原文链接:http://007havegone.github.io/2019/08/08/算法导论练习10.4-5二叉树遍历/

发表日期:August 8th 2019, 2:00:03 pm

更新日期:August 18th 2019, 4:12:41 pm

版权声明:‘原创内容,转载时请附上出处’

CATALOG