返回 LeetCode 刷题

Markdown File

树和二叉查找树BST和遍历

树和二叉查找树BST和遍历.md

1一、树 Tree 基础笔记
21. 前提条件
3
4树是一种非线性数据结构。
5
6线性结构是:数组、链表、栈、队列
7
8它们基本是:一个接一个
9
10树是:一对多的层次结构
11
12例如:
13
14 A
15 / | \
16 B C D
17 / \
18 E F
19
202. 核心概念
21结点 Node
22
23树中的每一个元素都叫结点:A、B、C、D、E、F 都是结点
24
25根结点 Root:最上面的结点。
26A 是根结点
27
28父结点 Parent
29如果 A 下面连着 B,那么:
30A 是 B 的父结点
31
32子结点 Child
33如果 A 下面连着 B,那么:
34B 是 A 的子结点
35
36兄弟结点 Sibling
37有同一个父结点的结点叫兄弟。
38B、C、D 是兄弟结点
39
40叶子结点 Leaf
41没有孩子的结点。
42C、D、E、F 是叶子结点
43
44结点的度
45一个结点的孩子个数。
46
47例如:A 有 3 个孩子
48
49所以:A 的度 = 3
50
51树的度:整棵树中,所有结点度的最大值。
52
53例如:A 的度最大,是 3
54
55所以:树的度 = 3
56
57层次
58
59一般教材常用:根结点是第 1 层
60
61例如:
62
63第1层:A
64第2层:B C D
65第3层:E F
66
67高度 / 深度
68常见记法:
69树的高度 = 最大层数
70
71例如上面的树高度是:3
72
733. 树的重要性质
74性质 1:n 个结点的树有 n-1 条边
75
76例如:
77
786 个结点
79
80那么边数:5 条
81
82因为除了根结点外,每个结点都有且只有一条边连向父结点。
83
84性质 2:二叉树每个结点最多两个孩子
85
86二叉树是树的一种特殊情况:每个结点最多有两个孩子
87
88分别叫:
89
90左孩子
91右孩子
92
93比如:
94
95 A
96 / \
97 B C
98 / \
99 D E
1004. 二叉树结构体模板
101struct TreeNode {
102 int val;
103 struct TreeNode* left;
104 struct TreeNode* right;
105};
106
107
108
109Python
110
111class TreeNode:
112 def __init__(self,val):
113 self.val=val
114 self.left=None
115 self.right=None
116
117含义:
118
119val:当前结点的值
120left:左孩子
121right:右孩子
122
1235. 二叉树递归的基本模板
124很多树题都是递归。
125
126模板:
127
128void dfs(struct TreeNode* root)
129{
130 if(root == NULL)
131 {
132 return;
133 }
134
135 // 处理当前结点,如果不是NULL就往左右各自遍历
136
137 dfs(root->left);
138
139 dfs(root->right);
140}
141
142核心:root == NULL 是递归边界
143
1446. 树题最重要的思维
145
146链表题经常是:
147当前节点 + next
148
149树题经常是:
150当前节点 + 左子树 + 右子树
151
152所以树的递归要这样想:
153
154如果左子树能解决
155如果右子树能解决
156那当前结点怎么处理?
157
1587. 易错点
159易错点 1:树不是线性结构
160
161链表只有一个 next。
162
163树有:
164
165left
166right
167
168甚至普通树有多个孩子。
169
170易错点 2:递归边界一定要写
171if(root == NULL)
172{
173 return;
174}
175
176否则访问:
177
178root->left
179
180会出错。
181
182二、二叉查找树 BST 笔记
1831. 前提条件
184
185二叉查找树,英文Binary Search Tree
186
187简称:BST
188
189它首先是一棵二叉树。
190
191然后额外满足:
192
193左子树所有结点 < 根结点
194右子树所有结点 > 根结点
195
196这就是 BST 的核心性质;BST 的查找、插入、删除复杂度和树高有关,如果树比较平衡,一般能接近 O(log n),如果退化成链表则可能到 O(n)。
197
1982. 核心概念
199
200例如:
201
202 8
203 / \
204 4 10
205 / \ \
206 2 6 12
207
208对于根结点 8:
209
210左边:4、2、6 都小于 8
211右边:10、12 都大于 8
212
213对于结点 4:
214
215左边 2 小于 4
216右边 6 大于 4
217
218每一个结点都满足这个规则。
219
2203. BST 最重要性质
221
222BST 的中序遍历结果是有序的。
223上面这棵树中序遍历:
224
2252 4 6 8 10 12
226
227是升序。
228
229这个性质非常重要。
230
231以后判断一棵树是不是 BST,经常用中序遍历。
232
233三、BST 查找
234
2351. 查找思路
236查找一个值 target。
237从根结点开始:
238
239如果 target == root->val
240 找到
241
242如果 target < root->val
243 去左子树找
244
245如果 target > root->val
246 去右子树找
247
2482. 查找例子
249树:
250
251 8
252 / \
253 4 10
254 / \ \
255 2 6 12
256
257查找:6
258
259过程:
260
2616 < 8,去左边
2626 > 4,去右边
2636 == 6,找到
264
2653. BST 查找 C 代码
266递归版:
267
268struct TreeNode* searchBST(struct TreeNode* root, int target)
269{
270 if(root == NULL)
271 {
272 return NULL;
273 }
274
275 if(root->val == target)
276 {
277 return root;
278 }
279
280 if(target < root->val)
281 {
282 return searchBST(root->left, target);
283 }
284 else
285 {
286 return searchBST(root->right, target);
287 }
288}
289
290迭代版:
291
292struct TreeNode* searchBST(struct TreeNode* root, int target)
293{
294 while(root != NULL)
295 {
296 if(root->val == target)
297 {
298 return root;
299 }
300 else if(target < root->val)
301 {
302 root = root->left;
303 }
304 else
305 {
306 root = root->right;
307 }
308 }
309
310 return NULL;
311}
312
313四、BST 插入
314
3151. 插入思路
316
317插入一个值 x。
318
319从根开始比较:
320
321x < 当前结点,往左走
322x > 当前结点,往右走
323
324直到遇到空位置:NULL
325
326就在这个位置创建新结点。
327
3282. 插入例子
329
330原树:
331
332 8
333 / \
334 4 10
335 / \
336 2 6
337
338插入:5
339
340过程:
341
3425 < 8,去左
3435 > 4,去右
3445 < 6,去左
3456 的左边为空,插入 5
346
347结果:
348
349 8
350 / \
351 4 10
352 / \
353 2 6
354 /
355 5
3563. 创建结点代码
357#include <stdlib.h>
358
359struct TreeNode* createNode(int x)
360{
361 struct TreeNode* node =
362 malloc(sizeof(struct TreeNode));
363
364 node->val = x;
365 node->left = NULL;
366 node->right = NULL;
367
368 return node;
369}
3704. 插入 C 代码
371
372递归版:
373
374struct TreeNode* insertBST(struct TreeNode* root, int x)
375{
376 if(root == NULL)
377 {
378 return createNode(x);
379 }
380
381 if(x < root->val)
382 {
383 root->left = insertBST(root->left, x);
384 }
385 else if(x > root->val)
386 {
387 root->right = insertBST(root->right, x);
388 }
389
390 return root;
391}
392
393说明:如果题目不允许重复值,x == root->val 时不插入。
394
395五、BST 删除
396
397删除是 BST 最容易混的地方。
398
399删除一个结点分三种情况。
400
401情况 1:删除叶子结点
402
403例如删除 2:
404
405 8
406 / \
407 4 10
408 / \
409 2 6
410
4112 没有孩子。
412
413直接删。
414
415结果:
416
417 8
418 / \
419 4 10
420 \
421 6
422情况 2:删除只有一个孩子的结点
423
424例如:
425
426 8
427 / \
428 4 10
429 \
430 12
431
432删除 10。
433
43410 只有右孩子 12。
435
436让 12 顶上来:
437
438 8
439 / \
440 4 12
441情况 3:删除有两个孩子的结点
442
443例如删除 8:
444
445 8
446 / \
447 4 10
448 / \ \
449 2 6 12
450
4518 有左孩子和右孩子。
452
453不能直接删。
454
455常用做法:找右子树最小值
456
457右子树:
458
45910
460 \
461 12
462
463最小值是:
464
46510
466
467用 10 替换 8。
468
469然后再去右子树删除原来的 10。
470
471结果:
472
473 10
474 / \
475 4 12
476 / \
477 2 6
478
479删除 C 代码
480struct TreeNode* findMin(struct TreeNode* root)
481{
482 while(root->left != NULL)
483 {
484 root = root->left;
485 }
486
487 return root;
488}
489
490struct TreeNode* deleteBST(struct TreeNode* root, int x)
491{
492 if(root == NULL)
493 {
494 return NULL;
495 }
496
497 if(x < root->val)
498 {
499 root->left = deleteBST(root->left, x);
500 }
501 else if(x > root->val)
502 {
503 root->right = deleteBST(root->right, x);
504 }
505 else
506 {
507 if(root->left == NULL && root->right == NULL)
508 {
509 free(root);
510 return NULL;
511 }
512 else if(root->left == NULL)
513 {
514 struct TreeNode* temp = root->right;
515 free(root);
516 return temp;
517 }
518 else if(root->right == NULL)
519 {
520 struct TreeNode* temp = root->left;
521 free(root);
522 return temp;
523 }
524 else
525 {
526 struct TreeNode* successor = findMin(root->right);
527 root->val = successor->val;
528 root->right = deleteBST(root->right, successor->val);
529 }
530 }
531
532 return root;
533}
534
535六、BST 易错点
5361. BST 不是普通二叉树
537普通二叉树没有大小关系。
538
539BST 必须满足:
540左小右大
541
5422. 中序遍历是升序
543这是 BST 最重要性质。
544BST 中序遍历 = 升序序列
545
5463. 查找不是全树遍历
547BST 查找不用左右都搜。
548只需要根据大小走一边:
549
550小了走左
551大了走右
552
5534. 删除两个孩子的结点最麻烦
554常用替代结点:
555右子树最小值
556
557或者:
558左子树最大值
559
560二选一即可。
561
5625. BST 可能退化成链表
563
564如果插入顺序是:
565
5661 2 3 4 5
567
568BST 会变成:
569
5701
571 \
572 2
573 \
574 3
575 \
576 4
577 \
578 5
579
580查找就退化成:
581
582O(n)
583
584这也是为什么后面要学 AVL 树。
585
586BST 笔记总结
587二叉查找树 BST
588
589定义:
590
591左子树所有结点 < 根结点
592右子树所有结点 > 根结点
593
594--------------------------------
595
596重要性质:中序遍历结果是升序
597
598--------------------------------
599
600查找:
601
602target < root->val
603 去左子树
604
605target > root->val
606 去右子树
607
608target == root->val
609 找到
610
611--------------------------------
612
613插入:按查找路径往下走
614
615遇到 NULL 就插入新结点
616
617--------------------------------
618
619删除:
620
6211. 叶子结点
622 直接删除
623
6242. 只有一个孩子
625 孩子顶上来
626
6273. 有两个孩子
628 用右子树最小值
629 或左子树最大值替换
630
631--------------------------------
632
633复杂度:和树高有关
634
635平衡时接近 O(log n)
636
637退化成链表时 O(n)
638
639--------------------------------
640
641为什么需要 AVL:
642
643普通 BST 插入顺序不好时,
644可能退化成链表。
645
646然后稍微复习一下py的代码
647一、普通二叉树
648节点定义
649
650Python:
651//使用类之后魔术封装给左右都是None,设立节点
652class TreeNode:
653 def __init__(self,val):
654 self.val = val
655 self.left = None
656 self.right = None
657
658对应 C:
659
660struct TreeNode{
661 int val;
662 struct TreeNode* left;
663 struct TreeNode* right;
664};
665
666手动建树
667
668例如:
669
670 1
671 / \
672 2 3
673 / \
674 4 5
675
676Python:
677
678root = TreeNode(1)
679
680root.left = TreeNode(2)
681root.right = TreeNode(3)
682
683root.left.left = TreeNode(4)
684root.left.right = TreeNode(5)
685
686画出来:
687
688 root
689
690 1
691 / \
692 2 3
693 / \
6944 5
695
696二、遍历
697前序遍历
698根左右
699
700def preorder(root):
701
702 if root is None:
703 return
704
705 print(root.val)
706
707 preorder(root.left)
708
709 preorder(root.right)
710
711中序遍历
712左根右
713
714def inorder(root):
715
716 if root is None:
717 return
718
719 inorder(root.left)
720
721 print(root.val)
722
723 inorder(root.right)
724
725后序遍历
726左右根
727
728def postorder(root):
729
730 if root is None:
731 return
732
733 postorder(root.left)
734
735 postorder(root.right)
736
737 print(root.val)
738
739树递归就一个模板:
740
741if root is None:
742 return
743
744左子树
745
746右子树
747
748只是:print放哪里不同。
749
750三、BST(二叉查找树)
751
752先定义节点:
753
754class TreeNode:
755
756 def __init__(self,val):
757
758 self.val = val
759 self.left = None
760 self.right = None
761查找
762
763例如找:6
764
765树:
766
767 8
768 / \
769 4 10
770 / \
771 2 6
772
773代码:
774
775def search(root,target):
776
777 if root is None:
778 return None
779
780 if root.val == target:
781 return root
782
783 if target < root.val:
784 return search(root.left,target)
785
786 return search(root.right,target)
787
788思想和 C 一模一样:
789
790比当前小去左边
791
792比当前大去右边
793
794
795插入:5
796
797代码:
798
799def insert(root,x):
800
801 if root is None:
802 return TreeNode(x)
803
804 if x < root.val:
805 root.left = insert(root.left,x)
806
807 elif x > root.val:
808 root.right = insert(root.right,x)
809
810 return root
811
812执行:
813
814root = insert(root,5)
815
816结果:
817
818 8
819 / \
820 4 10
821 / \
822 2 6
823 /
824 5
825
826四、封装成 BST 类
827
828面向对象写法。
829
830class BST:
831
832 def __init__(self):
833 self.root = None
834
835插入:
836
837class BST:
838
839 def __init__(self):
840 self.root = None
841
842 def _insert(self,node,x):
843
844 if node is None:
845 return TreeNode(x)
846
847 if x < node.val:
848 node.left = self._insert(node.left,x)
849
850 elif x > node.val:
851 node.right = self._insert(node.right,x)
852
853 return node
854
855 def insert(self,x):
856 self.root = self._insert(self.root,x)
857
858使用:
859
860tree = BST()
861
862tree.insert(8)
863tree.insert(4)
864tree.insert(10)
865tree.insert(2)
866tree.insert(6)
867
868最后:
869
870 8
871 / \
872 4 10
873 / \
874 2 6
Rendered Preview

