-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathBinaryTree.ts
206 lines (187 loc) · 6.59 KB
/
BinaryTree.ts
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
// 二叉树节点类
class TreeNode {
val: any //节点内容
left: TreeNode //左子树
right: TreeNode // 右子树
constructor(val:any) {
this.val = val
this.left = this.right = undefined
}
}
// 二叉树类
class Tree <T> {
root : TreeNode
constructor (data: T[]){
// 临时存储所有节点,方便寻找父子节点
let nodeList : TreeNode[] = []
// 顶节点
for(let i = 0, len = data.length; i < len; i++) {
let node = new TreeNode(data[i]);
nodeList.push(node);
if (i > 0) {
// 计算节点所在层级的指数 即每一层都是 2^k-1 个 k为层数 n = k -1
let n : number = Math.floor(Math.sqrt(i+1))
// 当前层的启始值
let q = Math.pow(2, n) - 1 // 索引值 减一
// 记录上一层的起始点
let p = Math.pow(2, n-1) - 1 //索引值 减一
// 找到当前节点的父节点
let parent: TreeNode = nodeList[p + Math.floor((i - q) / 2)]
// 将当前节点和上一次节点做关联
if (parent.left !== undefined) {
parent.right = node
} else {
parent.left = node
}
}
}
this.root = nodeList.shift()
nodeList.length = 0
}
// 中序遍历递归实现
public inOrderTraversal (root : TreeNode, array : T[]) : T[] {
if (root) {
this.inOrderTraversal(root.left, array)
array.push(root.val)
this.inOrderTraversal(root.right, array)
}
return array
}
// 中序遍历非递归实现
public inOrderTraversal2 (root: TreeNode) : T[] {
let arr: T[] = [];
let stack: TreeNode[] = [];
let node = root;
while(node || stack.length > 0) {
// 如果node存在
if (node) {
// node先入栈 之后访问它的左子树
stack.push(node);
node = node.left;
}
// node 不存在
else {
// 获取栈顶元素
node = stack.pop();
// 结果添加元素值
arr.push(node.val);
// 获取右子树 开始遍历
node = node.right;
}
}
return arr;
}
// 先序遍历递归实现
public preOrderTraversal (root : TreeNode, array: T[]) : T[] {
if (root) {
array.push(root.val)
this.preOrderTraversal(root.left, array)
this.preOrderTraversal(root.right, array)
}
return array
}
// 先序遍历非递归实现
public preOrderTraversal2 (root: TreeNode): T[] {
let arr: T[] = [];
let stack: TreeNode[] = [];
// 栈内存放root根节点
stack.push(root);
while(stack.length > 0) {
let node = stack.pop();
// 首先传入根节点的值
arr.push(node.val);
// 向栈内推送 右子树和左子树 使左子树在右子树上
if (node.right !== undefined) stack.push(node.right);
if (node.left !== undefined) stack.push(node.left);
}
return arr;
}
// 后序遍历递归实现
public postOrderTraversal (root: TreeNode, array: T[]) : T[] {
if (root) {
this.postOrderTraversal(root.left, array)
this.postOrderTraversal(root.right, array)
array.push(root.val)
}
return array
}
// 后续遍历非递归实现
public postOrderTraversal2 (root: TreeNode): T[] {
let arr: T[] = [];
let stack: TreeNode[] = [];
let node = root;
let right = null;
while (node || stack.length > 0) {
if (node) {
// 首先推入根节点
stack.push(node);
// 优先遍历左子树
node = node.left;
} else {
node = stack[stack.length - 1];
// 如果当前节点的右子树为上一次遍历的节点或者没有右子树 则直接读取
if (node.right === right || node.right === undefined) {
arr.push(node.val);
right = node;
stack.pop();
node = null;
}
// 否则继续访问右子树
else {
node = node.right;
}
}
}
return arr;
}
// 计算二叉树的深度
public treeDepth (root: TreeNode) : number {
// 一个二叉树的深度为 左子树深度和右子树深度的最大值 + 1
return (root === undefined || root.val === null) ? 0 : Math.max(this.treeDepth(root.left), this.treeDepth(root.right)) + 1
}
// 计算二叉树的最小深度
public minDepth (root: TreeNode) : number {
if (root === undefined || root.val === null) {
return 0
}
let left = this.minDepth(root.left)
let right = this.minDepth(root.right)
return (left && right) ? 1 + Math.min(left, right) : 1 + left + right
}
// 判断二叉树是否为平衡二叉树
public isBalanced (root: TreeNode) : boolean {
if (!root || root.val === null) {
return true;
}
let left = this.isBalanced(root.left)
let right = this.isBalanced(root.right)
// 如果存在不平衡情况即都不平衡
if (left === false || right === false || Math.abs(this.treeDepth(this.root.left) - this.treeDepth(this.root.right)) > 1) {
return false
}
return true
}
// 二叉树层次遍历
public levelTraversal (root: TreeNode) : number[][] | number[] {
if (!root) return []
// 使用 queue 来存储当前层级的节点
let result = [], queue = [root]
while (queue.length) {
let levelSize = queue.length
let currentLevel = []
while (levelSize--) {
let node = queue.shift()
currentLevel.push(node.val)
// 在当前层级推入一个结点时,把它的左右子结点推入队列中
if (node.left && node.left.val !== null) queue.push(node.left)
if (node.right && node.right.val !== null) queue.push(node.right)
}
result.push(currentLevel)
}
return result
}
}
export default Tree
export {
TreeNode
}