From 6fb5eeca7c0647b07c8c60ed7010563a1ec12f0e Mon Sep 17 00:00:00 2001 From: Ash827 Date: Wed, 16 Sep 2020 23:34:19 -0400 Subject: [PATCH 1/8] getting there --- Data_Structures_Questions.md | 2 +- queue/queue.py | 22 ++++- singly_linked_list/singly_linked_list.py | 121 +++++++++++++++++++++++ stack/stack.py | 17 +++- 4 files changed, 153 insertions(+), 9 deletions(-) diff --git a/Data_Structures_Questions.md b/Data_Structures_Questions.md index 4446a05144..2de933abec 100644 --- a/Data_Structures_Questions.md +++ b/Data_Structures_Questions.md @@ -2,7 +2,7 @@ Answer the following questions for each of the data structures you implemented a ## Stack -1. What is the runtime complexity of `push` using a list? +1. What is the runtime complexity of `push` using a list? 2. What is the runtime complexity of `push` using a linked list? diff --git a/queue/queue.py b/queue/queue.py index 0d2599ded7..7622111c85 100644 --- a/queue/queue.py +++ b/queue/queue.py @@ -13,16 +13,30 @@ Stretch: What if you could only use instances of your Stack class to implement the Queue? What would that look like? How many Stacks would you need? Try it! """ +import sys + +sys.path.append('./singly_linked_list') + +from singly_linked_list import LinkedList + +from math import ceil + class Queue: def __init__(self): self.size = 0 - # self.storage = ? + self.storage = [] + def __len__(self): - pass + return self.size def enqueue(self, value): - pass + self.storage.insert(0, value) + self.size += 1 def dequeue(self): - pass + if self.size == 0: + return None + else: + self.size -= 1 + return self.storage.pop() diff --git a/singly_linked_list/singly_linked_list.py b/singly_linked_list/singly_linked_list.py index e69de29bb2..592d45fdcf 100644 --- a/singly_linked_list/singly_linked_list.py +++ b/singly_linked_list/singly_linked_list.py @@ -0,0 +1,121 @@ + # a class that represents the individual elements in our LL + + +class Node: + def __init__(self, value=None, next_node=None): + self.value = value + self.next_node = next_node + + def get_value(self): + return self.value + + def get_next_node(self): + return self.next_node + + def set_next_node(self, new_next): + self.next_node = new_next + + +class LinkedList: + def __init__(self): + # what attributes do we need? + self.head = None + self.tail = None + + def add_to_head(self, value): + # create a new Node + new_node = Node(value) + if self.head is None: + # update head and tail attributes + self.head = new_node + self.tail = new_node + else: + # set next_node of my new Node to the head + new_node.set_next_node(self.head) + # update head attribute + self.head = new_node + + def add_to_tail(self, value): + # create a new Node + new_node = Node(value) + # 1. LL is empty + if self.head is None: + # update head & tail attributes + self.head = new_node + self.tail = new_node + + # 2 LL is NOT empty + else: + # update next_node of our tail + self.tail.set_next_node(new_node) + # update self.tail + self.tail = new_node + + def remove_head(self): + # empty list + if self.head is None: + return None + # else, return Value of the old head + else: + ret_value = self.head.get_value() + # list with 1 element + if self.head == self.tail: + self.head = None + self.tail = None + # list with +2 elements + else: + self.head = self.head.get_next_node() + return ret_value + + def remove_tail(self): + # empty list + if self.tail is None: + return None + # else, return value of the old tail + elif self.head == self.tail: + value = self.tail.get_value() + self.head = None + self.tail = None + return value + else: + # else set head to current + cur = self.head + # then while there are nodes afterward + while cur.get_next_node() != self.tail: + # change the current node to the next node, iterate + cur = cur.get_next_node() + # once the next node is none, set the current node to previous, and add none after it + value = self.tail.get_value() + cur.set_next_node(None) + # set that previous value to the new tail + self.tail = cur + # return the tail + return value + + def contains(self, value): + # loop through LL until pointer is None + cur_node = self.head + while cur_node is not None: + # if we find 'value' + if cur_node.get_value() == value: + return True + # next_node + cur_node = cur_node.get_next_node() + return False + + def get_max(self): + # empty list + if self.head is None: + return None + # iterate through all elements + cur_node = self.head + # set max to first node + cur_max = self.head.get_value() + while cur_node is not None: + # search for higher values + if cur_node.get_value() > cur_max: + # set new max + cur_max = cur_node.get_value() + # move on to next node + cur_node = cur_node.get_next_node() + return cur_max \ No newline at end of file diff --git a/stack/stack.py b/stack/stack.py index 6e6d660ac7..04cfda1be0 100644 --- a/stack/stack.py +++ b/stack/stack.py @@ -10,16 +10,25 @@ 3. What is the difference between using an array vs. a linked list when implementing a Stack? """ +import sys + +sys.path.append('./singly_linked_list') + +from singly_linked_list import LinkedList + class Stack: def __init__(self): self.size = 0 - # self.storage = ? + self.storage = [] def __len__(self): - pass + return self.size def push(self, value): - pass + self.storage.append(value) + self.size += 1 def pop(self): - pass + if self.size > 0: + self.size -= 1 + return self.storage.pop() From 0e16e7b67a414af17c4e36b241baf3d25a2f7c8e Mon Sep 17 00:00:00 2001 From: Ash827 Date: Thu, 17 Sep 2020 22:43:18 -0400 Subject: [PATCH 2/8] homework 1 finished --- queue/queue.py | 8 ----- singly_linked_list/singly_linked_list.py | 44 ++++++++++++++---------- stack/stack.py | 6 ---- 3 files changed, 25 insertions(+), 33 deletions(-) diff --git a/queue/queue.py b/queue/queue.py index 7622111c85..782eb50219 100644 --- a/queue/queue.py +++ b/queue/queue.py @@ -13,14 +13,6 @@ Stretch: What if you could only use instances of your Stack class to implement the Queue? What would that look like? How many Stacks would you need? Try it! """ -import sys - -sys.path.append('./singly_linked_list') - -from singly_linked_list import LinkedList - -from math import ceil - class Queue: def __init__(self): self.size = 0 diff --git a/singly_linked_list/singly_linked_list.py b/singly_linked_list/singly_linked_list.py index 592d45fdcf..52b6ec78fb 100644 --- a/singly_linked_list/singly_linked_list.py +++ b/singly_linked_list/singly_linked_list.py @@ -3,8 +3,8 @@ class Node: def __init__(self, value=None, next_node=None): - self.value = value - self.next_node = next_node + self.value = value + self.next_node = next_node def get_value(self): return self.value @@ -69,28 +69,34 @@ def remove_head(self): def remove_tail(self): # empty list - if self.tail is None: + # return None + if self.head is None: return None - # else, return value of the old tail + # list with 1 element + # save the value... update head and tail attr = None + # then return value elif self.head == self.tail: - value = self.tail.get_value() + ret_value = self.tail.get_value() self.head = None self.tail = None - return value + return ret_value + # list with +2 elements? + # save value of tail + # ref a temp node + # while node is not the tail + # keep going + # update pointer of temp node (prev_tail) to None + # return value else: - # else set head to current - cur = self.head - # then while there are nodes afterward - while cur.get_next_node() != self.tail: - # change the current node to the next node, iterate - cur = cur.get_next_node() - # once the next node is none, set the current node to previous, and add none after it - value = self.tail.get_value() - cur.set_next_node(None) - # set that previous value to the new tail - self.tail = cur - # return the tail - return value + ret_value = self.tail.get_value() + + cur_node = self.head + while cur_node.get_next_node() is not self.tail: + cur_node = cur_node.get_next_node() + + cur_node.set_next_node(None) + self.tail = cur_node + return ret_value def contains(self, value): # loop through LL until pointer is None diff --git a/stack/stack.py b/stack/stack.py index 04cfda1be0..ac496cce31 100644 --- a/stack/stack.py +++ b/stack/stack.py @@ -10,12 +10,6 @@ 3. What is the difference between using an array vs. a linked list when implementing a Stack? """ -import sys - -sys.path.append('./singly_linked_list') - -from singly_linked_list import LinkedList - class Stack: def __init__(self): self.size = 0 From f271d871ff4e7512301a7e119bc289b570c9ba7d Mon Sep 17 00:00:00 2001 From: Ash827 Date: Thu, 17 Sep 2020 23:34:33 -0400 Subject: [PATCH 3/8] DLL during lecture --- doubly_linked_list/doubly_linked_list.py | 50 +++++++++++++++++++++--- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/doubly_linked_list/doubly_linked_list.py b/doubly_linked_list/doubly_linked_list.py index 6f91b43a9b..4417ff11a3 100644 --- a/doubly_linked_list/doubly_linked_list.py +++ b/doubly_linked_list/doubly_linked_list.py @@ -7,6 +7,12 @@ def __init__(self, value, prev=None, next=None): self.prev = prev self.value = value self.next = next + + def delete(self): + if self.prev: + self.next.prev = self.prev + if self.next: + self.prev.next = self.next """ Our doubly-linked list class. It holds references to @@ -27,8 +33,20 @@ def __len__(self): the old head node's previous pointer accordingly. """ def add_to_head(self, value): - pass - + # create new_node + new_node = ListNode(value) + # 1. add to empty + if self.head is None: + self.head = new_node + self.tail = new_node + # 2. add to nonempty + else: + new_node.next = self.head + self.head.prev = new_node + self.head = new_node + # update length + self.length += 1 + """ Removes the List's current head node, making the current head's next node the new head of the List. @@ -58,8 +76,14 @@ def remove_from_tail(self): List and inserts it as the new head node of the List. """ def move_to_front(self, node): - pass - + # 1. delete() + if node is self.head: + return + self.delete(node) + # 2. add_to_head() + self.add_to_head(node.value) + + """ Removes the input node from its current spot in the List and inserts it as the new tail node of the List. @@ -72,7 +96,23 @@ def move_to_end(self, node): order of the other elements of the List. """ def delete(self, node): - pass + # don't need to return value + # DO need to update head and tail + if self.head is None: + return None + elif self.head is self.tail: + self.head = None + self.tail = None + elif node is self.head: # list has +2 nodes + self.head = node.next + node.delete() # updating prev and/or nest pointers + elif node is self.tail: + self.tail = node.prev + node.delete() + else: + node.delete() + + self.length -= 1 """ Finds and returns the maximum value of all the nodes From 62f7c1dedbbf63dc71a5c6209f76579ddd45ad40 Mon Sep 17 00:00:00 2001 From: Ash827 Date: Sun, 20 Sep 2020 23:09:46 -0400 Subject: [PATCH 4/8] DLL assignment --- doubly_linked_list/doubly_linked_list.py | 88 +++++++++++++++++++++--- singly_linked_list/singly_linked_list.py | 2 +- 2 files changed, 78 insertions(+), 12 deletions(-) diff --git a/doubly_linked_list/doubly_linked_list.py b/doubly_linked_list/doubly_linked_list.py index 4417ff11a3..cd9e4d7fd2 100644 --- a/doubly_linked_list/doubly_linked_list.py +++ b/doubly_linked_list/doubly_linked_list.py @@ -3,10 +3,10 @@ as well as its next node in the List. """ class ListNode: - def __init__(self, value, prev=None, next=None): - self.prev = prev + def __init__(self, value, prev_node=None, next_node=None): + self.prev = prev_node self.value = value - self.next = next + self.next = next_node def delete(self): if self.prev: @@ -53,23 +53,67 @@ def add_to_head(self, value): Returns the value of the removed Node. """ def remove_from_head(self): - pass - + # empty list + if self.head is None and self.tail is None: + return None + else: + # store head value before removal + value = self.head.value + # with 1 element + if self.head == self.tail: + self.head = None + self.tail = None + self.length = 0 + return value + self.head = self.head.next + if self.head: + self.head.prev = None + self.length -= 1 + return value + """ Wraps the given value in a ListNode and inserts it as the new tail of the list. Don't forget to handle the old tail node's next pointer accordingly. """ def add_to_tail(self, value): - pass - + new_node = ListNode(value) + # empty list + if self.head is None and self.tail is None: + # set new_node to head and tail + self.head = new_node + self.tail = new_node + else: + # have the current tail's 'next' pointing to the new node + self.tail.next = new_node + # then set the new node to now be the tail + self.tail = new_node + self.length += 1 + """ Removes the List's current tail node, making the current tail's previous node the new tail of the List. Returns the value of the removed Node. """ def remove_from_tail(self): - pass + self.length -= 1 + # empty list + if self.head is None and self.tail is None: + return + else: + # store tail value before removal + value = self.tail.value + # 1 element + if self.tail == self.head: + self.tail = None + self.head = None + self.length = 0 + return value + self.tail = self.tail.prev + if self.tail: + self.tail.next = None + self.length -= 1 + return value """ Removes the input node from its current spot in the @@ -89,7 +133,13 @@ def move_to_front(self, node): List and inserts it as the new tail node of the List. """ def move_to_end(self, node): - pass + value = node.value + if self.head == node: + self.head = self.head.next + self.head.prev = None + node.delete() + self.length -= 1 + self.add_to_tail(value) """ Deletes the input node from the List, preserving the @@ -105,7 +155,7 @@ def delete(self, node): self.tail = None elif node is self.head: # list has +2 nodes self.head = node.next - node.delete() # updating prev and/or nest pointers + node.delete() # updating prev and/or next pointers elif node is self.tail: self.tail = node.prev node.delete() @@ -119,4 +169,20 @@ def delete(self, node): in the List. """ def get_max(self): - pass \ No newline at end of file + # empty list + if not self.head: + return + # start with the head as the current value + current = self.head + # the current node is the max, for now + max = current.value + # while we can continue to iterate + while current: + # if the current node is greater than the max + if current.value > max: + # then this node becomes the new maximum! + max = current.value + # go to the next value (if it's None, the loop will end) + current = current.next + # once all values have been checked, return the max value + return max diff --git a/singly_linked_list/singly_linked_list.py b/singly_linked_list/singly_linked_list.py index 52b6ec78fb..46b8b0b548 100644 --- a/singly_linked_list/singly_linked_list.py +++ b/singly_linked_list/singly_linked_list.py @@ -124,4 +124,4 @@ def get_max(self): cur_max = cur_node.get_value() # move on to next node cur_node = cur_node.get_next_node() - return cur_max \ No newline at end of file + return cur_max From 98b2fdc0d2900fc0530523490a9ff644df19ad5b Mon Sep 17 00:00:00 2001 From: Ash827 Date: Mon, 21 Sep 2020 23:38:30 -0400 Subject: [PATCH 5/8] homework --- binary_search_tree/binary_search_tree.py | 25 ++++++++++- doubly_linked_list/doubly_linked_list.py | 54 +++++++++--------------- 2 files changed, 42 insertions(+), 37 deletions(-) diff --git a/binary_search_tree/binary_search_tree.py b/binary_search_tree/binary_search_tree.py index d80d9f6282..3acc1ad90a 100644 --- a/binary_search_tree/binary_search_tree.py +++ b/binary_search_tree/binary_search_tree.py @@ -17,12 +17,33 @@ def __init__(self, value): # Insert the given value into the tree def insert(self, value): - pass + # RECURSIVE + # if value < root, go left + # if left child is None + # add here... left child = bstnode(value) + # else + self.left.insert(value) # recursive call + + # if value >= root, go right (dupes go to the right) + # if right child is None + # add here + # else + self.right.insert(value) # recursive call + +""" # ITERATIVE - Need a loop + # while not at bottom level of tree + # if value < root, go left + # if left child is None + # add here +""" # Return True if the tree contains the value # False if it does not def contains(self, target): - pass + # check if self.value is target + # if yes, return True + # if no... + # go left or right? # Return the maximum value found in the tree def get_max(self): diff --git a/doubly_linked_list/doubly_linked_list.py b/doubly_linked_list/doubly_linked_list.py index cd9e4d7fd2..42b7036c22 100644 --- a/doubly_linked_list/doubly_linked_list.py +++ b/doubly_linked_list/doubly_linked_list.py @@ -10,9 +10,9 @@ def __init__(self, value, prev_node=None, next_node=None): def delete(self): if self.prev: - self.next.prev = self.prev - if self.next: self.prev.next = self.next + if self.next: + self.next.prev = self.prev """ Our doubly-linked list class. It holds references to @@ -53,23 +53,10 @@ def add_to_head(self, value): Returns the value of the removed Node. """ def remove_from_head(self): - # empty list - if self.head is None and self.tail is None: - return None - else: - # store head value before removal - value = self.head.value - # with 1 element - if self.head == self.tail: - self.head = None - self.tail = None - self.length = 0 - return value - self.head = self.head.next - if self.head: - self.head.prev = None - self.length -= 1 - return value + # save value to return + value = self.head.value + self.delete(self.head) + return value """ Wraps the given value in a ListNode and inserts it @@ -170,19 +157,16 @@ def delete(self, node): """ def get_max(self): # empty list - if not self.head: - return - # start with the head as the current value - current = self.head - # the current node is the max, for now - max = current.value - # while we can continue to iterate - while current: - # if the current node is greater than the max - if current.value > max: - # then this node becomes the new maximum! - max = current.value - # go to the next value (if it's None, the loop will end) - current = current.next - # once all values have been checked, return the max value - return max + if self.head is None: + return None + # keep track of current node + # keep track of max + cur_node = self.head + max_value = self.head.value + # loop through DLL + while cur_node: # same as saying is not none + # comparing with cur_max + if cur_node.value > max_value: + max_value = cur_node.value + cur_node = cur_node.next + return max_value \ No newline at end of file From e77682a2614c4b64bdad598b7e79f6ed17d71a58 Mon Sep 17 00:00:00 2001 From: Ash827 Date: Sat, 26 Sep 2020 18:18:19 -0400 Subject: [PATCH 6/8] catching up --- binary_search_tree/binary_search_tree.py | 71 +++++++++++++++++------- 1 file changed, 51 insertions(+), 20 deletions(-) diff --git a/binary_search_tree/binary_search_tree.py b/binary_search_tree/binary_search_tree.py index 3acc1ad90a..24c25ef710 100644 --- a/binary_search_tree/binary_search_tree.py +++ b/binary_search_tree/binary_search_tree.py @@ -9,6 +9,8 @@ 2. Implement the `in_order_print`, `bft_print`, and `dft_print` methods on the BSTNode class. """ + + class BSTNode: def __init__(self, value): self.value = value @@ -17,18 +19,21 @@ def __init__(self, value): # Insert the given value into the tree def insert(self, value): - # RECURSIVE - # if value < root, go left - # if left child is None - # add here... left child = bstnode(value) - # else - self.left.insert(value) # recursive call - - # if value >= root, go right (dupes go to the right) - # if right child is None - # add here - # else - self.right.insert(value) # recursive call + if (self.left is None) & (self.right is None): # Empty tree use case + if value >= self.value: + self.right = BSTNode(value) + else: + self.left = BSTNode(value) + elif (value < self.value): # value goes to left branch of root + if self.left is None: + self.left = BSTNode(value) + else: + self.left.insert(value) + else: # Value goes to the right branch of root + if self.right is None: + self.right = BSTNode(value) + else: + self.right.insert(value) """ # ITERATIVE - Need a loop # while not at bottom level of tree @@ -40,30 +45,56 @@ def insert(self, value): # Return True if the tree contains the value # False if it does not def contains(self, target): - # check if self.value is target - # if yes, return True - # if no... - # go left or right? + if self.value == target: + return True + elif target < self.value: + if self.left is None: + return False + else: return self.left.contains(target) + else: + if self.right is None: + return False + else: + return self.right.contains(target) # Return the maximum value found in the tree def get_max(self): - pass + # go right until you cannot anymore + # return value at far right + if self.right is None: + return self.value + else: + self.right.get_max() # Call the function `fn` on the value of each node def for_each(self, fn): - pass + # one side then the other - RECURSION + # fn(value) + if self.value != None: + fn(self.value) + if self.left is not None and self.right is not None: + self.left.for_each(fn) + self.right.for_each(fn) + elif self.right is not None: + self.right.for_each(fn) + elif self.left is not None: + self.left.for_each(fn) + elif self.left is None and self.right is None: + return None + else: + return None # Part 2 ----------------------- # Print all the values in order from low to high # Hint: Use a recursive, depth first traversal def in_order_print(self): - pass + # Print the value of every node, starting with the given node, # in an iterative breadth first traversal def bft_print(self): - pass + # Print the value of every node, starting with the given node, # in an iterative depth first traversal From afa5d5d2568ca4b023a5afd24222330a2a6bd80b Mon Sep 17 00:00:00 2001 From: Ash827 Date: Sun, 27 Sep 2020 23:03:48 -0400 Subject: [PATCH 7/8] more complete --- binary_search_tree/binary_search_tree.py | 77 +++++++++++++++++------- queue/queue.py | 1 + stack/stack.py | 1 + 3 files changed, 56 insertions(+), 23 deletions(-) diff --git a/binary_search_tree/binary_search_tree.py b/binary_search_tree/binary_search_tree.py index 24c25ef710..855df75664 100644 --- a/binary_search_tree/binary_search_tree.py +++ b/binary_search_tree/binary_search_tree.py @@ -9,7 +9,7 @@ 2. Implement the `in_order_print`, `bft_print`, and `dft_print` methods on the BSTNode class. """ - +from queue import Queue class BSTNode: def __init__(self, value): @@ -41,7 +41,6 @@ def insert(self, value): # if left child is None # add here """ - # Return True if the tree contains the value # False if it does not def contains(self, target): @@ -60,7 +59,7 @@ def contains(self, target): # Return the maximum value found in the tree def get_max(self): # go right until you cannot anymore - # return value at far right + # return value if self.right is None: return self.value else: @@ -68,38 +67,70 @@ def get_max(self): # Call the function `fn` on the value of each node def for_each(self, fn): - # one side then the other - RECURSION - # fn(value) - if self.value != None: - fn(self.value) - if self.left is not None and self.right is not None: - self.left.for_each(fn) - self.right.for_each(fn) - elif self.right is not None: - self.right.for_each(fn) - elif self.left is not None: - self.left.for_each(fn) - elif self.left is None and self.right is None: - return None - else: - return None + fn(self.value) + # base case - no children + if self.left is None and self.right is None: + return + # recursive case - 1 or more children + # go left, call fn(value) for each node + if self.left: + self.left.for_each(fn) + # go right, call fn(value) for each node + if self.right: + self.right.for_each(fn) # Part 2 ----------------------- # Print all the values in order from low to high # Hint: Use a recursive, depth first traversal def in_order_print(self): - + pass # Print the value of every node, starting with the given node, # in an iterative breadth first traversal def bft_print(self): - + # instantiate a Queue + q = Queue() + # insert the value + q.enqueue(self) + + # while length of q is greater than 0 + while q.size > 0: + # pop off the top + top = q.dequeue() + # print it + print(top.value) + # if there is a left child + if top.left: + # add left child to queue + q.enqueue(top.left) + # if there is a right child + if top.right: + # add right child to queue + q.enqueue(top.right) # Print the value of every node, starting with the given node, # in an iterative depth first traversal def dft_print(self): - pass + # create a stack to keep track of nodes we are processing + # push self into stack + # if a tree exists + if self: + # print the current value (as it's the first traversal) + print(self.value) + # if there is a left child + if self.left: + # re-run function with left child as root of tree + self.left.dft_print() + # if there is a right child + if self.right: + # re-run function with right child as root of tree + self.right.dft_print() + # while something still in the stack (not done processing all nodes) + # use existing 'for_each' as a reference for the traversal logic + # push when we START, pop when a node is DONE + # and don't forget to call print() + # Stretch Goals ------------------------- # Note: Research may be required @@ -112,9 +143,9 @@ def pre_order_dft(self): def post_order_dft(self): pass -""" + """ This code is necessary for testing the `print` methods -""" + """ bst = BSTNode(1) bst.insert(8) diff --git a/queue/queue.py b/queue/queue.py index 782eb50219..db7088411f 100644 --- a/queue/queue.py +++ b/queue/queue.py @@ -32,3 +32,4 @@ def dequeue(self): else: self.size -= 1 return self.storage.pop() +# first in first out diff --git a/stack/stack.py b/stack/stack.py index ac496cce31..cc384ab515 100644 --- a/stack/stack.py +++ b/stack/stack.py @@ -26,3 +26,4 @@ def pop(self): if self.size > 0: self.size -= 1 return self.storage.pop() +# last in first out \ No newline at end of file From 4df7516f02baca9d9c7e5241c56b5f27ed068909 Mon Sep 17 00:00:00 2001 From: Ashley Gaskins Date: Thu, 3 Dec 2020 09:40:46 -0500 Subject: [PATCH 8/8] pep8 cleanup --- binary_search_tree/binary_search_tree.py | 33 +++++++++++------------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/binary_search_tree/binary_search_tree.py b/binary_search_tree/binary_search_tree.py index 855df75664..117fececfd 100644 --- a/binary_search_tree/binary_search_tree.py +++ b/binary_search_tree/binary_search_tree.py @@ -1,8 +1,7 @@ """ -Binary search trees are a data structure that enforce an ordering over -the data they store. That ordering in turn makes it a lot more efficient -at searching for a particular piece of data in the tree. - +Binary search trees are a data structure that enforce an ordering over +the data they store. That ordering in turn makes it a lot more efficient +at searching for a particular piece of data in the tree. This part of the project comprises two days: 1. Implement the methods `insert`, `contains`, `get_max`, and `for_each` on the BSTNode class. @@ -11,6 +10,7 @@ """ from queue import Queue + class BSTNode: def __init__(self, value): self.value = value @@ -19,37 +19,35 @@ def __init__(self, value): # Insert the given value into the tree def insert(self, value): - if (self.left is None) & (self.right is None): # Empty tree use case + # Empty tree use case + if (self.left is None) & (self.right is None): if value >= self.value: self.right = BSTNode(value) else: self.left = BSTNode(value) - elif (value < self.value): # value goes to left branch of root + elif (value < self.value): + # value goes to left branch of root if self.left is None: self.left = BSTNode(value) else: self.left.insert(value) - else: # Value goes to the right branch of root + else: + # Value goes to the right branch of root if self.right is None: self.right = BSTNode(value) else: self.right.insert(value) - -""" # ITERATIVE - Need a loop - # while not at bottom level of tree - # if value < root, go left - # if left child is None - # add here -""" # Return True if the tree contains the value # False if it does not + def contains(self, target): if self.value == target: return True elif target < self.value: if self.left is None: return False - else: return self.left.contains(target) + else: + return self.left.contains(target) else: if self.right is None: return False @@ -95,7 +93,7 @@ def bft_print(self): q.enqueue(self) # while length of q is greater than 0 - while q.size > 0: + while q.size > 0: # pop off the top top = q.dequeue() # print it @@ -131,7 +129,6 @@ def dft_print(self): # push when we START, pop when a node is DONE # and don't forget to call print() - # Stretch Goals ------------------------- # Note: Research may be required @@ -165,4 +162,4 @@ def post_order_dft(self): print("in order") bst.in_order_dft() print("post order") -bst.post_order_dft() +bst.post_order_dft()