一、树 Tree 基础笔记

  1. 前提条件

树是一种非线性数据结构。

线性结构是:数组、链表、栈、队列

它们基本是:一个接一个

树是:一对多的层次结构

例如:

    A
  / | \
 B  C  D
/ \

E F

  1. 核心概念
    结点 Node

树中的每一个元素都叫结点:A、B、C、D、E、F 都是结点

根结点 Root:最上面的结点。
A 是根结点

父结点 Parent
如果 A 下面连着 B,那么:
A 是 B 的父结点

子结点 Child
如果 A 下面连着 B,那么:
B 是 A 的子结点

兄弟结点 Sibling
有同一个父结点的结点叫兄弟。
B、C、D 是兄弟结点

叶子结点 Leaf
没有孩子的结点。
C、D、E、F 是叶子结点

结点的度
一个结点的孩子个数。

例如:A 有 3 个孩子

所以:A 的度 = 3

树的度:整棵树中,所有结点度的最大值。

例如:A 的度最大,是 3

所以:树的度 = 3

层次

一般教材常用:根结点是第 1 层

例如:

第1层:A
第2层:B C D
第3层:E F

高度 / 深度
常见记法:
树的高度 = 最大层数

例如上面的树高度是:3

  1. 树的重要性质
    性质 1:n 个结点的树有 n-1 条边

