Skip to content

Commit f85c0ed

Browse files
committed
add binary_tree
1 parent 87d9100 commit f85c0ed

1 file changed

Lines changed: 168 additions & 0 deletions

File tree

binary_tree.md

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
---
2+
title: 二叉树
3+
date: 2016-09-23 15:32:24
4+
tags: Algorithm
5+
---
6+
畏惧了好久的二叉树,终于在近两天开搞了。二分法查找已在前几天完成,磨刀霍霍向猪羊,吼吼吼!
7+
何为二叉树?按照我目前的理解就是类似于发叉的树,树干上发两个叉或者一个(不发叉的树真不到有何用处),发叉的地方称为**节点**。然后发的两个叉又可以继续像树干一样发叉,新发的叉有可以继续发叉,子又生子,孙又生孙,无穷尽也!但是**树的左边的叉的值小于节点值,右边的大于节点值**
8+
9+
本文参考:
10+
[老齐的Github](https://github.com/qiwsir/algorithm/blob/master/binary_tree.md)
11+
12+
首先,建立一棵树。
13+
```python
14+
class Node:
15+
def __init__(self, data):
16+
self.left = None
17+
self.right = None
18+
self.data = data
19+
```
20+
这样,光秃秃的小树苗就种好了。接着就是茁长生长啦。浇水去喽!
21+
```python
22+
class Node:
23+
'''
24+
...
25+
'''
26+
def insert(self, data):
27+
if data < self.data: # 树叉小于节点
28+
if self.left is None: # 并且左面的树叉为空
29+
self.left = Node(data) # 当仁不让的插入
30+
else: # 非空的话
31+
self.left.insert(data) # 以左树叉为节点继续插入
32+
33+
elif data > self.data:
34+
if self.right is None:
35+
self.right = Node(data)
36+
else:
37+
self.right.insert(data)
38+
else:
39+
self.data = data
40+
```
41+
浇完水后,小树苗噌噌的往上窜啊。
42+
```python
43+
class Node:
44+
'''
45+
省略上述代码
46+
'''
47+
def search(self, data, parent=None):
48+
'''
49+
data为目标查询值,同时返回parent(父节点)便于定位。
50+
'''
51+
if data < self.data:
52+
if self.left is None:
53+
return None, None
54+
else:
55+
return self.left.search(data, self)
56+
57+
elif data > self.data:
58+
if self.right is None:
59+
return None, None
60+
61+
return self.right.search(data, self)
62+
else:
63+
# return self.data, parent.data
64+
return self, parent
65+
```
66+
树苗生长的那么好,想看看每个叉上都是啥呀,来来来,抬头往上看((其实是往下看啦)。
67+
```python
68+
def print_tree(self):
69+
if self.left:
70+
self.left.print_tree()
71+
print(self.data)
72+
if self.right:
73+
self.right.print_tree()
74+
75+
```
76+
转眼间小树苗涨的太旺盛了,疯涨啊!!怎么办呢,剪几个枝吧。别怪我哦,小树苗!
77+
删除节点时,有三种可能的情况:
78+
79+
1. 目标节点下没有任何节点(0个)
80+
2. 目标节点下有一个节点
81+
3. 目标节点下有两个节点
82+
83+
判断节点数目程序如下:
84+
```python
85+
class Node:
86+
```
87+
省略代码
88+
```
89+
def chrildren(self):
90+
count = 0
91+
if self.left:
92+
count += 1
93+
94+
if self.right:
95+
count += 1
96+
97+
return count
98+
```
99+
接下来就是删除操作啦。哦吼吼。
100+
```python
101+
class Node:
102+
```
103+
省略
104+
```
105+
106+
def delete(self, data):
107+
node, parent = self.search(data)
108+
chrildren = node.chrildren() # 子节点数目
109+
if chrildren == 0: # 情况 1
110+
if parent.left is node: # 判断目标节点是其父节点的 左or右 节点
111+
parent.left = None
112+
else:
113+
parent.right = None
114+
del node
115+
116+
elif chrildren == 1: # 情况 2
117+
if node.left:
118+
tmp = node.left
119+
else:
120+
tmp = node.right
121+
if parent:
122+
if parent.left is node:
123+
parent.left = tmp
124+
else:
125+
parent.right = tmp
126+
del node
127+
else: # 情况 3 没看太懂,过两天再看吧
128+
'''
129+
第三种情况比较复杂
130+
1. 左节点0个子节点
131+
2. 左节点1个子节点
132+
3. 左节点2个子节点
133+
'''
134+
parent = node
135+
successor = node.left
136+
while successor.left:
137+
parent = successor
138+
successor = successor.left
139+
node.data = successor.data
140+
if parent.left = successor:
141+
parent.left = successor.right
142+
else:
143+
parent.left = successor.right
144+
145+
146+
# 接下来可以测试以下种的树怎么样啦。
147+
root = Node(11)
148+
root.insert(14)
149+
root.insert(9)
150+
root.insert(9)
151+
root.insert(7)
152+
root.insert(10)
153+
root.insert(4)
154+
root.insert(5)
155+
root.insert(6)
156+
root.insert(8)
157+
value, parent = root.search(10)
158+
print(value.data, parent.data)
159+
root.print_tree()
160+
print('*' * 20)
161+
root.delete(4)
162+
root.print_tree()
163+
164+
```
165+
166+
把自己理解的部分写了写。当做练习,就先当个α版吧。
167+
168+
`2016-05-28`

0 commit comments

Comments
 (0)