-
Notifications
You must be signed in to change notification settings - Fork 1
Traversal bst #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
1d1a5e9
6f6a938
565e132
98c5039
0ecf7b2
c174663
597732f
8f5b2ac
5c46d3b
71ec1a7
c5587dc
994d3cb
a2afe95
afecfc5
f407dc3
c86b4f2
584ed8e
97c1573
23f848f
aba9fa0
ce9921e
0117406
df85d06
dde70ae
a56c6bd
f7f2aba
ba81221
f2a0d81
b52b36f
da8a93b
e689fae
68ff199
2a1e82a
26d6e09
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,32 +1,19 @@ | ||
| #Summary | ||
|
|
||
| The assignment was to implement a [Weighted Graph](https://codefellows.github.io/sea-python-401d5/assignments/graph_3_weighted.html) | ||
| in Python containing the following methods: | ||
|
|
||
|
|
||
| * g.nodes(): return a list of all nodes in the graph | ||
| * g.edges(): return a list of all edges in the graph | ||
| * g.add_node(n): adds a new node 'n' to the graph | ||
| * g.add_edge(n1, n2): adds a new edge to the graph connecting 'n1' and 'n2', if either n1 or n2 are not already present in the graph, they should be added. | ||
| * g.del_node(n): deletes the node 'n' from the graph, raises an error if no such node exists | ||
| * g.del_edge(n1, n2): deletes the edge connecting 'n1' and 'n2' from the graph, raises an error if no such edge exists | ||
| * g.has_node(n): True if node 'n' is contained in the graph, False if not. | ||
| * g.neighbors(n): returns the list of all nodes connected to 'n' by edges, raises an error if n is not in g | ||
| * g.adjacent(n1, n2): returns True if there is an edge connecting n1 and n2, False if not, raises an error if either of the supplied nodes are not in g | ||
| * g.depth_first_traversal(start): Returns the path list for the entire graph with a depth first traversal. | ||
| * g.breadth_first_travers(start): Returns the path list for the entire graph with a breadth first traversal. | ||
|
|
||
| in_order(self): will return a generator that will return the values in the tree using in-order traversal, one at a time. | ||
| pre_order(self): will return a generator that will return the values in the tree using pre-order traversal, one at a time. | ||
| post_order(self): will return a generator that will return the values in the tree using post_order traversal, one at a time. | ||
| breadth_first(self): will return a generator that will return the values in the tree using breadth-first traversal, one at a time. | ||
|
|
||
| # Coverage: | ||
|
|
||
| ---------- coverage: platform darwin, python 3.5.2-final-0 ----------- | ||
|
|
||
|
|
||
| | Name | Stmts | Miss | Cover | | ||
| | ----------------------- | ----- | ---- | ----- | | ||
| | weighted_graph.py | 78 | 3 | 96% | | ||
| | test_weighted_graph.py | 178 | 0 | 100% | | ||
| | ----------------------- | --- | -- | ---- | | ||
| | TOTAL | 256 | 3 | 98% | | ||
| ---------- coverage: platform darwin, python 2.7.12-final-0 ---------- | ||
| Name Stmts Miss Cover Missing | ||
| ----------------------------------------------------------- | ||
| src/bst.py 121 36 70% 39-40, 73, 92-94, 124, 143, 156-160, 164, 168-182, 186, 190-19 | ||
|
|
||
|
|
||
| ---------- coverage: platform darwin, python 3.5.2-final-0 ----------- | ||
| Name Stmts Miss Cover Missing | ||
| ----------------------------------------------------------- | ||
| src/bst.py 121 36 70% 39-40, 73, 92-94, 124, 143, 156-160, 164, 168-182, 186, 190-198 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,198 @@ | ||
| """Module for Binary Search Tree.""" | ||
|
|
||
| from queue_ds import Queue | ||
|
|
||
|
|
||
| class Node(object): | ||
| """Node class.""" | ||
|
|
||
| def __init__(self, value=None, left=None, right=None): | ||
| """Init of the Node class.""" | ||
| self.value = value | ||
| self.left = left | ||
| self.right = right | ||
|
|
||
|
|
||
| class BinarySearchTree(object): | ||
| """Binary Search Tree.""" | ||
|
|
||
| """insert(self, val): will insert the value val into the BST. If val is already present, it will be ignored.""" | ||
| """search(self, val): will return the node containing that value, else None""" | ||
| """size(self): will return the integer size of the BST (equal to the total number of values stored in the tree). It will return 0 if the tree is empty.""" | ||
| """depth(self): will return an integer representing the total number of levels in the tree. If there is one value, the depth should be 1, if two values it will be 2, if three values it may be 2 or three, depending, etc.""" | ||
| """contains(self, val): will return True if val is in the BST, False if not.""" | ||
| """balance(self): will return an integer, positive or negative that represents how well balanced the tree is. Trees which are higher on the left than the right should return a positive value, trees which are higher on the right than the left should return a negative value. An ideally-balanced tree should return 0.""" | ||
| """in_order(self): will return a generator that will return the values in the tree using in-order traversal, one at a time.""" | ||
| """pre_order(self): will return a generator that will return the values in the tree using pre-order traversal, one at a time.""" | ||
| """post_order(self): will return a generator that will return the values in the tree using post_order traversal, one at a time.""" | ||
| """breadth_first(self): will return a generator that will return the values in the tree using breadth-first traversal, one at a time.""" | ||
|
|
||
| def __init__(self, if_iter=None): | ||
| """Init of the Binary Search Tree class.""" | ||
| self.root = None | ||
| self.counter = 0 | ||
| self.container = [] | ||
| if if_iter: | ||
| try: | ||
| for value in if_iter: | ||
| self.insert(value) | ||
| except TypeError: | ||
| self.insert(if_iter) | ||
| self._in_order = self.in_order_trav() | ||
| self._pre_order = self.pre_order_trav() | ||
| self._post_order = self.post_order_trav() | ||
|
|
||
| def insert(self, val): | ||
| """Take a value, inserts into Binary Search Tree at correct placement.""" | ||
| if self.root is None: | ||
| self.root = Node(val) | ||
| self.counter += 1 | ||
| self.container.append(val) | ||
|
|
||
| else: | ||
| vertex = self.root | ||
| while True: | ||
| if val > vertex.value: | ||
| if vertex.right: | ||
| vertex = vertex.right | ||
| else: | ||
| vertex.right = Node(val) | ||
| self.counter += 1 | ||
| self.container.append(val) | ||
| break | ||
|
|
||
| elif val < vertex.value: | ||
| if vertex.left: | ||
| vertex = vertex.left | ||
| else: | ||
| vertex.left = Node(val) | ||
| self.counter += 1 | ||
| self.container.append(val) | ||
| break | ||
| else: | ||
| break | ||
|
|
||
| def size(self): | ||
| """Return size of Binary Search Tree.""" | ||
| return self.counter | ||
|
|
||
| def contains(self, val): | ||
| """Return True if val is in the BST, False if not.""" | ||
| return val in self.container | ||
|
|
||
| def search(self, val): | ||
| """Return the node containing that value, else None.""" | ||
| vertex = self.root | ||
| while vertex: | ||
| if val > vertex.value: | ||
| if not vertex.right: | ||
| return None | ||
| vertex = vertex.right | ||
| elif val < vertex.value: | ||
| if not vertex.left: | ||
| return None | ||
| vertex = vertex.left | ||
| else: | ||
| return vertex | ||
| return None | ||
|
|
||
| def depth(self): | ||
| """ | ||
| Return an integer representing the total number of levels in the tree. | ||
|
|
||
| If there is one value, the depth should be 1, if two values it will be 2, | ||
| if three values it may be 2 or three, depending, etc. | ||
| """ | ||
| return self.calc_depth(self.root) | ||
|
|
||
| def calc_depth(self, tree): | ||
| """Calculate the depth of the binary search tree recursively.""" | ||
| if tree is None: | ||
| return 0 | ||
| else: | ||
| return max(self.calc_depth(tree.right), self.calc_depth(tree.left)) + 1 | ||
|
|
||
| def balance(self): | ||
| """ | ||
| Return an integer, positive or negative that represents how well balanced the tree is. | ||
|
|
||
| Trees which are higher on the left than the right should return a positive value, | ||
| trees which are higher on the right than the left should return a negative value. | ||
| An ideally-balanced tree should return 0. | ||
| """ | ||
| if self.root is None: | ||
| return 0 | ||
| return self.calc_depth(self.root.right) - self.calc_depth(self.root.left) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. According to specs, left heavy is positive |
||
|
|
||
| def in_order(self): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I personally like how you are able to have both the generator method, and also be able to simply return the value |
||
| """Return.""" | ||
| return next(self._in_order) | ||
|
|
||
| def in_order_trav(self): | ||
| """Traverse in_order, yielding via generator.""" | ||
| vertex = self.root | ||
| visited = [] | ||
| while (visited or vertex is not None): | ||
|
|
||
| if vertex is not None: | ||
| visited.append(vertex) | ||
| vertex = vertex.left | ||
| else: | ||
| vertex = visited.pop() | ||
| yield vertex.value | ||
| vertex = vertex.right | ||
|
|
||
| def pre_order(self): | ||
| """Return.""" | ||
| return next(self._pre_order) | ||
|
|
||
| def pre_order_trav(self): | ||
| """Traverse pre_order, yielding via generator.""" | ||
| vertex = self.root | ||
| visited = [] | ||
| while (visited or vertex is not None): | ||
| if vertex is not None: | ||
| yield vertex.value | ||
| visited.append(vertex) | ||
| vertex = vertex.left | ||
| else: | ||
| vertex = visited.pop() | ||
| vertex = vertex.right | ||
|
|
||
| def post_order(self): | ||
| """Return.""" | ||
| return next(self._post_order) | ||
|
|
||
| def post_order_trav(self): | ||
| """Traverse pre_order, yielding via generator.""" | ||
| vertex = self.root | ||
| peek_vertex = None | ||
| last_vertex = None | ||
| visited = [] | ||
| while (visited or vertex is not None): | ||
| if vertex is not None: | ||
| visited.append(vertex) | ||
| vertex = vertex.left | ||
| else: | ||
| peek_vertex = visited[-1] | ||
| if peek_vertex.right and peek_vertex.right is not last_vertex: | ||
| vertex = peek_vertex.right | ||
| else: | ||
| yield peek_vertex.value | ||
| last_vertex = visited.pop() | ||
|
|
||
| def breadth_first(self): | ||
| """Fill in later.""" | ||
| return next(self._breadth_first) | ||
|
|
||
| def breadth_first_trav(self): | ||
| """Traverse breadth first order, yielding a generator.""" | ||
| q = Queue() | ||
| q.enqueue(self.root) | ||
| while len(q) > 0: | ||
| vertex = q.dequeue() | ||
| yield vertex.value | ||
| if (vertex.left): | ||
| q.enqueue(vertex.left) | ||
| if (vertex.right): | ||
| q.enqueue(vertex.right) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if you create a tree with some nodes in it, but then start a traversal, and then add nodes into it before you have completed it?