例如:

6 个结点

那么边数:5 条

因为除了根结点外,每个结点都有且只有一条边连向父结点。

性质 2:二叉树每个结点最多两个孩子

二叉树是树的一种特殊情况:每个结点最多有两个孩子

分别叫:

左孩子
右孩子

比如:

    A
   / \
  B   C
 / \
D   E

4. 二叉树结构体模板
struct TreeNode {
int val;
struct TreeNode* left;
struct TreeNode* right;
};

Python

class TreeNode:
def init(self,val):
self.val=val
self.left=None
self.right=None

含义:

val:当前结点的值
left:左孩子
right:右孩子

  1. 二叉树递归的基本模板
    很多树题都是递归。

模板:

void dfs(struct TreeNode* root)
{
if(root == NULL)
{
return;
}

// 处理当前结点,如果不是NULL就往左右各自遍历

dfs(root->left);

dfs(root->right);

}

核心:root == NULL 是递归边界

  1. 树题最重要的思维

链表题经常是:
当前节点 + next

树题经常是:
当前节点 + 左子树 + 右子树

所以树的递归要这样想:

如果左子树能解决
如果右子树能解决
那当前结点怎么处理?

  1. 易错点
    易错点 1:树不是线性结构

链表只有一个 next。

树有:

left
right

