diff --git a/README.md b/README.md index 35295f4..bb5c59e 100644 --- a/README.md +++ b/README.md @@ -37,17 +37,10 @@ * **๐Ÿ“– algorithms and data structures revisited (2023)**: - * ๐Ÿ˜๐Ÿ˜๐Ÿ™๐Ÿ˜. **[arrays, vectors, strings](arrays_and_strings)** + * ๐Ÿ˜๐Ÿ˜๐Ÿ™๐Ÿ˜. **[arrays and strings](arrays_and_strings)** * ๐Ÿ˜๐Ÿ˜๐Ÿ™๐Ÿ™. **[linked lists](linked_lists)** * ๐Ÿ˜๐Ÿ™๐Ÿ˜๐Ÿ˜. **[stacks and queues](stacks_and_queues)** * ๐Ÿ˜๐Ÿ™๐Ÿ˜๐Ÿ™. **[bit manipulation](bit_manipulation)** * ๐Ÿ˜๐Ÿ™๐Ÿ™๐Ÿ˜. **[math and logic](math_and_logic)** - * ๐Ÿ˜๐Ÿ™๐Ÿ™๐Ÿ™. **[object-oriented design](object_oriented_design)** - * ๐Ÿ™๐Ÿ˜๐Ÿ˜๐Ÿ˜. **[recursion and dynamic programming](recursion_and_dp)** * ๐Ÿ™๐Ÿ˜๐Ÿ˜๐Ÿ™. **[sorting and searching](sorting_and_searching)** - * ๐Ÿ™๐Ÿ˜๐Ÿ™๐Ÿ˜. **[concurrency](concurrency)** - * ๐Ÿ™๐Ÿ˜๐Ÿ™๐Ÿ™. **[trees and graphs](trees_and_graphs/)** - - [trees, nodes, binary trees, binary search, trees](trees_and_graphs/Trees.py) - - - \ No newline at end of file + * ๐Ÿ™๐Ÿ˜๐Ÿ™๐Ÿ™. **[trees, transversals, graphs](trees_and_graphs/)** diff --git a/arrays_and_strings/README.md b/arrays_and_strings/README.md index e69de29..f63f4e8 100644 --- a/arrays_and_strings/README.md +++ b/arrays_and_strings/README.md @@ -0,0 +1,55 @@ +## arrays and strings + +
+ +### `is_palindrome.py` + +
+ +```python +python3 is_palindrome.py + +Testing is_palindrome()... +Is subi no onibus a palindrone?: True +Is helllo there a palindrone?: False +``` + +
+ +### `playing_with_strings.py` + +
+ +```python +python3 playing_with_strings.py + +Testing reverse_array_in_place +Array: [1, 2, 3, 4, 5] +Reversed: [5, 4, 3, 2, 1] +``` + +
+ +### `anagram.py` + +
+ +```python +python3 anagram.py + +Testing is_anagram()... +Is listen an anagram of silent?: True +``` + +
+ +### `permutation.py` + +
+ +```python +python3 permutation.py + +Testing permutation()... +Permutation of bt3gl: ['bt3gl', 'bt3lg', 'btg3l', 'btgl3', 'btl3g', 'btlg3', 'b3tgl', 'b3tlg', 'b3gtl', 'b3glt', 'b3ltg', 'b3lgt', 'bgt3l', 'bgtl3', 'bg3tl', 'bg3lt', 'bglt3', 'bgl3t', 'blt3g', 'bltg3', 'bl3tg', 'bl3gt', 'blgt3', 'blg3t', 'tb3gl', 'tb3lg', 'tbg3l', 'tbgl3', 'tbl3g', 'tblg3', 't3bgl', 't3blg', 't3gbl', 't3glb', 't3lbg', 't3lgb', 'tgb3l', 'tgbl3', 'tg3bl', 'tg3lb', 'tglb3', 'tgl3b', 'tlb3g', 'tlbg3', 'tl3bg', 'tl3gb', 'tlgb3', 'tlg3b', '3btgl', '3btlg', '3bgtl', '3bglt', '3bltg', '3blgt', '3tbgl', '3tblg', '3tgbl', '3tglb', '3tlbg', '3tlgb', '3gbtl', '3gblt', '3gtbl', '3gtlb', '3glbt', '3gltb', '3lbtg', '3lbgt', '3ltbg', '3ltgb', '3lgbt', '3lgtb', 'gbt3l', 'gbtl3', 'gb3tl', 'gb3lt', 'gblt3', 'gbl3t', 'gtb3l', 'gtbl3', 'gt3bl', 'gt3lb', 'gtlb3', 'gtl3b', 'g3btl', 'g3blt', 'g3tbl', 'g3tlb', 'g3lbt', 'g3ltb', 'glbt3', 'glb3t', 'gltb3', 'glt3b', 'gl3bt', 'gl3tb', 'lbt3g', 'lbtg3', 'lb3tg', 'lb3gt', 'lbgt3', 'lbg3t', 'ltb3g', 'ltbg3', 'lt3bg', 'lt3gb', 'ltgb3', 'ltg3b', 'l3btg', 'l3bgt', 'l3tbg', 'l3tgb', 'l3gbt', 'l3gtb', 'lgbt3', 'lgb3t', 'lgtb3', 'lgt3b', 'lg3bt', 'lg3tb'] +``` \ No newline at end of file diff --git a/arrays_and_strings/anagram.py b/arrays_and_strings/anagram.py new file mode 100644 index 0000000..3331c75 --- /dev/null +++ b/arrays_and_strings/anagram.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# author: bt3gl + + +def is_anagram(string1, string2) -> bool: + + string1 = string1.lower() + string2 = string2.lower() + + if len(string1) != len(string2): + return False + + for char in string1: + if char not in string2: + return False + + return True + + +if __name__ == '__main__': + + print('Testing is_anagram()...') + string1 = "listen" + string2 = "silent" + print(f'Is {string1} an anagram of {string2}?: {is_anagram(string1, string2)}') diff --git a/arrays_and_strings/palindrome.py b/arrays_and_strings/palindrome.py new file mode 100644 index 0000000..2db9f90 --- /dev/null +++ b/arrays_and_strings/palindrome.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# author: bt3gl + +def is_palindrome(sentence): + + sentence = sentence.strip(' ') + if len(sentence) < 2: + return True + + if sentence[0] == sentence[-1]: + return is_palindrome(sentence[1:-1]) + + return False + + +if __name__ == '__main__': + print('Testing is_palindrome()...') + sentence ="subi no onibus" + print(f'Is {sentence} a palindrone?: {is_palindrome(sentence)}') + + sentence ="helllo there" + print(f'Is {sentence} a palindrone?: {is_palindrome(sentence)}') diff --git a/arrays_and_strings/permutation.py b/arrays_and_strings/permutation.py new file mode 100644 index 0000000..51fefc9 --- /dev/null +++ b/arrays_and_strings/permutation.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# author: bt3gl + + +def permutation(string) -> list: + + if len(string) == 1: + return [string] + + result = [] + for i, char in enumerate(string): + for perm in permutation(string[:i] + string[i+1:]): + result += [char + perm] + + return result + + +if __name__ == '__main__': + print('Testing permutation()...') + string = "bt3gl" + print(f'Permutation of {string}: {permutation(string)}') diff --git a/arrays_and_strings/playing_with_strings.py b/arrays_and_strings/playing_with_strings.py new file mode 100644 index 0000000..58cf41f --- /dev/null +++ b/arrays_and_strings/playing_with_strings.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# author: bt3gl + +def reverse_array_in_place(array): + """ Reverse an array in place """ + return array[::-1] + + +if __name__ == '__main__': + + print('Testing reverse_array_in_place') + array = [1, 2, 3, 4, 5] + print(f'Array: {array}') + print(f'Reversed: {reverse_array_in_place(array)}') diff --git a/bit_manipulation/README.md b/bit_manipulation/README.md index e69de29..1718af3 100644 --- a/bit_manipulation/README.md +++ b/bit_manipulation/README.md @@ -0,0 +1,25 @@ +## bit manipulation + +
+ +### `playing_with_bits.py` + +
+ + +```python +> python3 playing_with_bits.py + +Integer number: 144 +Binary number: 10010000 + +Update bit: 0b10010100 +Set bit: 0b10010100 +Clear bit: 0b10000000 + +I: 144, I2: 90 +B: 10010000, B2: 01011010 +Count bits swapped: 4 + +Swap bit in place: (90, 144) +``` diff --git a/bit_manipulation/playing_with_bits.py b/bit_manipulation/playing_with_bits.py new file mode 100644 index 0000000..b03fa18 --- /dev/null +++ b/bit_manipulation/playing_with_bits.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# author: bt3gl + + +def set_bit(num, i): + mask = 1 << i + return bin( num | mask ) + +def update_bit(num, i, v): + mask = ~ (1 << i) + return bin( (num & mask) | (v << i) ) + +def count_bits_swapped(a, b): + count = 0 + m = a^b + while m: + count +=1 + m = m & (m-1) + return count + +def clear_bit(num, i): + mask = ~ (1 << i) # -0b10001 + return bin(num & mask) + +def swap_bit_in_place(a, b): + a = a^b + b = a^b + a = a^b + return a, b + +def find_how_many_1_in_a_binary(num): + + counter = 0 + while num: + if num & 1: + counter += 1 + num >>= 1 + return counter + + +if __name__ == '__main__': + + binary_number = '10010000' + binary_number2 = '01011010' + integer_number = int(binary_number, 2) + integer_number2 = int(binary_number2, 2) + + print(f'Integer number: {integer_number}') + print(f'Binary number: {binary_number}') + print(f'\nUpdate bit: {update_bit(integer_number, 2, 1)}') + print(f'Set bit: {set_bit(integer_number, 2)}') + print(f'Clear bit: {clear_bit(integer_number, 4)}') + print(f'\nI: {integer_number}, I2: {integer_number2}') + print(f'B: {binary_number}, B2: {binary_number2}') + print(f'Count bits swapped: {count_bits_swapped(integer_number, integer_number2)}') + print(f'\nSwap bit in place: {swap_bit_in_place(integer_number, integer_number2)}') + print(f'Find how many 1 in a binary: {find_how_many_1_in_a_binary(integer_number)}') + \ No newline at end of file diff --git a/book/ebook_src/searching_and_sorting/searching/find_time_occurence_list.py b/book/ebook_src/searching_and_sorting/searching/find_time_occurence_list.py index af26ded..c7fa6e0 100644 --- a/book/ebook_src/searching_and_sorting/searching/find_time_occurence_list.py +++ b/book/ebook_src/searching_and_sorting/searching/find_time_occurence_list.py @@ -2,7 +2,7 @@ __author__ = "bt3" -def binary_serch_counting(lst1, k, lo=0, hi=None): +def binary_search_counting(lst1, k, lo=0, hi=None): if hi is None: hi = len(lst1) while lo < hi: mid = (lo+hi)//2 @@ -24,7 +24,7 @@ def find_time_occurrence_list(seq, k): the dict is fixed. Another way, since the array is sorted, it to use binary search, since this is only O(logn). """ - index_some_k = binary_serch_counting(seq, k) + index_some_k = binary_search_counting(seq, k) count = 1 sizet = len(seq) diff --git a/concurrency/README.md b/concurrency/README.md deleted file mode 100644 index e69de29..0000000 diff --git a/math_and_logic/README.md b/math_and_logic/README.md index e69de29..8dcf2e3 100644 --- a/math_and_logic/README.md +++ b/math_and_logic/README.md @@ -0,0 +1,20 @@ +## math and logic + +
+ + +```python +python3 fibonacci.py + +Testing fibonacci +Fibonacci of 10: 55 +``` + +
+ +```python +python playing_with_math.py + +Greatest common divider of 21 and 7 is 7 +Prime factors of 21 are [3, 7] +``` diff --git a/math_and_logic/fibonacci.py b/math_and_logic/fibonacci.py new file mode 100644 index 0000000..2d92d9e --- /dev/null +++ b/math_and_logic/fibonacci.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# author: bt3gl + +def fibonacci(n): + """ Calculate the nth Fibonacci number """ + if n == 0 or n == 1: + return n + return fibonacci(n - 1) + fibonacci(n - 2) + + +if __name__ == '__main__': + + print('Testing fibonacci') + n = 10 + print(f'Fibonacci of {n}: {fibonacci(n)}') diff --git a/math_and_logic/playing_with_math.py b/math_and_logic/playing_with_math.py new file mode 100644 index 0000000..31e0df3 --- /dev/null +++ b/math_and_logic/playing_with_math.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# author: bt3gl + +import math +import random + + +def find_greatest_common_divider(a, b) -> int: + '''Implements the greatest common divider algorithm ''' + + while(b != 0): + result = b + a, b = b, a % b + + return result + + +def _is_prime(number) -> bool: + '''Check if a number is prime ''' + + if number < 2: + return False + + for i in range(2, int(math.sqrt(number))): + if number % i == 0: + return False + + return True + + +def find_prime_factors(number) -> list: + '''Find prime factors of a number ''' + + divisors = [d for d in range(2, number//2 + 1) if number % d == 0] + primes = [d for d in divisors if _is_prime(d)] + + return primes + + + +if __name__ == '__main__': + + n1 = 21 + n2 = 7 + + print(f'Greatest common divider of {n1} and {n2} is {find_greatest_common_divider(n1, n2)}') + print(f'Prime factors of {n1} are {find_prime_factors(n1)}') + + diff --git a/object_oriented_design/README.md b/object_oriented_design/README.md deleted file mode 100644 index e69de29..0000000 diff --git a/recursion_and_dp/README.md b/recursion_and_dp/README.md deleted file mode 100644 index e69de29..0000000 diff --git a/sorting_and_searching/README.md b/sorting_and_searching/README.md index e69de29..be9e482 100644 --- a/sorting_and_searching/README.md +++ b/sorting_and_searching/README.md @@ -0,0 +1,29 @@ +## sorting and searching + +
+ +### `sorting_algorithms.py` + +
+ +```python +> python3 sorting_algorithms.py + + +Array: [3, 5, 1, 2, 10, 6] +Testing merge sort: [1, 2, 3, 5, 6, 10] +Testing quick sort: [1, 2, 3, 5, 6, 10] +``` + +
+ +### `binary_search.py` + +
+ +```python +> python binary_search.py +Recursive: 6 +Iterative: 6 +``` + diff --git a/sorting_and_searching/binary_search.py b/sorting_and_searching/binary_search.py new file mode 100644 index 0000000..f7a2255 --- /dev/null +++ b/sorting_and_searching/binary_search.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# author: bt3gl + +def binary_search_recursive(array, item, higher=None, lower=0): + + higher = higher or len(array) + if higher < lower: + return False + + mid = (higher + lower)//2 + if item == array[mid]: + return mid + elif item < array[mid]: + return binary_search_recursive(array, item, higher=mid-1, lower=lower) + else: + return binary_search_recursive(array, item, higher=higher, lower=mid+1) + + +def binary_search_iterative(array, item): + lower, higher = 0, len(array) + + while lower < higher: + mid = (higher+lower)//2 + if array[mid] == item: + return mid + elif array[mid] > item: + higher = mid + else: + lower=mid+1 + return False + +def binary_search_matrix(matrix, item, lower=0, higher=None): + """ Binary search in a matrix """ + + if not matrix: + return None + + rows = len(matrix) + cols = len(matrix[0]) + higher = higher or rows*cols + + if higher > lower: + mid = (higher + lower)//2 + row = mid//cols + col = mid%cols + item = matrix[row][col] + + if item == item: + return row, col + elif item < item: + return binary_search_matrix(matrix, item, lower, mid-1) + else: + return binary_search_matrix(matrix, item, mid+1, higher) + + return None + + +if __name__ == '__main__': + + array = [2, 3, 5, 6, 8, 10, 15, 23] + matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] + item = 15 + + print('Recursive: ', binary_search_recursive(array, item)) + print('Iterative: ', binary_search_iterative(array, item)) + print('Matrix: ', binary_search_matrix(matrix, item)) + diff --git a/sorting_and_searching/sorting_algorithms.py b/sorting_and_searching/sorting_algorithms.py new file mode 100644 index 0000000..c9cb66d --- /dev/null +++ b/sorting_and_searching/sorting_algorithms.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# author: bt3gl + + +def merge_sort(array): + """Sort an array using merge sort""" + + # part 1: recursively divide the array into subarrays + if len(array) < 2: + return array + + mid = len(array) // 2 + left = merge_sort(array[:mid]) + right = merge_sort(array[mid:]) + + # part 2: merge the subarrays + result = [] + i, j = 0, 0 + + while i < len(left) and j < len(right): + if left[i] <= right[j]: + result.append(left[i]) + i +=1 + else: + result.append(right[j]) + j +=1 + + if left[i:]: + result.extend(left[i:]) + if right[j:]: + result.extend(right[j:]) + + return result + + +def quick_sort_partition(array): + """Sort an array using quick sort""" + + pivot, array = array[0], array[1:] + + lower = [i for i in array if i <= pivot] + higher = [i for i in array if i > pivot] + + return lower, pivot, higher + + +def quick_sort_divided(array): + """Sort an array using quick sort""" + + if len(array) < 2: + return array + + lower, pivot, higher = quick_sort_partition(array) + return quick_sort_divided(lower) + [pivot] + quick_sort_divided(higher) + + +if __name__ == '__main__': + + array = [3, 5, 1, 2, 10, 6] + print(f'Array: {array}') + + print(f'Testing merge sort: {merge_sort(array)}') + print(f'Testing quick sort: {quick_sort_divided(array)}') diff --git a/stacks_and_queues/Queue.py b/stacks_and_queues/Queue.py new file mode 100644 index 0000000..118c9c3 --- /dev/null +++ b/stacks_and_queues/Queue.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# author: bt3gl + +import heapq + + +class Queue: + + def __init__(self): + self._in = [] + self._out = [] + + ###################### + # Private methods + ###################### + def _transfer_in_to_out(self): + while self._in: + self._out.append(self._in.pop()) + + def __repr__(self): + if not self._out: + self._transfer_in_to_out() + + return f'{self._out}' + + ###################### + # Properties + ###################### + @property + def size(self): + return len(self._in) + len(self._out) + + @property + def peek(self): + if not self._out: + self._transfer_in_to_out() + if self._out: + return self._out[-1] + else: + print('โŒ Queue is empty, cannot peek.') + + @property + def is_empty(self): + return not (bool(self._in) or bool(self._out)) + + ###################### + # Public methods + ###################### + def enqueue(self, item): + self._in.append(item) + + def dequeue(self): + if not self._out: + while self._in: + self.out.append(self._in.pop()) + + if self._out: + self._out.pop() + else: + print('โŒ Queue is empty, cannot dequeue.') + + +class PriorityQueue: + + def __init__(self): + self.queue = [] + self.index = 0 + + def push(self, item, priority): + heapq.heappush(self.queue, (-priority, self.index, item)) + self.index += 1 + + def pop(self): + return heapq.heappop(self.queue)[-1] + +class Item: + + def __init__(self, name): + self.name = name + + def __repr__(self): + return f'{self.name}' + + + +if __name__ == '__main__': + + ###################### + # Simple Queue + ###################### + print('๐Ÿงช Testing Queue...') + queue = Queue() + print(f"Is the queue empty? {queue.is_empty}") + print("Adding 1 to 10 in the queue...") + for i in range(1, 11): + queue.enqueue(i) + + print(f"Queue: {queue}") + print(f"\nQueue size: {queue.size}") + print(f"Queue peek : {queue.peek}") + print(f"Is the queue empty? {queue.is_empty}") + print(f"\nDequeue...") + queue.dequeue() + print(f"Queue: {queue}") + print(f"\nQueue size: {queue.size}") + print(f"Queue peek: {queue.peek}") + print(f"Is the queue empty? {queue.is_empty}") + + ###################### + # Priority Queue + ###################### + print('\n\n๐Ÿงช Testing Priority Queue...') + q = PriorityQueue() + q.push(Item('Item 1'), 1) + q.push(Item('Item 4'), 4) + q.push(Item('Item 3'), 3) + print(f"Priority Queue: {q.queue}") + print(f"Pop: {q.pop()}") + print(f"Priority Queue: {q.queue}") diff --git a/stacks_and_queues/README.md b/stacks_and_queues/README.md index e69de29..e6e7c07 100644 --- a/stacks_and_queues/README.md +++ b/stacks_and_queues/README.md @@ -0,0 +1,59 @@ +## stacks and queues + +
+ +### `Queues.py` + +
+ +```python +> python3 queues.py + +๐Ÿงช Testing Queue... +Is the queue empty? True +Adding 1 to 10 in the queue... +Queue: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] + +Queue size: 10 +Queue peek : 1 +Is the queue empty? False + +Dequeue... +Queue: [10, 9, 8, 7, 6, 5, 4, 3, 2] + +Queue size: 9 +Queue peek: 2 +Is the queue empty? False + + +๐Ÿงช Testing Priority Queue... +Priority Queue: [(-4, 1, Item 4), (-1, 0, Item 1), (-3, 2, Item 3)] +Pop: Item 4 +Priority Queue: [(-3, 2, Item 3), (-1, 0, Item 1)] +``` + +
+ +### `stack.py` + +
+ +```python +python3 stack.py + +Testing Stack... + +Stack: [12, 13, 14, 15, 16, 17, 18, 19, 20] +Stack size: 9 +Stack peek: 20 +Stack is empty: False +Stack min: 12 + +Popping... +20 +19 +18 +17 +16 +Stack: [12, 13, 14, 15] +``` \ No newline at end of file diff --git a/stacks_and_queues/Stack.py b/stacks_and_queues/Stack.py new file mode 100644 index 0000000..cecc22e --- /dev/null +++ b/stacks_and_queues/Stack.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# author: bt3gl + + +class Stack: + + def __init__(self): + self.content = [] + self.min_array = [] + self.min = float('inf') + + ###################### + # Private methods + ###################### + def __repr__(self): + return f'{self.content}' + + ###################### + # Properties + ###################### + @property + def size(self): + return len(self.content) + + @property + def peek(self): + if self.content: + return self.content[-1] + else: + print('โŒ Queue is empty, cannot peek.') + + @property + def is_empty(self): + return not bool(self.content) + + ###################### + # Public methods + ###################### + def push(self, value): + if value < self.min: + self.min = value + + self.content.append(value) + self.min_array.append(self.min) + + def pop(self): + if self.content: + value = self.content.pop() + self.min_array.pop() + if self.min_array: + self.min = self.min_array[-1] + return value + + def find_min(self): + if self.min_array: + return self.min_array[-1] + + +if __name__ == '__main__': + + ###################### + # Simple Stack + ###################### + print('Testing Stack...') + stack = Stack() + for i in range(12, 21): + stack.push(i) + + print(f'\nStack: {stack}') + print(f'Stack size: {stack.size}') + print(f'Stack peek: {stack.peek}') + print(f'Stack is empty: {stack.is_empty}') + print(f'Stack min: {stack.find_min()}') + + print('\nPopping...') + for i in range(5): + print(stack.pop()) + print(f'Stack: {stack}') diff --git a/trees_and_graphs/BinaryTree.py b/trees_and_graphs/BinaryTree.py new file mode 100644 index 0000000..ce75eaf --- /dev/null +++ b/trees_and_graphs/BinaryTree.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# author: bt3gl + + +class Node(object): + + def __init__(self, value): + self.value = value + self.right = None + self.left = None + + def add(self, value): + new_node = Node(value) + if not self.value: + self.value = new_node + elif not self.left: + self.left = new_node + elif not self. right: + self.right = new_node + else: + self.left = self.left.add(value) + return self # without this, it doesn't add! + + def search(self, item): + if self.value == item: + return True + found = False + if (self.left and self.left.search(item)) or \ + (self.right and self.right.search(item)): + found = True + return found + + def preorder(self): + yield self.value + if self.left: + for node in self.left.preorder(): + yield node + if self.right: + for node in self.right.preorder(): + yield node + + def postorder(self): + yield self.value + if self.left: + for node in self.left.postorder(): + yield node + if self.right: + for node in self.right.postorder(): + yield node + + def inorder(self): + yield self.value + if self.left: + for node in self.left.inorder(): + yield node + if self.right: + for node in self.right.inorder(): + yield node + + +class BinaryTree(object): + def __init__(self): + self.root = None + + def add(self, value): + if not self.root: + self.root = Node(value) + else: + self.root.add(value) + + def search(self, item): + if self.root: + return self.root.search(item) + + def preorder(self): + if self.root: + return list(self.root.preorder()) + + def inorder(self): + if self.root: + return list(self.root.inorder()) + + def postorder(self): + if self.root: + return list(self.root.postorder()) + + +if __name__ == '__main__': + + + print("\n\n๐ŸŒณ๐ŸŒณ๐ŸŒณ Testing BinaryTree ๐ŸŒณ๐ŸŒณ๐ŸŒณ") + bt = BinaryTree() + array1 = [4, 1, 4, 6, 7, 9, 10, 5, 11, 5] + print(f'\n๐ŸŸก Adding {array1} to the tree...') + for i in array1: + bt.add(i) + print(f"๐ŸŸข Print the tree preorder: {bt.preorder()}") + print(f"๐ŸŸข Print the tree inorder: {bt.inorder()}") + print(f"๐ŸŸข Print the tree postorder: {bt.postorder()}") + + print(f'\n๐ŸŸข Search for node 5: {bt.search(5)}') + print(f'โŒ Search for node 15: {bt.search(15)}') + + diff --git a/trees_and_graphs/README.md b/trees_and_graphs/README.md new file mode 100644 index 0000000..6d8b66a --- /dev/null +++ b/trees_and_graphs/README.md @@ -0,0 +1,93 @@ +## trees + +
+ + +### `Tree.py` + +
+ +```python +> python3 Trees.py + + +๐ŸŒด๐ŸŒด๐ŸŒด Testing SimpleTree ๐ŸŒด๐ŸŒด๐ŸŒด +a + b + d + e + c + h + g + + + +๐ŸŒณ๐ŸŒณ๐ŸŒณ Testing BinaryTree ๐ŸŒณ๐ŸŒณ๐ŸŒณ + +๐ŸŸก Adding [4, 1, 4, 6, 7, 9, 10, 5, 11, 5] to the tree... +๐ŸŸข Printing the tree in preorder... +4 +1 +6 +9 +5 +5 +11 +10 +7 +4 + +๐ŸŸข Searching for node 5: True +โŒ Searching for node 15: False +โŒ Is root a leaf? False +๐ŸŸข Is root full? True +โŒ Is the tree balanced? False +โŒ Is the tree a binary search tree? False + + +๐ŸŽ„๐ŸŽ„๐ŸŽ„ Testing BinarySearchTree ๐ŸŽ„๐ŸŽ„๐ŸŽ„ + +๐ŸŸก Adding [4, 1, 4, 6, 7, 9, 10, 5, 11, 5] to the tree... +โŒ Item 4 not added as BSTs do not support repetition. +โŒ Item 5 not added as BSTs do not support repetition. +๐ŸŸข Printing the tree in preorder: +4 +1 +6 +5 +7 +9 +10 +11 + +๐ŸŸข Searching for node 5: True +โŒ Searching for node 15: False +โŒ Is root a leaf? False +๐ŸŸข Is root full? True +๐ŸŸข Largest node? 11 +๐ŸŸข Smallest node? 1 +โŒ Is the tree balanced? False +๐ŸŸข Is the tree a binary search tree? True +``` + +
+ +### `BinaryTree.py` + +
+ +* a clean implementation adapted from the class above. + +```python +> python3 BinaryTree.py + +๐ŸŒณ๐ŸŒณ๐ŸŒณ Testing BinaryTree ๐ŸŒณ๐ŸŒณ๐ŸŒณ + +๐ŸŸก Adding [4, 1, 4, 6, 7, 9, 10, 5, 11, 5] to the tree... +๐ŸŸข Print the tree preorder: [4, 1, 6, 9, 5, 5, 11, 10, 7, 4] +๐ŸŸข Print the tree inorder: [4, 1, 6, 9, 5, 5, 11, 10, 7, 4] +๐ŸŸข Print the tree postorder: [4, 1, 6, 9, 5, 5, 11, 10, 7, 4] + +๐ŸŸข Search for node 5: True +โŒ Search for node 15: False +``` diff --git a/trees_and_graphs/Trees.py b/trees_and_graphs/Trees.py index 47bfc8e..b1b3826 100644 --- a/trees_and_graphs/Trees.py +++ b/trees_and_graphs/Trees.py @@ -294,5 +294,3 @@ if __name__ == '__main__': print(f'๐ŸŸข Smallest node? {bst.smallest_node(bst.root)}') print(f'โŒ Is the tree balanced? {bst.is_balanced(bst.root)}') print(f'๐ŸŸข Is the tree a binary search tree? {bst.is_binary_search_tree(bst.root)}') - -