|
| 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