甚至普通树有多个孩子。

易错点 2:递归边界一定要写
if(root == NULL)
{
return;
}

否则访问:

root->left

会出错。

二、二叉查找树 BST 笔记

  1. 前提条件

二叉查找树,英文Binary Search Tree

简称:BST

它首先是一棵二叉树。

然后额外满足:

左子树所有结点 < 根结点
右子树所有结点 > 根结点

这就是 BST 的核心性质;BST 的查找、插入、删除复杂度和树高有关,如果树比较平衡,一般能接近 O(log n),如果退化成链表则可能到 O(n)。

  1. 核心概念

例如:

    8
   / \
  4   10
 / \    \
2   6    12

对于根结点 8:

左边:4、2、6 都小于 8
右边:10、12 都大于 8

对于结点 4:

左边 2 小于 4
右边 6 大于 4

每一个结点都满足这个规则。

  1. BST 最重要性质

BST 的中序遍历结果是有序的。
上面这棵树中序遍历:

2 4 6 8 10 12

是升序。

这个性质非常重要。

以后判断一棵树是不是 BST,经常用中序遍历。

三、BST 查找

  1. 查找思路
    查找一个值 target。
    从根结点开始:

如果 target == root->val
找到

如果 target < root->val
去左子树找

如果 target > root->val
去右子树找

  1. 查找例子
    树:

     8
    / \
    

    4 10
    / \
    2 6 12

