二叉树的递归实现(链表)
常规遍历方式
实现了二叉树的生成以及三种遍历方式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#include <iostream>
#include <stdio.h>
using namespace std;
#define OK true;
#define ERROR false;
typedef struct BiTNode{
char data;
BiTNode *lchild , *rchild;
}BiTNode , *BiTree;
//构造树
bool CreatBiTree(BiTree &T){
char ch;
cin>>ch;
if(ch == '#') T = NULL;
else{
T = (BiTree)malloc(sizeof(BiTNode));
if(!T) return ERROR;
T->data = ch; // 生成根节点
CreatBiTree(T->lchild); //生成左子树
CreatBiTree(T->rchild); //生成右子树
}
return OK;
}
//前序遍历
void PreOrder(BiTree T){
if(T){
cout<<T->data<<' ';
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
//中序遍历
void InOrder(BiTree T){
if(T){
InOrder(T->lchild);
cout<<T->data<<' ';
InOrder(T->rchild);
}
}
//后序遍历
void PostOrder(BiTree T){
if(T){
PostOrder(T->lchild);
PostOrder(T->rchild);
cout<<T->data<<' ';
}
}
//层序遍历
queue<BiTree> q;
void level_order(BiTree t){
q.push(t);
while(!q.empty()){
if(t->lchild){
q.push(t->lchild);
}
if(t->rchild){
q.push(t->rchild);
}
cout<<q.front()->data<<' ';
q.pop();
t = q.front();
}
}
int main()
{
BiTree T;
CreatBiTree(T);
PreOrder(T);
cout<<endl;
InOrder(T);
cout<<endl;
PostOrder(T);
}
已知后序、中序遍历,求层序遍历
1 | #include<bits/stdc++.h> |
二叉树的非递归算法(链表)
实现了二叉树的三种遍历方式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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146#include <iostream>
#include <stdio.h>
using namespace std;
#define OK true;
#define ERROR false;
typedef struct BiTNode{
char data;
BiTNode *lchild , *rchild;
}BiTNode , *BiTree;
typedef struct Stack{
BiTree data;
Stack *Next;
}Stack , *StackList;
typedef struct{
StackList base;
StackList top;
}ListStack;
bool InitStack(ListStack &s){
s.base = (StackList)malloc(sizeof(Stack));
if(!s.base) return ERROR;
s.top = s.base;
s.top->Next = NULL;
return OK;
}
bool push(ListStack &s , BiTree T){
StackList p = (StackList)malloc(sizeof(Stack));
if(!p) return ERROR;
p->data = T;
p->Next = s.top;
s.top = p;
return OK;
}
bool pop(ListStack &s){
if(s.top == s.base) return ERROR;
StackList p = s.top;
s.top = p->Next;
free(p);
return OK;
}
BiTree getTop(ListStack &s){
return s.top->data;
}
bool isEmpty(ListStack &s){
if(s.base == s.top) return true;
else return false;
}
//构造树
bool CreatBiTree(BiTree &T){
char ch;
cin>>ch;
if(ch == '#') T = NULL;
else{
T = (BiTree)malloc(sizeof(BiTNode));
if(!T) return ERROR;
T->data = ch; // 生成根节点
CreatBiTree(T->lchild); //生成左子树
CreatBiTree(T->rchild); //生成右子树
}
return OK;
}
void PreOrder(BiTree T){
ListStack s;
InitStack(s);
while(T || !isEmpty(s)){
while(T){
cout<<T->data<<' ';
push(s , T);
T = T->lchild;
}
if(!isEmpty(s)){
T = getTop(s);
pop(s);
T = T->rchild;
}
}
cout<<endl;
}
void InOrder(BiTree T){
ListStack s;
InitStack(s);
while(T || !isEmpty(s)){
while(T){
push(s , T);
T = T->lchild;
}
if(!isEmpty(s)){
T = getTop(s);
pop(s);
cout<<T->data<<' ';
T = T->rchild;
}
}
cout<<endl;
}
void PostOrder(BiTree T){
ListStack s;
InitStack(s);
int flag = 1; // 用来判断是否进入右子树
BiTree p;
if(T){
do{
while(T){
push(s , T);
T = T->lchild;
}
flag = 1;
p = NULL;
while(!isEmpty(s) && flag == 1){
T = getTop(s); // 因为经过第一个while循环,T = NULL,所以要把他变回来
if(T->rchild == p){
cout<<T->data<<' ';
p = T; //用于判断此节点的右孩子是否已经被访问,或者是没有右孩子
pop(s);
}
else {
T = T->rchild;
flag = 0;
}
}
}while(!isEmpty(s));
}
cout<<endl;
}
int main()
{
BiTree T;
CreatBiTree(T);
PreOrder(T);
InOrder(T);
PostOrder(T);
}
线索二叉树中序遍历的实现
线索二叉树的初始化
与普通二叉树相比,多了一个指示域:LTag和RTag,如果值是Link,那么有左孩子或右孩子,如果是Thread,那么有前驱或后继。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#include <iostream>
#include <stdio.h>
using namespace std;
#define OK true;
#define ERROR false;
typedef enum PointerTag{ // 声明PointTag为枚举类型
Link,
Thread
};
typedef struct BiThrNode{
char data;
BiThrNode *lchild , *rchild;
PointerTag LTag , RTag;
}BiThrNode , *BiThrTree;
bool CreatBiTree(BiThrTree &T){
char ch;
cin>>ch;
if(ch == '#') T = NULL;
else{
T = (BiThrTree)malloc(sizeof(BiThrNode));
if(!T) return ERROR;
T->data = ch; // 生成根节点
T->LTag = Link;
T->RTag = Link;
CreatBiTree(T->lchild); //生成左子树
CreatBiTree(T->rchild); //生成右子树
}
return OK;
}
遍历
在线索树上遍历,只需找到要遍历的第一个节点,然后依次按照三种遍历方式的规定找后继就可以了。要遍历线索树,就要把普通的二叉树线索化,就是按照规定把空指针改为前驱或后继,所以三种遍历方式的线索化操作是不同的。
中序遍历
1 | BiThrTree pre; |
前序遍历
1 | BiThrTree pre; |
