Skip to content

Commit a2afef3

Browse files
committed
update trees
1 parent ec65683 commit a2afef3

File tree

2 files changed

+610
-0
lines changed

2 files changed

+610
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,305 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# Binary Search Trees"
8+
]
9+
},
10+
{
11+
"cell_type": "markdown",
12+
"metadata": {},
13+
"source": [
14+
"This is the code ot go along with the video explanation. Check out the video lecture for full details!"
15+
]
16+
},
17+
{
18+
"cell_type": "code",
19+
"execution_count": 5,
20+
"metadata": {
21+
"collapsed": false
22+
},
23+
"outputs": [],
24+
"source": [
25+
"class TreeNode:\n",
26+
" \n",
27+
" def __init__(self,key,val,left=None,right=None,parent=None):\n",
28+
" self.key = key\n",
29+
" self.payload = val\n",
30+
" self.leftChild = left\n",
31+
" self.rightChild = right\n",
32+
" self.parent = parent\n",
33+
"\n",
34+
" def hasLeftChild(self):\n",
35+
" return self.leftChild\n",
36+
"\n",
37+
" def hasRightChild(self):\n",
38+
" return self.rightChild\n",
39+
"\n",
40+
" def isLeftChild(self):\n",
41+
" return self.parent and self.parent.leftChild == self\n",
42+
"\n",
43+
" def isRightChild(self):\n",
44+
" return self.parent and self.parent.rightChild == self\n",
45+
"\n",
46+
" def isRoot(self):\n",
47+
" return not self.parent\n",
48+
"\n",
49+
" def isLeaf(self):\n",
50+
" return not (self.rightChild or self.leftChild)\n",
51+
"\n",
52+
" def hasAnyChildren(self):\n",
53+
" return self.rightChild or self.leftChild\n",
54+
"\n",
55+
" def hasBothChildren(self):\n",
56+
" return self.rightChild and self.leftChild\n",
57+
"\n",
58+
" def replaceNodeData(self,key,value,lc,rc):\n",
59+
" self.key = key\n",
60+
" self.payload = value\n",
61+
" self.leftChild = lc\n",
62+
" self.rightChild = rc\n",
63+
" if self.hasLeftChild():\n",
64+
" self.leftChild.parent = self\n",
65+
" if self.hasRightChild():\n",
66+
" self.rightChild.parent = self\n",
67+
"\n",
68+
"\n",
69+
"class BinarySearchTree:\n",
70+
"\n",
71+
" def __init__(self):\n",
72+
" self.root = None\n",
73+
" self.size = 0\n",
74+
"\n",
75+
" def length(self):\n",
76+
" return self.size\n",
77+
"\n",
78+
" def __len__(self):\n",
79+
" return self.size\n",
80+
"\n",
81+
" def put(self,key,val):\n",
82+
" if self.root:\n",
83+
" self._put(key,val,self.root)\n",
84+
" else:\n",
85+
" self.root = TreeNode(key,val)\n",
86+
" self.size = self.size + 1\n",
87+
"\n",
88+
" def _put(self,key,val,currentNode):\n",
89+
" if key < currentNode.key:\n",
90+
" if currentNode.hasLeftChild():\n",
91+
" self._put(key,val,currentNode.leftChild)\n",
92+
" else:\n",
93+
" currentNode.leftChild = TreeNode(key,val,parent=currentNode)\n",
94+
" else:\n",
95+
" if currentNode.hasRightChild():\n",
96+
" self._put(key,val,currentNode.rightChild)\n",
97+
" else:\n",
98+
" currentNode.rightChild = TreeNode(key,val,parent=currentNode)\n",
99+
"\n",
100+
" def __setitem__(self,k,v):\n",
101+
" self.put(k,v)\n",
102+
"\n",
103+
" def get(self,key):\n",
104+
" if self.root:\n",
105+
" res = self._get(key,self.root)\n",
106+
" if res:\n",
107+
" \n",
108+
" return res.payload\n",
109+
" else:\n",
110+
" return None\n",
111+
" else:\n",
112+
" return None\n",
113+
"\n",
114+
" def _get(self,key,currentNode):\n",
115+
" \n",
116+
" if not currentNode:\n",
117+
" return None\n",
118+
" elif currentNode.key == key:\n",
119+
" return currentNode\n",
120+
" elif key < currentNode.key:\n",
121+
" return self._get(key,currentNode.leftChild)\n",
122+
" else:\n",
123+
" return self._get(key,currentNode.rightChild)\n",
124+
"\n",
125+
" def __getitem__(self,key):\n",
126+
" return self.get(key)\n",
127+
"\n",
128+
" def __contains__(self,key):\n",
129+
" if self._get(key,self.root):\n",
130+
" return True\n",
131+
" else:\n",
132+
" return False\n",
133+
"\n",
134+
" def delete(self,key):\n",
135+
" \n",
136+
" if self.size > 1:\n",
137+
" \n",
138+
" nodeToRemove = self._get(key,self.root)\n",
139+
" if nodeToRemove:\n",
140+
" self.remove(nodeToRemove)\n",
141+
" self.size = self.size-1\n",
142+
" else:\n",
143+
" raise KeyError('Error, key not in tree')\n",
144+
" elif self.size == 1 and self.root.key == key:\n",
145+
" self.root = None\n",
146+
" self.size = self.size - 1\n",
147+
" else:\n",
148+
" raise KeyError('Error, key not in tree')\n",
149+
"\n",
150+
" def __delitem__(self,key):\n",
151+
" \n",
152+
" self.delete(key)\n",
153+
"\n",
154+
" def spliceOut(self):\n",
155+
" if self.isLeaf():\n",
156+
" if self.isLeftChild():\n",
157+
" \n",
158+
" self.parent.leftChild = None\n",
159+
" else:\n",
160+
" self.parent.rightChild = None\n",
161+
" elif self.hasAnyChildren():\n",
162+
" if self.hasLeftChild():\n",
163+
" \n",
164+
" if self.isLeftChild():\n",
165+
" \n",
166+
" self.parent.leftChild = self.leftChild\n",
167+
" else:\n",
168+
" \n",
169+
" self.parent.rightChild = self.leftChild\n",
170+
" self.leftChild.parent = self.parent\n",
171+
" else:\n",
172+
" \n",
173+
" if self.isLeftChild():\n",
174+
" \n",
175+
" self.parent.leftChild = self.rightChild\n",
176+
" else:\n",
177+
" self.parent.rightChild = self.rightChild\n",
178+
" self.rightChild.parent = self.parent\n",
179+
"\n",
180+
" def findSuccessor(self):\n",
181+
" \n",
182+
" succ = None\n",
183+
" if self.hasRightChild():\n",
184+
" succ = self.rightChild.findMin()\n",
185+
" else:\n",
186+
" if self.parent:\n",
187+
" \n",
188+
" if self.isLeftChild():\n",
189+
" \n",
190+
" succ = self.parent\n",
191+
" else:\n",
192+
" self.parent.rightChild = None\n",
193+
" succ = self.parent.findSuccessor()\n",
194+
" self.parent.rightChild = self\n",
195+
" return succ\n",
196+
"\n",
197+
" def findMin(self):\n",
198+
" \n",
199+
" current = self\n",
200+
" while current.hasLeftChild():\n",
201+
" current = current.leftChild\n",
202+
" return current\n",
203+
"\n",
204+
" def remove(self,currentNode):\n",
205+
" \n",
206+
" if currentNode.isLeaf(): #leaf\n",
207+
" if currentNode == currentNode.parent.leftChild:\n",
208+
" currentNode.parent.leftChild = None\n",
209+
" else:\n",
210+
" currentNode.parent.rightChild = None\n",
211+
" elif currentNode.hasBothChildren(): #interior\n",
212+
" \n",
213+
" succ = currentNode.findSuccessor()\n",
214+
" succ.spliceOut()\n",
215+
" currentNode.key = succ.key\n",
216+
" currentNode.payload = succ.payload\n",
217+
"\n",
218+
" else: # this node has one child\n",
219+
" if currentNode.hasLeftChild():\n",
220+
" if currentNode.isLeftChild():\n",
221+
" currentNode.leftChild.parent = currentNode.parent\n",
222+
" currentNode.parent.leftChild = currentNode.leftChild\n",
223+
" elif currentNode.isRightChild():\n",
224+
" currentNode.leftChild.parent = currentNode.parent\n",
225+
" currentNode.parent.rightChild = currentNode.leftChild\n",
226+
" else:\n",
227+
" \n",
228+
" currentNode.replaceNodeData(currentNode.leftChild.key,\n",
229+
" currentNode.leftChild.payload,\n",
230+
" currentNode.leftChild.leftChild,\n",
231+
" currentNode.leftChild.rightChild)\n",
232+
" else:\n",
233+
" \n",
234+
" if currentNode.isLeftChild():\n",
235+
" currentNode.rightChild.parent = currentNode.parent\n",
236+
" currentNode.parent.leftChild = currentNode.rightChild\n",
237+
" elif currentNode.isRightChild():\n",
238+
" currentNode.rightChild.parent = currentNode.parent\n",
239+
" currentNode.parent.rightChild = currentNode.rightChild\n",
240+
" else:\n",
241+
" currentNode.replaceNodeData(currentNode.rightChild.key,\n",
242+
" currentNode.rightChild.payload,\n",
243+
" currentNode.rightChild.leftChild,\n",
244+
" currentNode.rightChild.rightChild)\n",
245+
"\n",
246+
"\n"
247+
]
248+
},
249+
{
250+
"cell_type": "code",
251+
"execution_count": 6,
252+
"metadata": {
253+
"collapsed": false
254+
},
255+
"outputs": [
256+
{
257+
"name": "stdout",
258+
"output_type": "stream",
259+
"text": [
260+
"yellow\n",
261+
"at\n"
262+
]
263+
}
264+
],
265+
"source": [
266+
"mytree = BinarySearchTree()\n",
267+
"mytree[3]=\"red\"\n",
268+
"mytree[4]=\"blue\"\n",
269+
"mytree[6]=\"yellow\"\n",
270+
"mytree[2]=\"at\"\n",
271+
"\n",
272+
"print(mytree[6])\n",
273+
"print(mytree[2])"
274+
]
275+
},
276+
{
277+
"cell_type": "markdown",
278+
"metadata": {},
279+
"source": [
280+
"** Check the video for full explanation! **"
281+
]
282+
}
283+
],
284+
"metadata": {
285+
"kernelspec": {
286+
"display_name": "Python 2",
287+
"language": "python",
288+
"name": "python2"
289+
},
290+
"language_info": {
291+
"codemirror_mode": {
292+
"name": "ipython",
293+
"version": 2
294+
},
295+
"file_extension": ".py",
296+
"mimetype": "text/x-python",
297+
"name": "python",
298+
"nbconvert_exporter": "python",
299+
"pygments_lexer": "ipython2",
300+
"version": "2.7.11"
301+
}
302+
},
303+
"nbformat": 4,
304+
"nbformat_minor": 0
305+
}

0 commit comments

Comments
 (0)