查找:6

过程:

6 < 8,去左边
6 > 4,去右边
6 == 6,找到

  1. BST 查找 C 代码
    递归版:

struct TreeNode* searchBST(struct TreeNode* root, int target)
{
if(root == NULL)
{
return NULL;
}

if(root->val == target)
{
    return root;
}

if(target < root->val)
{
    return searchBST(root->left, target);
}
else
{
    return searchBST(root->right, target);
}

}

迭代版:

struct TreeNode* searchBST(struct TreeNode* root, int target)
{
while(root != NULL)
{
if(root->val == target)
{
return root;
}
else if(target < root->val)
{
root = root->left;
}
else
{
root = root->right;
}
}

return NULL;

}

四、BST 插入

  1. 插入思路

插入一个值 x。

从根开始比较:

x < 当前结点,往左走
x > 当前结点,往右走

直到遇到空位置:NULL

就在这个位置创建新结点。

  1. 插入例子

原树:

    8
   / \
  4   10
 / \
2   6

插入:5

过程:

5 < 8,去左
5 > 4,去右
5 < 6,去左
6 的左边为空,插入 5

结果:

    8
   / \
  4   10
 / \
2   6
   /
  5

3. 创建结点代码
#include <stdlib.h>

struct TreeNode* createNode(int x)
{
struct TreeNode* node =
malloc(sizeof(struct TreeNode));

node->val = x;
node->left = NULL;
node->right = NULL;

return node;

}
4. 插入 C 代码

递归版:

struct TreeNode* insertBST(struct TreeNode* root, int x)
{
if(root == NULL)
{
return createNode(x);
}

if(x < root->val)
{
    root->left = insertBST(root->left, x);
}
else if(x > root->val)
{
    root->right = insertBST(root->right, x);
}

return root;

}

说明:如果题目不允许重复值,x == root->val 时不插入。

五、BST 删除

删除是 BST 最容易混的地方。

删除一个结点分三种情况。

情况 1:删除叶子结点

例如删除 2:

    8
   / \
  4   10
 / \
2   6

2 没有孩子。

直接删。

结果:

    8
   / \
  4   10
   \
    6

情况 2:删除只有一个孩子的结点

例如:

    8
   / \
  4   10
         \
         12

删除 10。

10 只有右孩子 12。

让 12 顶上来:

    8
   / \
  4   12

情况 3:删除有两个孩子的结点

例如删除 8:

    8
   / \
  4   10
 / \    \
2   6    12

8 有左孩子和右孩子。

不能直接删。

常用做法:找右子树最小值

右子树:

10

12

最小值是:

10

用 10 替换 8。

然后再去右子树删除原来的 10。

结果:

    10
   /  \
  4    12
 / \
2   6

删除 C 代码
struct TreeNode* findMin(struct TreeNode* root)
{
while(root->left != NULL)
{
root = root->left;
}

return root;

}

struct TreeNode* deleteBST(struct TreeNode* root, int x)
{
if(root == NULL)
{
return NULL;
}

if(x < root->val)
{
    root->left = deleteBST(root->left, x);
}
else if(x > root->val)
{
    root->right = deleteBST(root->right, x);
}
else
{
    if(root->left == NULL && root->right == NULL)
    {
        free(root);
        return NULL;
    }
    else if(root->left == NULL)
    {
        struct TreeNode* temp = root->right;
        free(root);
        return temp;
    }
    else if(root->right == NULL)
    {
        struct TreeNode* temp = root->left;
        free(root);
        return temp;
    }
    else
    {
        struct TreeNode* successor = findMin(root->right);
        root->val = successor->val;
        root->right = deleteBST(root->right, successor->val);
    }
}

return root;

}

六、BST 易错点

  1. BST 不是普通二叉树
    普通二叉树没有大小关系。

BST 必须满足:
左小右大

  1. 中序遍历是升序
    这是 BST 最重要性质。
    BST 中序遍历 = 升序序列

  2. 查找不是全树遍历
    BST 查找不用左右都搜。
    只需要根据大小走一边:

小了走左
大了走右

  1. 删除两个孩子的结点最麻烦
    常用替代结点:
    右子树最小值

或者:
左子树最大值

二选一即可。

  1. BST 可能退化成链表

如果插入顺序是:

1 2 3 4 5

BST 会变成:

1

2

3

4

5

查找就退化成:

O(n)

这也是为什么后面要学 AVL 树。

BST 笔记总结
二叉查找树 BST

定义:

左子树所有结点 < 根结点
右子树所有结点 > 根结点


重要性质:中序遍历结果是升序


查找:

target < root->val
去左子树

target > root->val
去右子树

target == root->val
找到


插入:按查找路径往下走

遇到 NULL 就插入新结点


删除:

  1. 叶子结点
    直接删除

  2. 只有一个孩子
    孩子顶上来

  3. 有两个孩子
    用右子树最小值
    或左子树最大值替换


复杂度:和树高有关

平衡时接近 O(log n)

退化成链表时 O(n)


为什么需要 AVL:

普通 BST 插入顺序不好时,
可能退化成链表。

然后稍微复习一下py的代码
一、普通二叉树
节点定义

Python:
//使用类之后魔术封装给左右都是None,设立节点
class TreeNode:
def init(self,val):
self.val = val
self.left = None
self.right = None

对应 C:

struct TreeNode{
int val;
struct TreeNode* left;
struct TreeNode* right;
};

手动建树

例如:

    1
   / \
  2   3
 / \
4   5

Python:

root = TreeNode(1)

root.left = TreeNode(2)
root.right = TreeNode(3)

root.left.left = TreeNode(4)
root.left.right = TreeNode(5)

画出来:

root

1
/
2 3
/
4 5

二、遍历
前序遍历
根左右

def preorder(root):

if root is None:
    return

print(root.val)

preorder(root.left)

preorder(root.right)

中序遍历
左根右

def inorder(root):

if root is None:
    return

inorder(root.left)

print(root.val)

inorder(root.right)

后序遍历
左右根

def postorder(root):

if root is None:
    return

postorder(root.left)

postorder(root.right)

print(root.val)

树递归就一个模板:

if root is None:
return

左子树

右子树

只是:print放哪里不同。

三、BST(二叉查找树)

先定义节点:

class TreeNode:

def __init__(self,val):

    self.val = val
    self.left = None
    self.right = None

查找

例如找:6

树:

    8
   / \
  4   10
 / \
2   6

代码:

def search(root,target):

if root is None:
    return None

if root.val == target:
    return root

if target < root.val:
    return search(root.left,target)

return search(root.right,target)

思想和 C 一模一样:

比当前小去左边

比当前大去右边

插入:5

代码:

def insert(root,x):

if root is None:
    return TreeNode(x)

if x < root.val:
    root.left = insert(root.left,x)

elif x > root.val:
    root.right = insert(root.right,x)

return root

执行:

root = insert(root,5)

结果:

    8
   / \
  4   10
 / \
2   6
   /
  5

四、封装成 BST 类

面向对象写法。

class BST:

def __init__(self):
    self.root = None

插入:

class BST:

def __init__(self):
    self.root = None

def _insert(self,node,x):

    if node is None:
        return TreeNode(x)

    if x < node.val:
        node.left = self._insert(node.left,x)

    elif x > node.val:
        node.right = self._insert(node.right,x)

    return node

def insert(self,x):
    self.root = self._insert(self.root,x)

使用:

tree = BST()

tree.insert(8)
tree.insert(4)
tree.insert(10)
tree.insert(2)
tree.insert(6)

最后:

    8
   / \
  4   10
 / \
2   6