From 818c40036cd7e281fbe1e18e8edbc265a89ac8f9 Mon Sep 17 00:00:00 2001 From: Aniket Shetty Date: Wed, 10 Nov 2021 12:54:12 +0530 Subject: [PATCH 01/53] Add files vai upload --- Chapter01/chapter1.py | 578 ++++++++++++++++++ Chapter02/binary_search.py | 16 + Chapter02/linear_search.py | 12 + Chapter02/matrix_chain.py | 14 + Chapter02/merge_sort.py | 37 ++ Chapter03/Fibonacci_series.py | 8 + Chapter03/MatrixChain_multiplication.py | 14 + Chapter03/binary_search.py | 16 + Chapter03/dijkstra.py | 80 +++ Chapter03/dyna_fib.py | 13 + Chapter03/factorial.py | 10 + Chapter03/merge_sort.py | 35 ++ Chapter04/CircularList.py | 99 +++ Chapter04/SinglyLinkedList.py | 33 + ...ppend_at_any_location_singly_linkedlist.py | 64 ++ .../delete_operation_doubly_linkedlist.py | 75 +++ .../delete_operation_singly_linkedlist.py | 74 +++ Chapter04/doubly_linked_list.py | 69 +++ Chapter04/faster_append_singly_linked_list.py | 31 + Chapter04/list_traversal_singly_linklist.py | 37 ++ Chapter05/Linked_list_based_queue.py | 45 ++ Chapter05/List_based_queue.py | 37 ++ Chapter05/Queue_application.py | 99 +++ Chapter05/Stack.py | 68 +++ Chapter05/Stack_based_queue.py | 27 + Chapter06/binary_search_tree.py | 145 +++++ Chapter06/level_order_traversal.py | 35 ++ Chapter06/reverse_polish_expression.py | 46 ++ Chapter06/tree_traversal.py | 53 ++ Chapter07/heap.py | 50 ++ Chapter07/heap_sort.py | 66 ++ Chapter08/hashing.py | 10 + Chapter08/hashtable.py | 74 +++ Chapter09/breadth_first_search.py | 33 + Chapter09/depth_first_search.py | 36 ++ Chapter09/graph.py | 31 + Chapter10/Unordered_linear_search.py | 27 + Chapter10/binary_search_iterative.py | 23 + Chapter10/binary_search_recursive | 17 + Chapter10/interpolation_search.py | 26 + Chapter10/search_ordered_list.py | 30 + Chapter11/Insertion_sort.py | 18 + Chapter11/Quick_sort.py | 35 ++ Chapter11/Selection_Sort.py | 14 + Chapter11/bubble_sort.py | 29 + Chapter12/deterministic_selection.py | 85 +++ Chapter12/randomized_search.py | 67 ++ Chapter13/Boyer_Moore_String_Matching.py | 46 ++ Chapter13/Brute_force_string_matching.py | 27 + Chapter13/Rabin_Karp_String_Matching.py | 46 ++ Chapter13/example_suffix_prefix.py | 6 + 51 files changed, 2666 insertions(+) create mode 100644 Chapter01/chapter1.py create mode 100644 Chapter02/binary_search.py create mode 100644 Chapter02/linear_search.py create mode 100644 Chapter02/matrix_chain.py create mode 100644 Chapter02/merge_sort.py create mode 100644 Chapter03/Fibonacci_series.py create mode 100644 Chapter03/MatrixChain_multiplication.py create mode 100644 Chapter03/binary_search.py create mode 100644 Chapter03/dijkstra.py create mode 100644 Chapter03/dyna_fib.py create mode 100644 Chapter03/factorial.py create mode 100644 Chapter03/merge_sort.py create mode 100644 Chapter04/CircularList.py create mode 100644 Chapter04/SinglyLinkedList.py create mode 100644 Chapter04/append_at_any_location_singly_linkedlist.py create mode 100644 Chapter04/delete_operation_doubly_linkedlist.py create mode 100644 Chapter04/delete_operation_singly_linkedlist.py create mode 100644 Chapter04/doubly_linked_list.py create mode 100644 Chapter04/faster_append_singly_linked_list.py create mode 100644 Chapter04/list_traversal_singly_linklist.py create mode 100644 Chapter05/Linked_list_based_queue.py create mode 100644 Chapter05/List_based_queue.py create mode 100644 Chapter05/Queue_application.py create mode 100644 Chapter05/Stack.py create mode 100644 Chapter05/Stack_based_queue.py create mode 100644 Chapter06/binary_search_tree.py create mode 100644 Chapter06/level_order_traversal.py create mode 100644 Chapter06/reverse_polish_expression.py create mode 100644 Chapter06/tree_traversal.py create mode 100644 Chapter07/heap.py create mode 100644 Chapter07/heap_sort.py create mode 100644 Chapter08/hashing.py create mode 100644 Chapter08/hashtable.py create mode 100644 Chapter09/breadth_first_search.py create mode 100644 Chapter09/depth_first_search.py create mode 100644 Chapter09/graph.py create mode 100644 Chapter10/Unordered_linear_search.py create mode 100644 Chapter10/binary_search_iterative.py create mode 100644 Chapter10/binary_search_recursive create mode 100644 Chapter10/interpolation_search.py create mode 100644 Chapter10/search_ordered_list.py create mode 100644 Chapter11/Insertion_sort.py create mode 100644 Chapter11/Quick_sort.py create mode 100644 Chapter11/Selection_Sort.py create mode 100644 Chapter11/bubble_sort.py create mode 100644 Chapter12/deterministic_selection.py create mode 100644 Chapter12/randomized_search.py create mode 100644 Chapter13/Boyer_Moore_String_Matching.py create mode 100644 Chapter13/Brute_force_string_matching.py create mode 100644 Chapter13/Rabin_Karp_String_Matching.py create mode 100644 Chapter13/example_suffix_prefix.py diff --git a/Chapter01/chapter1.py b/Chapter01/chapter1.py new file mode 100644 index 0000000..2631bf5 --- /dev/null +++ b/Chapter01/chapter1.py @@ -0,0 +1,578 @@ +p = "Hello India" +q = 10 +r = 10.2 +print(type(p)) +print(type(q)) +print(type(r)) +print(type(12+31j)) + +############### + +var = 13.2 +print(var) +#13.2 + +type (var) +# + +var = "Now the type is string" +print(var) + +type(var) +# +var = 13.2 +print(var) +#13.2 + +############# +print(type(bool(22))) +print(type(True)) +print(type(False)) +''' +Output: + + + +''' + +bool(False) +#False +va1 = 0 +print(bool(va1)) +#False + +va2 = 11 +print(bool(va2)) +#True + +va3 = -2.3 +print(bool(va3)) +#True + +#### Strings +Str1 = 'Hello how are you' +str2 = "Hello how are you" +str3 = 'multiline'+'string'; +print(str3) + +f = 'data' +s = 'structure' +print(f + s) +#'datastructure' +print('Data ' + 'structure') +#Data structure + + +st = 'data.' +print(st * 3) +#'data.data.data.' +print(3 * st) +#'data.data.data.' + + +###### Lists ###### + +a = ['food', 'bus', 'apple', 'queen'] +print(a) +#['food', 'bus', 'apple', 'queen'] + + +mylist = [10, "India", "world", 8] +# accessing elements in list. +print(mylist[1]) +#India + + + +###### Ordered List ###### + +[10, 12, 31, 14] == [14, 10, 31, 12] +print([10, 12, 31, 14] == [14, 10, 31, 12]) +#False + + +###### Dynamic List ###### +b = ['data', 'and', 'book', 'structure', 'hello', 'st'] + +b += [32] +print(b) +#['data', 'and', 'book', 'structure', 'hello', 'st', 32] + + +b[2:3] = [] +print(b) +#['data', 'and', 'structure', 'hello', 'st', 32] + +del b[0] +print(b) +#['and', 'structure', 'hello', 'st', 32] + +a = [2.2, 'python', 31, 14, 'data', False, 33.59] +print(a) +#[2.2, 'python', 31, 14, 'data', False, 33.59] + + +a = ['data', 'structures', 'using', 'python', 'happy', 'learning'] +print(a[0]) +'data' +print(a[2]) +'using' +print(a[-1]) +'learning' +print(a[-5]) +'structures' + + +print(a[1:5]) +['structures', 'using'] + +print(a[-3:-1]) +['python', 'happy'] + +######### Mutable #### +a = ['data', 'and', 'book', 'structure', 'hello', 'st'] +print(a) +['data', 'and', 'book', 'structure', 'hello', 'st'] +a[1] = 1 +a[-1] = 120 +print(a) +['data', 1, 'book', 'structure', 'hello', 120] + +a = ['data', 'and', 'book', 'structure', 'hello', 'st'] + +print(a[2:5]) +['book', 'structure', 'hello'] +a[2:5] = [1, 2, 3, 4, 5] +print(a) +['data', 'and', 1, 2, 3, 4, 5, 'st'] + +######### Other operators #### + +a = ['data', 'structures', 'using', 'python', 'happy', 'learning'] +print('data' in a) +#True + +print(a) +#['data', 'structures', 'using', 'python', 'happy', 'learning'] + +a + ['New', 'elements'] +print(a) +#['data', 'structures', 'using', 'python', 'happy', 'learning', 'New', 'elements'] + +print(a * 2) +#['data', 'structures', 'using', 'python', 'happy', 'learning', 'New', 'elements', 'data', 'structures', 'using', 'python', 'happy', 'learning', 'New', 'elements'] + +print(len(a)) +#6 +print(min(a)) + + +############ Membership operators + +#using 'in' operator +mylist1=[100,20,30,40] +mylist2=[10,50,60,90] +if mylist1[1] in mylist2: + print("elements are overlapping") +else: + print("elements are not overlapping") + +#Output: +#elements are not overlapping + + +########## Program to illustrate 'not in' operator +val = 104 +mylist = [100, 210, 430, 840, 108] +if val not in mylist: + print("val is NOT present in mylist") +else: + print("val is present in mylist") + +#Output: +#val is NOT present in mylist + + + +############# Example program to demonstrate the use of 'is' operator +Firstlist = [] +Secondlist = [] +if Firstlist == Secondlist: + print("Both are equal") +else: + print("Both are not equal") +if Firstlist is Secondlist: + print("Both variables are pointing to the same object") +else: + print("Both variables are not pointing to the same object") +thirdList = Firstlist +if thirdList is Secondlist: + print("Both are pointing to the same object") +else: + print("Both are not pointing to the same object ") +''' +Output: +Both are equal +Both variables are not pointing to the same object +Both are pointing to the same object +''' + + + +####### Example program to demonstrate the use of 'is not' operator +Firstlist = [] +Secondlist = [] +if Firstlist is not Secondlist: + print("Both are pointing to the different object") +else: + print("Both are not pointing to the different object ") + +#Output: +# Both are pointing to the different object + + + +############## Logical Operators + +#### Example program to demonstrate the use of 'and' operator +a = 32 +b = 132 +if a > 0 and b > 0: + print("Both a and b are greater than zero") +else: + print("At least one variable is less than 0") + +#Output: +#Both a and b are greater than zero + + + +######### Example program to demonstrate the use of 'or' operator +a = 32 +b = -32 +if a > 0 or b > 0: + print("At least one variable is greater than zero") +else: + print("Both variables are less than 0") + +#Output: +#At least one variable is greater than zero + + +########## Example program to demonstrate the use of 'or' operator +a = 32 +if not a: + print("Boolean value of a is False") +else: + print("Boolean value of a is True") + +#Output: +#Boolean value of a is True + + + + +########## Tuple ########### + +tupleName = ("entry1" , "entry2" , "entry3") +myTuple = ("Shyam", 23 , True , "male") +print(len((4,5, 'hello'))) + +print((4,5)+(10,20)) +print((2,1)*3) +print(3 in ('hi', 'xyz',3)) +for p in (6,7,8): + print(p) + +x = ('hello', 'world', 'india') +print(x[1]) +print(x[-2]) +print(x[1:]) + + +######### Dictionaries ######### +my_dict = { + '1': 'Data', + '2': 'Structure', + '3': 'python', + '4': 'programming', + '5': 'language' +} + + +############ + +person = {} +print(type(person)) +# + +person['name'] = 'ABC' +person['lastname'] = 'XYZ' +person['age'] = 31 +person['address'] = ['Jaipur'] + +print(person) +#{'name': 'ABC', 'lastname': 'XYZ', 'age': 31, 'address': ['Jaipur']} + +print(person['name']) +#'ABC' + + +print('name' in person) +#True +print('fname' not in person) +#True +print(len(person)) +#4 + +mydict = {'a': 1, 'b': 2, 'c': 3} +print(mydict) +#{'a': 1, 'b': 2, 'c': 3} +mydict.clear() +print(mydict) +#{} + +''' +mydict.get('b') +print(mydict) +#2 +mydict.get('z') +print(mydict) +#None + +print(list(mydict.items())) +#[('a', 1), ('b', 2), ('c', 3)] + +print(list(mydict.keys())) +#['a', 'b', 'c'] + +print(list(mydict.values())) +#[1, 2, 3] + +print(mydict.pop('b')) +#2 +print(mydict) +#{'a': 1, 'c': 3} +mydict = {'a': 1,'b': 2,'c': 3} +print(mydict.popitem()) +#('c', 3) +print(mydict) +#{'a': 1, 'b': 2} +d1 = {'a': 10, 'b': 20, 'c': 30} +d2 = {'b': 200, 'd': 400} + +print(d1.update(d2)) +print(d1) +#{'a': 10, 'b': 200, 'c': 30, 'd': 400} +''' + + +############## SETS ############# + +x1 = set(['and', 'python', 'data', 'structure']) +print(x1) +#{'and', 'python', 'data', 'structure'} +print(type(x1)) +# + +x2 = {'and', 'python', 'data', 'structure'} +print(x2) +#{'and', 'python', 'data', 'structure'} +x = {'data', 'structure', 'and', 'python'} +print(len(x)) +#4 +print('structure' in x) +#True +x1 = {'data', 'structure'} +x2 = {'python', 'java', 'c', 'data'} + +######### Union of two sets, x1 and x2. +x3 = x1 | x2 +print(x3) +{'java', 'structure', 'c', 'python', 'data'} + +print(x1.union(x2)) +{'java', 'structure', 'c', 'python', 'data'} + + +########## Intersection of sets +print(x1.intersection(x2)) +#{'data'} +print(x1 & x2) +#{'data'} + + +########## Difference of sets + +print(x1.difference(x2)) +#{'structure'} +print(x1 - x2) +#{'structure'} + + +######### Symmetric difference ########## +print(x1.symmetric_difference(x2)) +#{'structure', 'python', 'c', 'java'} + +print(x1 ^ x2) +#{'structure', 'python', 'c', 'java'} + +####### subset ###### + +print(x1.issubset(x2)) +#False +print(x1 <= x2) +#False + +########## Immutable Sets ######### + +x = frozenset(['data', 'structure', 'and', 'python']) +print(x) +#frozenset({'and', 'python', 'data', 'structure'}) +##### Error in the below code #### +''' +a11 = set(['data']) +a21 = set(['structure']) +a31 = set(['python']) +x1 = {a11, a21, a31} +''' + +a1 = frozenset(['data']) +a2 = frozenset(['structure']) +a3 = frozenset(['python']) +x = {a1, a2, a3} +print(x) + + + +######## Named Tuples ######## + +from collections import namedtuple +Book = namedtuple ('Book', ['name', 'ISBN', 'quantity']) +Book1 = Book('Hands on Data Structures', '9781788995573', '50') +# Accessing data items +print('Using index ISBN:' + Book1[1]) +#Using index ISBN: 9781788995573 +print('Using key ISBN:' + Book1.ISBN) +#Using key ISBN: 9781788995573 + + +######## Deque ############ + +from collections import deque +s = deque() # Creates an empty deque +my_queue = deque([1, 2, 'Name']) +print(my_queue) +#deque([1, 2, 'Name']) +my_queue.append('age') +print(my_queue) +my_queue.appendleft('age') +print(my_queue) +my_queue.pop() +print(my_queue) +my_queue.popleft() +print(my_queue) + + +########## Ordered Dictionaries ######## + +from collections import OrderedDict +od = OrderedDict({'my': 2, 'name ': 4, 'is': 2, 'Mohan' :5}) +od['hello'] = 4 +print(od) +#([('my', 2), ('name', 4), ('is', 2), ('Mohan', 5), ('hello', 4)]) + + +############ Default Dictionary ######## + +from collections import defaultdict +dd = defaultdict(int) +words = str.split('data python data data structure data python') +for word in words: + dd[word] +=1 + +print(dd) +#defaultdict(, {'data': 4, 'python': 2, 'structure': 1}) + + + + +############ ChainMap Object ############## + +from collections import ChainMap +dict1 = {"data": 1, "structure": 2} +dict2 = {"python": 3, "language": 4} +chain = ChainMap(dict1, dict2) + +print(chain) +#ChainMap({'data': 1, 'structure': 2}, {'python': 3, 'language': 4}) +print (list(chain.keys())) +#['python', 'language', 'data', 'structure'] +print (list(chain.values())) +#[3, 4, 1, 2] +print(chain["data"]) +#1 +print(chain["language"]) +#4 + + +################ Counter Objects ########### + +from collections import Counter +inventory = Counter('hello') +print(inventory) +Counter({'l': 2, 'h': 1, 'e': 1, 'o': 1}) + + + +############### UserDict ############# +''' +from collections import UserDict +class MyDict(UserDict): + def push(self, key, value): + raise RuntimeError("Cannot insert") + +d = MyDict({'ab':1, 'bc': 2, 'cd': 3}) +d.push('b', 2) + +Traceback (most recent call last): + File "", line 12, in +File "", line 6, in push +RuntimeError: Cannot insert +''' + +######### UserList ########### +''' +from collections import UserList +class MyList(UserList): + def push(self, key): + raise RuntimeError("Cannot insert in the list") + +d = MyList([11, 12, 13]) +d.push(2) + +Traceback (most recent call last): + Traceback (most recent call last): + File "", line 1, in + File "", line 3, in push +RuntimeError: Cannot insert in the list +''' + +######### UserString ########## + +# create a custom append function for string +from collections import UserString +class MyString(UserString): + def append(self, value): + self.data += value + +s1 = MyString("data") +print("Original:", s1) +#Original: data + +s1.append('h') +print("After append: ", s1) +#After append: datah + + + diff --git a/Chapter02/binary_search.py b/Chapter02/binary_search.py new file mode 100644 index 0000000..4ca8711 --- /dev/null +++ b/Chapter02/binary_search.py @@ -0,0 +1,16 @@ +def binary_search(arr, low, high, key): + while low <= high: + mid = int(low + (high - low)/2) + if arr[mid] == key: + return mid + elif arr[mid] < key: + low = mid + 1 + else: + high = mid - 1 + return -1 + + +arr = [ 2, 3, 4, 2, 10, 40] +x = 10 +result = binary_search(arr, 0, len(arr)-1, x) +print(result) diff --git a/Chapter02/linear_search.py b/Chapter02/linear_search.py new file mode 100644 index 0000000..5f6dda7 --- /dev/null +++ b/Chapter02/linear_search.py @@ -0,0 +1,12 @@ +# Linear search program to search an element, return the index position of the #array + +def searching(search_arr, x): + for i in range(len(search_arr)): + if search_arr[i] == x: + return i + return -1 + + +search_arr = [3, 4, 1, 6, 14] +x=4 +print("Index position for the element x is:", searching(search_arr, x)) diff --git a/Chapter02/matrix_chain.py b/Chapter02/matrix_chain.py new file mode 100644 index 0000000..2d30a87 --- /dev/null +++ b/Chapter02/matrix_chain.py @@ -0,0 +1,14 @@ +import sys + +def matrix_chain(mat, i, j): + if i == j: + return 0 + minimum_computations = sys.maxsize + for k in range(i, j): + count = (MatrixChain(mat, i, k) + MatrixChain(mat, k+1, j)+ mat[i-1] * mat[k] * mat[j]) + if count < minimum_computations: + minimum_computations = count + return minimum_computations + +matrix_sizes = [20, 30, 45, 50] +print("Minimum multiplications are", MatrixChain(matrix_sizes , 1, len(matrix_sizes)-1)) diff --git a/Chapter02/merge_sort.py b/Chapter02/merge_sort.py new file mode 100644 index 0000000..d724aca --- /dev/null +++ b/Chapter02/merge_sort.py @@ -0,0 +1,37 @@ +def merge_sort(unsorted_list): + if len(unsorted_list) == 1: + return unsorted_list + mid_point = int(len(unsorted_list)/2) + first_half = unsorted_list[:mid_point] + second_half = unsorted_list[mid_point:] + + half_a = merge_sort(first_half) + half_b = merge_sort(second_half) + + return merge(half_a, half_b) + + +def merge(first_sublist, second_sublist): + i = j = 0 + merged_list = [] + while i < len(first_sublist) and j < len(second_sublist): + if first_sublist[i] < second_sublist[j]: + merged_list.append(first_sublist[i]) + i += 1 + else: + merged_list.append(second_sublist[j]) + j += 1 + + while i < len(first_sublist): + merged_list.append(first_sublist[i]) + i += 1 + + while j < len(second_sublist): + merged_list.append(second_sublist[j]) + j += 1 + return merged_list + + +a= [11, 12, 7, 41, 61, 13, 16, 14] +print(merge_sort(a)) + diff --git a/Chapter03/Fibonacci_series.py b/Chapter03/Fibonacci_series.py new file mode 100644 index 0000000..99590f2 --- /dev/null +++ b/Chapter03/Fibonacci_series.py @@ -0,0 +1,8 @@ +def fib(n): + if n <= 1: + return 1 + else: + return fib(n-1) + fib(n-2) + +for i in range(5): + print(fib(i)) diff --git a/Chapter03/MatrixChain_multiplication.py b/Chapter03/MatrixChain_multiplication.py new file mode 100644 index 0000000..3c14e70 --- /dev/null +++ b/Chapter03/MatrixChain_multiplication.py @@ -0,0 +1,14 @@ +import sys +def MatrixChain(mat, i, j): + if i == j: + return 0 + minimum_computations = sys.maxsize + for k in range(i, j): + count = (MatrixChain(mat, i, k) + MatrixChain(mat, k+1, j)+ mat[i-1] * mat[k] * mat[j]) + if count < minimum_computations: + minimum_computations = count + return minimum_computations + + +matrix_sizes = [20, 30, 45, 50] +print("Minimum multiplications are", MatrixChain(matrix_sizes , 1, len(matrix_sizes)-1)) diff --git a/Chapter03/binary_search.py b/Chapter03/binary_search.py new file mode 100644 index 0000000..dac62d4 --- /dev/null +++ b/Chapter03/binary_search.py @@ -0,0 +1,16 @@ +def binary_search(arr, low, high, key): + while low <= high: + mid = int(low + (high - low)/2) + if arr[mid] == key: + return mid + elif arr[mid] < key: + low = mid + 1 + else: + high = mid - 1 + return -1 + + +arr = [ 2, 3, 4, 2, 10, 40] +x = 10 +result = binary_search(arr, 0, len(arr)-1, x) +print(result) diff --git a/Chapter03/dijkstra.py b/Chapter03/dijkstra.py new file mode 100644 index 0000000..29cab7a --- /dev/null +++ b/Chapter03/dijkstra.py @@ -0,0 +1,80 @@ + +def get_shortest_distance(table, vertex): + shortest_distance = table[vertex][DISTANCE] + return shortest_distance + +def set_shortest_distance(table, vertex, new_distance): + table[vertex][DISTANCE] = new_distance + +def set_previous_node(table, vertex, previous_node): + table[vertex][PREVIOUS_NODE] = previous_node + +def get_distance(graph, first_vertex, second_vertex): + return graph[first_vertex][second_vertex] + +def get_next_node(table, visited_nodes): + unvisited_nodes = list(set(table.keys()).difference(set(visited_nodes))) + assumed_min = table[unvisited_nodes[0]][DISTANCE] + min_vertex = unvisited_nodes[0] + for node in unvisited_nodes: + if table[node][DISTANCE] < assumed_min: + assumed_min = table[node][DISTANCE] + min_vertex = node + return min_vertex + +def find_shortest_path(graph, table, origin): + visited_nodes = [] + current_node = origin + starting_node = origin + while True: + adjacent_nodes = graph[current_node] + if set(adjacent_nodes).issubset(set(visited_nodes)): + # Nothing here to do. All adjacent nodes have been visited. + pass + else: + unvisited_nodes = set(adjacent_nodes).difference(set(visited_nodes)) + for vertex in unvisited_nodes: + distance_from_starting_node = get_shortest_distance(table, vertex) + if distance_from_starting_node == INFINITY and current_node == starting_node: + total_distance = get_distance(graph, vertex, current_node) + else: + total_distance = get_shortest_distance (table, + current_node) + get_distance(graph, current_node, vertex) + if total_distance < distance_from_starting_node: + set_shortest_distance(table, vertex, total_distance) + set_previous_node(table, vertex, current_node) + visited_nodes.append(current_node) + #print(visited_nodes) + if len(visited_nodes) == len(table.keys()): + break + current_node = get_next_node(table,visited_nodes) + return(table) + +graph = dict() +graph['A'] = {'B': 5, 'D': 9, 'E': 2} +graph['B'] = {'A': 5, 'C': 2} +graph['C'] = {'B': 2, 'D': 3} +graph['D'] = {'A': 9, 'F': 2, 'C': 3} +graph['E'] = {'A': 2, 'F': 3} +graph['F'] = {'E': 3, 'D': 2} + +table = dict() +table = { + 'A': [0, None], + 'B': [float("inf"), None], + 'C': [float("inf"), None], + 'D': [float("inf"), None], + 'E': [float("inf"), None], + 'F': [float("inf"), None], +} + + +DISTANCE = 0 +PREVIOUS_NODE = 1 +INFINITY = float('inf') + +shortest_distance_table = find_shortest_path(graph, table, 'A') + + +for k in sorted(shortest_distance_table): + print("{} - {}".format(k,shortest_distance_table[k])) diff --git a/Chapter03/dyna_fib.py b/Chapter03/dyna_fib.py new file mode 100644 index 0000000..5ba97f6 --- /dev/null +++ b/Chapter03/dyna_fib.py @@ -0,0 +1,13 @@ +def dyna_fib(n, lookup): + if n == 0: + return 0 + if n <= 2: + lookup[n] = 1 + if lookup[n] is None: + lookup[n] = dyna_fib(n-1, lookup) + dyna_fib(n-2, lookup) + return lookup[n] + +lookup = [None]*(1000) + +for i in range(6): + print(dyna_fib(i, lookup)) diff --git a/Chapter03/factorial.py b/Chapter03/factorial.py new file mode 100644 index 0000000..3469d23 --- /dev/null +++ b/Chapter03/factorial.py @@ -0,0 +1,10 @@ +def factorial(n): + # test for a base case + if n == 0: + return 1 + else: + return n*factorial(n-1) # make a calculation and a recursive call + + + +print(factorial(4)) diff --git a/Chapter03/merge_sort.py b/Chapter03/merge_sort.py new file mode 100644 index 0000000..e546be9 --- /dev/null +++ b/Chapter03/merge_sort.py @@ -0,0 +1,35 @@ +def merge_sort(unsorted_list): + if len(unsorted_list) == 1: + return unsorted_list + mid_point = int(len(unsorted_list)/2) + first_half = unsorted_list[:mid_point] + second_half = unsorted_list[mid_point:] + + half_a = merge_sort(first_half) + half_b = merge_sort(second_half) + + return merge(half_a, half_b) + + + +def merge(first_sublist, second_sublist): + i = j = 0 + merged_list = [] + while i < len(first_sublist) and j < len(second_sublist): + if first_sublist[i] < second_sublist[j]: + merged_list.append(first_sublist[i]) + i += 1 + else: + merged_list.append(second_sublist[j]) + j += 1 + while i < len(first_sublist): + merged_list.append(first_sublist[i]) + i += 1 + while j < len(second_sublist): + merged_list.append(second_sublist[j]) + j += 1 + return merged_list + + +a= [11, 12, 7, 41, 61, 13, 16, 14] +print(merge_sort(a)) diff --git a/Chapter04/CircularList.py b/Chapter04/CircularList.py new file mode 100644 index 0000000..7ddd583 --- /dev/null +++ b/Chapter04/CircularList.py @@ -0,0 +1,99 @@ +class Node: + """ A Circular linked node. """ + def __init__(self, data=None): + self.data = data + self.next = None + + + +class CircularList: + def __init__ (self): + self.tail = None + self.head = None + self.size = 0 + + def append(self, data): + node = Node(data) + if self.head: + self.head.next = node + self.head = node + else: + self.head = node + self.tail = node + self.head.next = self.tail + self.size += 1 + + def delete(self, data): + current = self.tail + prev = self.tail + while prev == current or prev != self.head: + if current.data == data: + if current == self.tail: + self.tail = current.next + self.head.next = self.tail + else: + prev.next = current.next + self.size -= 1 + return + prev = current + current = current.next + + + def iter(self): + current = self.tail + while current: + val = current.data + current = current.next + yield val + + + +words = CircularList() +words.append('eggs') +words.append('ham') +words.append('spam') + + +counter = 0 +for word in words.iter(): + print(word) + counter += 1 + if counter > 10: + break + +words.append('foo') +words.append('bar') +words.append('bim') +words.append('baz') +words.append('quux') +words.append('duux') + + + +print("Done iterating. Now we try to delete something that isn't there.") +words.delete('socks') +print('back to iterating') +counter = 0 +for item in words.iter(): + print(item) + counter += 1 + if counter > 2: + break + +print('Let us delete something that is there.') +words.delete('foo') +print('back to iterating') +counter = 0 +for item in words.iter(): + print(item) + counter += 1 + if counter > 2: + break + + + + + + + + diff --git a/Chapter04/SinglyLinkedList.py b/Chapter04/SinglyLinkedList.py new file mode 100644 index 0000000..6859a8c --- /dev/null +++ b/Chapter04/SinglyLinkedList.py @@ -0,0 +1,33 @@ +class Node: + """ A singly-linked node. """ + def __init__(self, data=None): + self.data = data + self.next = None + + +class SinglyLinkedList: + def __init__ (self): + self.tail = None + + def append(self, data): + # Encapsulate the data in a Node + node = Node(data) + if self.tail == None: + self.tail = node + else: + current = self.tail + while current.next: + current = current.next + current.next = node + + + +words = SinglyLinkedList() +words.append('egg') +words.append('ham') +words.append('spam') + +current = words.tail +while current: + print(current.data) + current = current.next diff --git a/Chapter04/append_at_any_location_singly_linkedlist.py b/Chapter04/append_at_any_location_singly_linkedlist.py new file mode 100644 index 0000000..e385d76 --- /dev/null +++ b/Chapter04/append_at_any_location_singly_linkedlist.py @@ -0,0 +1,64 @@ +class Node: + """ A singly-linked node. """ + def __init__(self, data=None): + self.data = data + self.next = None + + +class SinglyLinkedList: + def __init__ (self): + self.tail = None + + def append(self, data): + # Encapsulate the data in a Node + node = Node(data) + if self.tail == None: + self.tail = node + else: + current = self.tail + while current.next: + current = current.next + current.next = node + + def append_at_a_location(self, data, index): + current = self.tail + prev = self.tail + node = Node(data) + count = 1 + while current: + if count == index: + node.next = current + prev.next = node + print(count) + return + elif index == 1: + node.next = current + self.tail = node + return + count += 1 + prev = current + current = current.next + + + +words = SinglyLinkedList() +words.append('egg') +words.append('ham') +words.append('spam') + +current = words.tail +while current: + print(current.data) + current = current.next + + + +words.append_at_a_location('new', 2) + +current = words.tail +while current: + print(current.data) + current = current.next + + + diff --git a/Chapter04/delete_operation_doubly_linkedlist.py b/Chapter04/delete_operation_doubly_linkedlist.py new file mode 100644 index 0000000..2b129e9 --- /dev/null +++ b/Chapter04/delete_operation_doubly_linkedlist.py @@ -0,0 +1,75 @@ +class Node(object): + def __init__ (self, data = None, next = None, prev = None): + self.data = data + self.next = next + self.prev = prev + +class DoublyLinkedList(object): + def __init__ (self): + self.head = None + self.tail = None + self.count = 0 + + def append(self, data): + #Append an item to the list. + new_node = Node(data, None, None) + if self.head is None: + self.head = new_node + self.tail = self.head + else: + new_node.prev = self.tail + self.tail.next = new_node + self.tail = new_node + self.count += 1 + + + + def delete(self, data): + # Delete a node from the list. + current = self.head + node_deleted = False + if current is None: #Item to be deleted is not found in the list + node_deleted = False + elif current.data == data: #Item to be deleted is found at starting of list + self.head = current.next + self.head.prev = None + node_deleted = True + elif self.tail.data == data: #Item to be deleted is found at the end of list. + self.tail = self.tail.prev + self.tail.next = None + node_deleted = True + else: + while current: #search item to be deleted, and delete that node + if current.data == data: + current.prev.next = current.next + current.next.prev = current.prev + node_deleted = True + current = current.next + if node_deleted: + self.count -= 1 + + + +#Code to create for a doubly linked list +words = DoublyLinkedList() +words.append('egg') +words.append('ham') +words.append('spam') +current = words.head +while current: + print(current.data) + current = current.next + + +words.delete('ham') +current = words.head +while current: + print(current.data) + current = current.next + + +words.delete('spam') +current = words.head +while current: + print(current.data) + current = current.next diff --git a/Chapter04/delete_operation_singly_linkedlist.py b/Chapter04/delete_operation_singly_linkedlist.py new file mode 100644 index 0000000..b7a344c --- /dev/null +++ b/Chapter04/delete_operation_singly_linkedlist.py @@ -0,0 +1,74 @@ +class Node: + """ A singly-linked node. """ + def __init__(self, data=None): + self.data = data + self.next = None + +class SinglyLinkedList: + def __init__ (self): + self.tail = None + + def append(self, data): + # Encapsulate the data in a Node + node = Node(data) + if self.tail == None: + self.tail = node + else: + current = self.tail + while current.next: + current = current.next + current.next = node + + def delete_First_node (self): + current = self.tail + if current == self.tail: + self.tail = current.next + + def delete_last_node (self): + current = self.tail + prev = self.tail + while current: + if current.next == None: + prev.next = current.next + self.size -= 1 + prev = current + current = current.next + + + def delete(self, data): + current = self.tail + prev = self.tail + while current: + if current.data == data: + if current == self.tail: + self.tail = current.next + else: + prev.next = current.next + self.size -= 1 + return + prev = current + current = current.next + + +words = SinglyLinkedList() +words.append('egg') +words.append('ham') +words.append('spam') + + +words.delete_last_node() + +current = words.tail +while current: + print(current.data) + current = current.next + + + +words.delete('ham') +current = words.tail +while current: + print(current.data) + current = current.next + + diff --git a/Chapter04/doubly_linked_list.py b/Chapter04/doubly_linked_list.py new file mode 100644 index 0000000..63c9762 --- /dev/null +++ b/Chapter04/doubly_linked_list.py @@ -0,0 +1,69 @@ +class Node(object): + def __init__ (self, data = None, next = None, prev = None): + self.data = data + self.next = next + self.prev = prev + +class DoublyLinkedList(object): + def __init__ (self): + self.head = None + self.tail = None + self.count = 0 + + def append(self, data): + #Append an item to the list. + new_node = Node(data, None, None) + if self.head is None: + self.head = new_node + self.tail = self.head + else: + new_node.prev = self.tail + self.tail.next = new_node + self.tail = new_node + self.count += 1 + + + def append_at_start(self, data): + # Append an item at beginning to the list. + new_node = Node(data, None, None) + if self.head is None: + self.head = new_node + self.tail = self.head + else: + new_node.next = self.head + self.head.prev = new_node + self.head = new_node + self.count += 1 + + def append_at_a_location(self, data): + current = self.head + prev = self.head + new_node = Node(data, None, None) + while current: + if current.data == data: + new_node.prev = prev + new_node.next = current + prev.next = new_node + current.prev = new_node + self.count += 1 + prev = current + current = current.next + + + +words = DoublyLinkedList() +words.append('egg') +words.append('ham') +words.append('spam') + +current = words.head +while current: + print(current.data) + current = current.next + + +words.append_at_a_location('ham') +current = words.head +while current: + print(current.data) + current = current.next diff --git a/Chapter04/faster_append_singly_linked_list.py b/Chapter04/faster_append_singly_linked_list.py new file mode 100644 index 0000000..7910893 --- /dev/null +++ b/Chapter04/faster_append_singly_linked_list.py @@ -0,0 +1,31 @@ +class Node: + """ A singly-linked node. """ + def __init__(self, data=None): + self.data = data + self.next = None + + +class SinglyLinkedList: + def __init__ (self): + self.tail = None + self.head = None + + def append(self, data): + node = Node(data) + if self.head: + self.head.next = node + self.head = node + else: + self.tail = node + self.head = node + + +words = SinglyLinkedList() +words.append('egg') +words.append('ham') +words.append('spam') + +current = words.tail +while current: + print(current.data) + current = current.next diff --git a/Chapter04/list_traversal_singly_linklist.py b/Chapter04/list_traversal_singly_linklist.py new file mode 100644 index 0000000..8a25ad8 --- /dev/null +++ b/Chapter04/list_traversal_singly_linklist.py @@ -0,0 +1,37 @@ +class Node: + """ A singly-linked node. """ + def __init__(self, data=None): + self.data = data + self.next = None + + +class SinglyLinkedList: + def __init__ (self): + self.tail = None + + def append(self, data): + # Encapsulate the data in a Node + node = Node(data) + if self.tail == None: + self.tail = node + else: + current = self.tail + while current.next: + current = current.next + current.next = node + + def iter(self): + current = self.tail + while current: + val = current.data + current = current.next + yield val + + +words = SinglyLinkedList() +words.append('egg') +words.append('ham') +words.append('spam') + +for word in words.iter(): + print(word) diff --git a/Chapter05/Linked_list_based_queue.py b/Chapter05/Linked_list_based_queue.py new file mode 100644 index 0000000..8bda557 --- /dev/null +++ b/Chapter05/Linked_list_based_queue.py @@ -0,0 +1,45 @@ +class Node(object): + def __init__(self, data=None, next=None, prev=None): + self.data = data + self.next = next + self.prev = prev + + +class Queue: + def __init__(self): + self.head = None + self.tail = None + self.count = 0 + + def enqueue(self, data): + new_node = Node(data, None, None) + if self.head is None: + self.head = new_node + self.tail = self.head + else: + new_node.prev = self.tail + self.tail.next = new_node + self.tail = new_node + + self.count += 1 + + + def dequeue(self): + current = self.head + if self.count == 1: + self.count -= 1 + self.head = None + self.tail = None + elif self.count > 1: + self.head = self.head.next + self.head.prev = None + self.count -= 1 + + + +q= Queue() +q.enqueue(4) +q.enqueue('dog') +q.enqueue('True') + +print(q.count) diff --git a/Chapter05/List_based_queue.py b/Chapter05/List_based_queue.py new file mode 100644 index 0000000..4b4f8eb --- /dev/null +++ b/Chapter05/List_based_queue.py @@ -0,0 +1,37 @@ +class Node(object): + def __init__(self, data=None, next=None, prev=None): + self.data = data + self.next = next + self.prev = prev + +class ListQueue: + def __init__(self): + self.items = [] + self.size = 0 + + def empty(self): + return self.items == [] + + def enqueue(self, data): + self.items.insert(0, data) # Always insert items at index 0 + self.size += 1 # increment the size of the queue by 1 + + def dequeue(self): + data = self.items.pop() + self.size -= 1 + return data + + def size1(self): + # print(self.size) + return self.size + + +q= ListQueue() +q.enqueue(4) +q.enqueue('dog') +q.enqueue('cat') +q.enqueue('monday') + + +a= q.size1() +print(a) diff --git a/Chapter05/Queue_application.py b/Chapter05/Queue_application.py new file mode 100644 index 0000000..c456f1a --- /dev/null +++ b/Chapter05/Queue_application.py @@ -0,0 +1,99 @@ +from random import randint + + + +class Node(object): + """ A Doubly-linked lists' node. """ + def __init__(self, data=None, next=None, prev=None): + self.data = data + self.next = next + self.prev = prev + + +class Queue(object): + """ A doubly-linked list. """ + def __init__(self): + self.head = None + self.tail = None + self.count = 0 + + def enqueue(self, data): + """ Append an item to the list. """ + + new_node = Node(data, None, None) + if self.head is None: + self.head = new_node + self.tail = self.head + else: + new_node.prev = self.tail + self.tail.next = new_node + self.tail = new_node + + self.count += 1 + + def dequeue(self): + """ Remove elements from the front of the list""" + current = self.head + if self.count == 1: + self.count -= 1 + self.head = None + self.tail = None + elif self.count > 1: + self.head = self.head.next + self.head.prev = None + self.count -= 1 + return current + + + +queue = Queue() + +import time +start_time = time.time() +for i in range(100000): + queue.enqueue(i) +for i in range(100000): + queue.dequeue() +print("--- %s seconds ---" % (time.time() - start_time)) + + +class Track: + + def __init__(self, title=None): + self.title = title + self.length = randint(5, 10) + + + +track1 = Track("white whistle") +track2 = Track("butter butter") +print(track1.length) +print(track2.length) + +import time +class MediaPlayerQueue(Queue): + + def __init__(self): + super(MediaPlayerQueue, self).__init__() + + def add_track(self, track): + self.enqueue(track) + + def play(self): + while self.count > 0: + current_track_node = self.dequeue() + print("Now playing {}".format(current_track_node.data.title)) + time.sleep(current_track_node.data.length) + +track1 = Track("white whistle") +track2 = Track("butter butter") +track3 = Track("Oh black star") +track4 = Track("Watch that chicken") +track5 = Track("Don't go") +media_player = MediaPlayerQueue() +media_player.add_track(track1) +media_player.add_track(track2) +media_player.add_track(track3) +media_player.add_track(track4) +media_player.add_track(track5) +media_player.play() diff --git a/Chapter05/Stack.py b/Chapter05/Stack.py new file mode 100644 index 0000000..eeceffd --- /dev/null +++ b/Chapter05/Stack.py @@ -0,0 +1,68 @@ +class Node: + def __init__(self, data=None): + self.data = data + self.next = None + + + +class Stack: + def __init__(self): + self.top = None + self.size = 0 + + def push(self, data): + # create a new node + node = Node(data) + if self.top: + node.next = self.top + self.top = node + else: + self.top = node + self.size += 1 + + + + def pop(self): + if self.top: + data = self.top.data + self.size -= 1 + if self.top.next: #check if there is more than one node. + self.top = self.top.next + else: + self.top = None + return data + else: + return None + + + def peek(self): + if self.top: + return self.top.data + else: + return None + + + +words = Stack() +words.push('4') +words.push('5') +words.push('6') +words.push('7') + +#print the stack elements. +current = words.top +while current: + print(current.data) + current = current.next + + +words.pop() + +current = words.top +while current: + print(current.data) + current = current.next + + +words.peek() + diff --git a/Chapter05/Stack_based_queue.py b/Chapter05/Stack_based_queue.py new file mode 100644 index 0000000..da67178 --- /dev/null +++ b/Chapter05/Stack_based_queue.py @@ -0,0 +1,27 @@ +class Queue: + def __init__(self): + self.inbound_stack = [] + self.outbound_stack = [] + + def enqueue(self, data): + self.inbound_stack.append(data) + + + def dequeue(self): + if not self.outbound_stack: + while self.inbound_stack: + self.outbound_stack.append(self.inbound_stack.pop()) + return self.outbound_stack.pop() + + +queue = Queue() +queue.enqueue(5) +queue.enqueue(6) +queue.enqueue(7) +print(queue.inbound_stack) + +queue.dequeue() +print(queue.inbound_stack) +print(queue.outbound_stack) +queue.dequeue() +print(queue.outbound_stack) diff --git a/Chapter06/binary_search_tree.py b/Chapter06/binary_search_tree.py new file mode 100644 index 0000000..49d455b --- /dev/null +++ b/Chapter06/binary_search_tree.py @@ -0,0 +1,145 @@ +class Node: + def __init__(self, data): + self.data = data + self.right_child = None + self.left_child = None + +class Tree: + def __init__(self): + self.root_node = None + + def insert(self, data): + node = Node(data) + if self.root_node is None: + self.root_node = node + else: + current = self.root_node + parent = None + while True: + parent = current + if node.data < parent.data: + current = current.left_child + if current is None: + parent.left_child = node + return + else: + current = current.right_child + if current is None: + parent.right_child = node + return + + + def get_node_with_parent(self, data): + parent = None + current = self.root_node + if current is None: + return (parent, None) + while True: + if current.data == data: + return (parent, current) + elif current.data > data: + parent = current + current = current.left_child + else: + parent = current + current = current.right_child + return (parent, current) + + + def remove(self, data): + parent, node = self.get_node_with_parent(data) + + if parent is None and node is None: + return False + + # Get children count + children_count = 0 + + if node.left_child and node.right_child: + children_count = 2 + elif (node.left_child is None) and (node.right_child is None): + children_count = 0 + else: + children_count = 1 + + if children_count == 0: + if parent: + if parent.right_child is node: + parent.right_child = None + else: + parent.left_child = None + else: + self.root_node = None + elif children_count == 1: + next_node = None + if node.left_child: + next_node = node.left_child + else: + next_node = node.right_child + + if parent: + if parent.left_child is node: + parent.left_child = next_node + else: + parent.right_child = next_node + else: + self.root_node = next_node + else: + parent_of_leftmost_node = node + leftmost_node = node.right_child + while leftmost_node.left_child: + parent_of_leftmost_node = leftmost_node + leftmost_node = leftmost_node.left_child + node.data = leftmost_node.data + + if parent_of_leftmost_node.left_child == leftmost_node: + parent_of_leftmost_node.left_child = leftmost_node.right_child + else: + parent_of_leftmost_node.right_child = leftmost_node.right_child + + + + def search(self, data): + current = self.root_node + while True: + if current is None: + return None + elif current.data is data: + return data + elif current.data > data: + current = current.left_child + else: + current = current.right_child + + + def find_min(self): + current = self.root_node + while current.left_child: + current = current.left_child + return current.data + + + def find_max(self): + current = self.root_node + while current.right_child: + current = current.right_child + return current.data + + + +tree = Tree() +tree.insert(5) +tree.insert(2) +tree.insert(7) +tree.insert(9) +tree.insert(1) + +for i in range(1, 10): + found = tree.search(i) + print("{}: {}".format(i, found)) + + +print(tree.find_min()) + +print(tree.find_max()) + diff --git a/Chapter06/level_order_traversal.py b/Chapter06/level_order_traversal.py new file mode 100644 index 0000000..6278b99 --- /dev/null +++ b/Chapter06/level_order_traversal.py @@ -0,0 +1,35 @@ +from collections import deque + +class Node: + def __init__(self, data): + self.data = data + self.right_child = None + self.left_child = None + + +n1 = Node("root node") +n2 = Node("left child node") +n3 = Node("right child node") +n4 = Node("left grandchild node") + +n1.left_child = n2 +n1.right_child = n3 +n2.left_child = n4 + + + +def level_order_traversal(root_node): + list_of_nodes = [] + traversal_queue = deque([root_node]) + while len(traversal_queue) > 0: + node = traversal_queue.popleft() + list_of_nodes.append(node.data) + if node.left_child: + traversal_queue.append(node.left_child) + if node.right_child: + traversal_queue.append(node.right_child) + return list_of_nodes + + + +print(breadth_first_traversal(n1)) diff --git a/Chapter06/reverse_polish_expression.py b/Chapter06/reverse_polish_expression.py new file mode 100644 index 0000000..e01080d --- /dev/null +++ b/Chapter06/reverse_polish_expression.py @@ -0,0 +1,46 @@ + +class Stack: + def __init__(self): + self.elements = [] + + def push(self, item): + self.elements.append(item) + + def pop(self): + return self.elements.pop() + + +class TreeNode: + def __init__(self, data=None): + self.data = data + self.right = None + self.left = None + +def calc(node): + if node.data == "+": + return calc(node.left) + calc(node.right) + elif node.data == "-": + return calc(node.left) - calc(node.right) + elif node.data == "*": + return calc(node.left) * calc(node.right) + elif node.data == "/": + return calc(node.left) / calc(node.right) + else: + return node.data + +expr = "4 5 + 5 3 - *".split() + +stack = Stack() + +for term in expr: + if term in "+-*/": + node = TreeNode(term) + node.right = stack.pop() + node.left = stack.pop() + else: + node = TreeNode(int(term)) + stack.push(node) + +root = stack.pop() +result = calc(root) +print(result) diff --git a/Chapter06/tree_traversal.py b/Chapter06/tree_traversal.py new file mode 100644 index 0000000..cf3d41d --- /dev/null +++ b/Chapter06/tree_traversal.py @@ -0,0 +1,53 @@ +class Node: + def __init__(self, data): + self.data = data + self.right_child = None + self.left_child = None + + +n1 = Node("root node") +n2 = Node("left child node") +n3 = Node("right child node") +n4 = Node("left grandchild node") +n1.left_child = n2 +n1.right_child = n3 +n2.left_child = n4 + +current = n1 +while current: + print(current.data) + current = current.left_child + +print("\n" ) + +def inorder(root_node): + current = root_node + if current is None: + return + inorder(current.left_child) + print(current.data) + inorder(current.right_child) + +def preorder(root_node): + current = root_node + if current is None: + return + print(current.data) + preorder(current.left_child) + preorder(current.right_child) + + +def postorder(root_node): + current = root_node + if current is None: + return + postorder(current.left_child) + postorder(current.right_child) + print(current.data) + + +inorder( n1) +print("\n" ) +preorder( n1) +print("\n" ) +postorder(n1) diff --git a/Chapter07/heap.py b/Chapter07/heap.py new file mode 100644 index 0000000..e3149f0 --- /dev/null +++ b/Chapter07/heap.py @@ -0,0 +1,50 @@ +class Heap: + def __init__(self): + self.heap = [0] + self.size = 0 + + def arrange(self, k): + while k // 2 > 0: + if self.heap[k] < self.heap[k//2]: + self.heap[k], self.heap[k//2] = self.heap[k//2], self.heap[k] + k //= 2 + + def insert(self, item): + self.heap.append(item) + self.size += 1 + self.arrange(self.size) + + def sink(self, k): + while k * 2 <= self.size: + mc = self.minchild(k) + if self.heap[k] > self.heap[mc]: + self.heap[k], self.heap[mc] = self.heap[mc], self.heap[k] + k = mc + + def minchild(self, k): + if k * 2 + 1 > self.size: + return k * 2 + elif self.heap[k*2] < self.heap[k*2+1]: + return k * 2 + else: + return k * 2 + 1 + + def pop(self): + item = self.heap[1] + self.heap[1] = self.heap[self.size] + self.size -= 1 + self.heap.pop() + self.sink(1) + return item + + +h = Heap() +for i in ( 4, 8, 7, 2, 9, 10, 5, 1, 3, 6): + h.insert(i) + +print(h.heap) + +for i in range(10): + n = h.pop() + print(n) + print(h.heap) diff --git a/Chapter07/heap_sort.py b/Chapter07/heap_sort.py new file mode 100644 index 0000000..f673e01 --- /dev/null +++ b/Chapter07/heap_sort.py @@ -0,0 +1,66 @@ +class Heap: + def __init__(self): + self.heap = [0] + self.size = 0 + + def arrange(self, k): + while k // 2 > 0: + if self.heap[k] < self.heap[k//2]: + self.heap[k], self.heap[k//2] = self.heap[k//2], self.heap[k] + k //= 2 + + def insert(self, item): + self.heap.append(item) + self.size += 1 + self.arrange(self.size) + + def sink(self, k): + while k * 2 <= self.size: + mc = self.minchild(k) + if self.heap[k] > self.heap[mc]: + self.heap[k], self.heap[mc] = self.heap[mc], self.heap[k] + k = mc + + def minchild(self, k): + if k * 2 + 1 > self.size: + return k * 2 + elif self.heap[k*2] < self.heap[k*2+1]: + return k * 2 + else: + return k * 2 + 1 + + def pop(self): + item = self.heap[1] + self.heap[1] = self.heap[self.size] + self.size -= 1 + self.heap.pop() + self.sink(1) + return item + + def heap_sort(self): + sorted_list = [] + for node in range(self.size): + n = self.pop() + sorted_list.append(n) + return sorted_list + + + +h = Heap() +for i in ( 4, 8, 7, 2, 9, 10, 5, 1, 3, 6): + h.insert(i) + +print(h.heap) + + +h = Heap() +unsorted_list = [4, 8, 7, 2, 9, 10, 5, 1, 3, 6] + + +for i in unsorted_list: + h.insert(i) + +print("Unsorted list: {}".format(unsorted_list)) + + +h.heap_sort() diff --git a/Chapter08/hashing.py b/Chapter08/hashing.py new file mode 100644 index 0000000..3b49cf3 --- /dev/null +++ b/Chapter08/hashing.py @@ -0,0 +1,10 @@ +def hash(data): + counter = 1 + sum = 0 + for d in data: + sum += counter * ord(d) + return sum % 256 + +items = ['foo', 'bar', 'bim', 'baz', 'quux', 'duux', 'gnn'] +for item in items: + print("{}: {}".format(item, hash(item))) diff --git a/Chapter08/hashtable.py b/Chapter08/hashtable.py new file mode 100644 index 0000000..9254f14 --- /dev/null +++ b/Chapter08/hashtable.py @@ -0,0 +1,74 @@ +class HashItem: + def __init__(self, key, value): + self.key = key + self.value = value + + +class HashTable: + def __init__(self): + self.size = 256 + self.slots = [None for i in range(self.size)] + self.count = 0 + + def _hash(self, key): + mult = 1 + hv = 0 + for ch in key: + hv += mult * ord(ch) + mult += 1 + return hv % self.size + + def put(self, key, value): + item = HashItem(key, value) + h = self._hash(key) + + while self.slots[h] != None: + if self.slots[h].key == key: + break + h = (h + 1) % self.size + if self.slots[h] == None: + self.count += 1 + self.slots[h] = item + + def get(self, key): + h = self._hash(key) + while self.slots[h] != None: + if self.slots[h].key == key: + return self.slots[h].value + h = (h+ 1) % self.size + return None + + def __setitem__(self, key, value): + self.put(key, value) + + def __getitem__(self, key): + return self.get(key) + + +ht = HashTable() +ht.put("good", "eggs") +ht.put("better", "ham") +ht.put("best", "spam") +ht.put("ad", "do not") +ht.put("ga", "collide") + +for key in ("good", "better", "best", "worst", "ad", "ga"): + v = ht.get(key) + print(v) + + + + +ht = HashTable() +ht["good"] = "eggs" +ht["better"] = "ham" +ht["best"] = "spam" +ht["ad"] = "do not" +ht["ga"] = "collide" +ht["data"] = "value" + +for key in ("good", "better", "best", "worst", "ad", "ga"): + v = ht[key] + print(v) + +print("The number of elements is: {}".format(ht.count)) diff --git a/Chapter09/breadth_first_search.py b/Chapter09/breadth_first_search.py new file mode 100644 index 0000000..28165c9 --- /dev/null +++ b/Chapter09/breadth_first_search.py @@ -0,0 +1,33 @@ +graph = dict() +graph['A'] = ['B', 'G', 'D'] +graph['B'] = ['A', 'F', 'E'] +graph['C'] = ['F', 'H'] +graph['D'] = ['F', 'A'] +graph['E'] = ['B', 'G'] +graph['F'] = ['B', 'D', 'C'] +graph['G'] = ['A', 'E'] +graph['H'] = ['C'] + + +from collections import deque + +def breadth_first_search(graph, root): + visited_vertices = list() + graph_queue = deque([root]) + visited_vertices.append(root) + node = root + + while len(graph_queue) > 0: + node = graph_queue.popleft() + adj_nodes = graph[node] + + remaining_elements = set(adj_nodes).difference(set(visited_vertices)) + if len(remaining_elements) > 0: + for elem in sorted(remaining_elements): + visited_vertices.append(elem) + graph_queue.append(elem) + + return visited_vertices + + +print(breadth_first_search(graph, 'A')) diff --git a/Chapter09/depth_first_search.py b/Chapter09/depth_first_search.py new file mode 100644 index 0000000..36232b4 --- /dev/null +++ b/Chapter09/depth_first_search.py @@ -0,0 +1,36 @@ +graph = dict() +graph['A'] = ['B', 'S'] +graph['B'] = ['A'] +graph['S'] = ['A','G','C'] +graph['D'] = ['C'] +graph['G'] = ['S','F','H'] +graph['H'] = ['G','E'] +graph['E'] = ['C','H'] +graph['F'] = ['C','G'] +graph['C'] = ['D','S','E','F'] + +def depth_first_search(graph, root): + visited_vertices = list() + graph_stack = list() + graph_stack.append(root) + node = root + while len(graph_stack) > 0: + if node not in visited_vertices: + visited_vertices.append(node) + adj_nodes = graph[node] + if set(adj_nodes).issubset(set(visited_vertices)): + graph_stack.pop() + if len(graph_stack) > 0: + node = graph_stack[-1] + continue + else: + remaining_elements = set(adj_nodes).difference(set(visited_vertices)) + + first_adj_node = sorted(remaining_elements)[0] + graph_stack.append(first_adj_node) + node = first_adj_node + return visited_vertices + + + +print(depth_first_search(graph, 'A')) diff --git a/Chapter09/graph.py b/Chapter09/graph.py new file mode 100644 index 0000000..58cc88b --- /dev/null +++ b/Chapter09/graph.py @@ -0,0 +1,31 @@ +graph = dict() +graph['A'] = ['B', 'C'] +graph['B'] = ['E','C', 'A'] +graph['C'] = ['A', 'B', 'E','F'] +graph['E'] = ['B', 'C'] +graph['F'] = ['C'] + +matrix_elements = sorted(graph.keys()) +cols = rows = len(matrix_elements) + +adjacency_matrix = [[0 for x in range(rows)] for y in range(cols)] + +edges_list = [] + + +for key in matrix_elements: + for neighbor in graph[key]: + edges_list.append((key,neighbor)) + + +print(edges_list) + + + +for edge in edges_list: + index_of_first_vertex = matrix_elements.index(edge[0]) + index_of_second_vertex = matrix_elements.index(edge[1]) + adjacency_matrix[index_of_first_vertex][index_of_second_vertex] = 1 + + +print(adjacency_matrix) diff --git a/Chapter10/Unordered_linear_search.py b/Chapter10/Unordered_linear_search.py new file mode 100644 index 0000000..66a037a --- /dev/null +++ b/Chapter10/Unordered_linear_search.py @@ -0,0 +1,27 @@ + +def search(unordered_list, term): + unordered_list_size = len(unordered_list) + for i in range(unordered_list_size): + if term == unordered_list[i]: + return i + return None + + + +scores = [60, 1, 88, 10, 11, 600] + +search_term = 65 +position = search(scores, search_term) + +if position is None: + print("{} not found".format(search_term)) +else: + print("{} found at position {}".format(search_term, position)) + + +search_term = 600 +position = search(scores, search_term) +if position is None: + print("{} not found".format(search_term)) +else: + print("{} found at position {}".format(search_term, position)) diff --git a/Chapter10/binary_search_iterative.py b/Chapter10/binary_search_iterative.py new file mode 100644 index 0000000..c8cc4cd --- /dev/null +++ b/Chapter10/binary_search_iterative.py @@ -0,0 +1,23 @@ +def binary_search_iterative(ordered_list, term): + size_of_list = len(ordered_list) - 1 + index_of_first_element = 0 + index_of_last_element = size_of_list + while index_of_first_element <= index_of_last_element: + mid_point = (index_of_first_element + index_of_last_element)//2 + if ordered_list[mid_point] == term: + return mid_point + if term > ordered_list[mid_point]: + index_of_first_element = mid_point + 1 + else: + index_of_last_element = mid_point - 1 + + + +store = [1, 4, 5, 12, 43, 54, 60, 77] +a = binary_search_iterative(store, 2) +print("Index position of value 2 is", a) + + +print(binary_search_iterative(store, 7)) + +print(binary_search_iterative(store, 60)) diff --git a/Chapter10/binary_search_recursive b/Chapter10/binary_search_recursive new file mode 100644 index 0000000..914b1d4 --- /dev/null +++ b/Chapter10/binary_search_recursive @@ -0,0 +1,17 @@ +def binary_search_recursive(ordered_list, first_element_index, last_element_index, term): + if (last_element_index < first_element_index): + return None + else: + mid_point = first_element_index + ((last_element_index - first_element_index) // 2) + + if ordered_list[mid_point] > term: + return binary_search(ordered_list, first_element_index, mid_point-1,term) + elif ordered_list[mid_point] < term: + return binary_search(ordered_list, mid_point+1, last_element_index, term) + else: + return mid_point + + +store = [2, 4, 5, 12, 43, 54, 60, 77] +print(binary_search_recursive(store, 0, 7, 12)) + diff --git a/Chapter10/interpolation_search.py b/Chapter10/interpolation_search.py new file mode 100644 index 0000000..6301267 --- /dev/null +++ b/Chapter10/interpolation_search.py @@ -0,0 +1,26 @@ + +def nearest_mid(input_list, lower_bound_index, upper_bound_index, search_value): + return lower_bound_index + (( upper_bound_index - lower_bound_index)// + (input_list[upper_bound_index] - input_list[lower_bound_index])) * (search_value - input_list[lower_bound_index]) + + +def interpolation_search(ordered_list, term): + size_of_list = len(ordered_list) - 1 + index_of_first_element = 0 + index_of_last_element = size_of_list + while index_of_first_element <= index_of_last_element: + mid_point = nearest_mid(ordered_list, index_of_first_element, index_of_last_element, term) + if mid_point > index_of_last_element or mid_point < index_of_first_element: + return None + if ordered_list[mid_point] == term: + return mid_point + if term > ordered_list[mid_point]: + index_of_first_element = mid_point + 1 + else: + index_of_last_element = mid_point - 1 + + + +store = [2, 4, 5, 12, 43, 54, 60, 77] +a = interpolation_search(store, 2) +print("Index position of value 2 is ",a) diff --git a/Chapter10/search_ordered_list.py b/Chapter10/search_ordered_list.py new file mode 100644 index 0000000..f819076 --- /dev/null +++ b/Chapter10/search_ordered_list.py @@ -0,0 +1,30 @@ + +def search_ordered(ordered_list, term): + ordered_list_size = len(ordered_list) + for i in range(ordered_list_size): + if term == ordered_list[i]: + return i + elif ordered_list[i] > term: + return None + + return None + + + +scores = [2, 3, 4, 6, 7] + +search_term = 5 +position = search_ordered(scores, search_term) + +if position is None: + print("{} not found".format(search_term)) +else: + print("{} found at position {}".format(search_term, position)) + + +search_term = 2 +position = search_ordered(scores, search_term) +if position is None: + print("{} not found".format(search_term)) +else: + print("{} found at position {}".format(search_term, position)) diff --git a/Chapter11/Insertion_sort.py b/Chapter11/Insertion_sort.py new file mode 100644 index 0000000..fd1634b --- /dev/null +++ b/Chapter11/Insertion_sort.py @@ -0,0 +1,18 @@ + +def insertion_sort(unsorted_list): + for index in range(1, len(unsorted_list)): + search_index = index + insert_value = unsorted_list[index] + while search_index > 0 and unsorted_list[search_index-1] > insert_value : + unsorted_list[search_index] = unsorted_list[search_index-1] + search_index -= 1 + unsorted_list[search_index] = insert_value + + + + + +my_list = [10, 11, 12, 1, 2, 3] +print(my_list) +insertion_sort(my_list) +print(my_list) diff --git a/Chapter11/Quick_sort.py b/Chapter11/Quick_sort.py new file mode 100644 index 0000000..96efa57 --- /dev/null +++ b/Chapter11/Quick_sort.py @@ -0,0 +1,35 @@ +def partition(unsorted_array, first_index, last_index): + pivot = unsorted_array[first_index] + pivot_index = first_index + index_of_last_element = last_index + less_than_pivot_index = index_of_last_element + greater_than_pivot_index = first_index + 1 + while True: + while unsorted_array[greater_than_pivot_index] < pivot and greater_than_pivot_index < last_index: + greater_than_pivot_index += 1 + while unsorted_array[less_than_pivot_index] > pivot and less_than_pivot_index >= first_index: + less_than_pivot_index -= 1 + if greater_than_pivot_index < less_than_pivot_index: + temp = unsorted_array[greater_than_pivot_index] + unsorted_array[greater_than_pivot_index] = unsorted_array[less_than_pivot_index] + unsorted_array[less_than_pivot_index] = temp + else: + break + unsorted_array[pivot_index] = unsorted_array[less_than_pivot_index] + unsorted_array[less_than_pivot_index] = pivot + return less_than_pivot_index + + +def quick_sort(unsorted_array, first, last): + if last - first <= 0: + return + else: + partition_point = partition(unsorted_array, first, last) + quick_sort(unsorted_array, first, partition_point-1) + quick_sort(unsorted_array, partition_point+1, last) + + +my_array = [43, 3, 77, 89, 4, 20] +print(my_array) +quick_sort(my_array, 0, 5) +print(my_array) diff --git a/Chapter11/Selection_Sort.py b/Chapter11/Selection_Sort.py new file mode 100644 index 0000000..fa39989 --- /dev/null +++ b/Chapter11/Selection_Sort.py @@ -0,0 +1,14 @@ + +def selection_sort(unsorted_list): + size_of_list = len(unsorted_list) + for i in range(size_of_list): + for j in range(i+1, size_of_list): + if unsorted_list[j] < unsorted_list[i]: + temp = unsorted_list[i] + unsorted_list[i] = unsorted_list[j] + unsorted_list[j] = temp + + +a_list = [3, 2, 35, 4, 32, 94, 5, 7] +selection_sort(a_list) +print(a_list) diff --git a/Chapter11/bubble_sort.py b/Chapter11/bubble_sort.py new file mode 100644 index 0000000..58e2f81 --- /dev/null +++ b/Chapter11/bubble_sort.py @@ -0,0 +1,29 @@ +unordered_list = [5, 2] + +temp = unordered_list[0] +unordered_list[0] = unordered_list[1] +unordered_list[1] = temp + +print(unordered_list) + + + +def bubble_sort(unordered_list): + iteration_number = len(unordered_list)-1 + for i in range(iteration_number,0,-1): + for j in range(i): + if unordered_list[j] > unordered_list[j+1]: + temp = unordered_list[j] + unordered_list[j] = unordered_list[j+1] + unordered_list[j+1] = temp + + + + +my_list = [4,3,2,1] +bubble_sort(my_list) +print(my_list) + +my_list = [1,12,3,4] +bubble_sort(my_list) +print(my_list) diff --git a/Chapter12/deterministic_selection.py b/Chapter12/deterministic_selection.py new file mode 100644 index 0000000..8258e3b --- /dev/null +++ b/Chapter12/deterministic_selection.py @@ -0,0 +1,85 @@ +def partition(unsorted_array, first_index, last_index): + if first_index == last_index: + return first_index + else: + nearest_median = median_of_medians(unsorted_array[first_index:last_index]) + + index_of_nearest_median = get_index_of_nearest_median(unsorted_array, first_index, + last_index, nearest_median) + swap(unsorted_array, first_index, index_of_nearest_median) + + pivot = unsorted_array[first_index] + pivot_index = first_index + index_of_last_element = last_index + less_than_pivot_index = index_of_last_element + greater_than_pivot_index = first_index + 1 + + ## This while loop is used to correctly place pivot element at its correct position + while 1: + while unsorted_array[greater_than_pivot_index] < pivot and greater_than_pivot_index < last_index: + greater_than_pivot_index += 1 + while unsorted_array[less_than_pivot_index] > pivot and less_than_pivot_index >= first_index: + less_than_pivot_index -= 1 + + if greater_than_pivot_index < less_than_pivot_index: + temp = unsorted_array[greater_than_pivot_index] + unsorted_array[greater_than_pivot_index] = unsorted_array[less_than_pivot_index] + unsorted_array[less_than_pivot_index] = temp + else: + break + + unsorted_array[pivot_index]=unsorted_array[less_than_pivot_index] + unsorted_array[less_than_pivot_index]=pivot + return less_than_pivot_index + + +def median_of_medians(elems): + + sublists = [elems[j:j+5] for j in range(0, len(elems), 5)] + medians = [] + for sublist in sublists: + medians.append(sorted(sublist)[int(len(sublist)/2)]) + + if len(medians) <= 5: + return sorted(medians)[int(len(medians)/2)] + else: + return median_of_medians(medians) + + + +def get_index_of_nearest_median(array_list, first, second, median): + if first == second: + return first + else: + return first + array_list[first:second].index(median) + + + + +def swap(array_list, first, second): + temp = array_list[first] + array_list[first] = array_list[second] + array_list[second] = temp + + + + +def deterministic_select(array_list, left, right, k): + + split = partition(array_list, left, right) + if split == k: + return array_list[split] + elif split < k: + return deterministic_select(array_list, split + 1, right, k) + else: + return deterministic_select(array_list, left, split-1, k) + + + + +stored = [3,1,10,4,6, 5] +print(deterministic_select(stored, 0, 5, 2)) + + + + diff --git a/Chapter12/randomized_search.py b/Chapter12/randomized_search.py new file mode 100644 index 0000000..655afbb --- /dev/null +++ b/Chapter12/randomized_search.py @@ -0,0 +1,67 @@ +def partition(unsorted_array, first_index, last_index): + + pivot = unsorted_array[first_index] + pivot_index = first_index + index_of_last_element = last_index + + less_than_pivot_index = index_of_last_element + greater_than_pivot_index = first_index + 1 + + while True: + + while unsorted_array[greater_than_pivot_index] < pivot and greater_than_pivot_index < last_index: + greater_than_pivot_index += 1 + while unsorted_array[less_than_pivot_index] > pivot and less_than_pivot_index >= first_index: + less_than_pivot_index -= 1 + + if greater_than_pivot_index < less_than_pivot_index: + temp = unsorted_array[greater_than_pivot_index] + unsorted_array[greater_than_pivot_index] = unsorted_array[less_than_pivot_index] + unsorted_array[less_than_pivot_index] = temp + else: + break + + unsorted_array[pivot_index] = unsorted_array[less_than_pivot_index] + unsorted_array[less_than_pivot_index] = pivot + + return less_than_pivot_index + + +def quick_select(array_list, left, right, k): + + split = partition(array_list, left, right) + + if split == k: + return array_list[split] + elif split < k: + return quick_select(array_list, split + 1, right, k) + else: + return quick_select(array_list, left, split-1, k) + + +stored = [5, 3] +print(stored) +print(quick_select(stored, 0, 1, 0)) + +stored = [3, 5] +print(stored) +print(quick_select(stored, 0, 1, 0)) + + + + + + +stored = [3,1,10,4,6,5] +print(stored) +print(quick_select(stored, 0, 5, 0)) +stored = [3,1,10,4,6, 5] +print(quick_select(stored, 0, 5, 1)) +stored = [3,1,10,4,6, 5] +print(quick_select(stored, 0, 5, 2)) +stored = [3,1,10,4,6, 5] +print(quick_select(stored, 0, 5, 3)) +stored = [3,1,10,4,6, 5] +print(quick_select(stored, 0, 5, 4)) +stored = [3,1,10,4,6, 5] +print(quick_select(stored, 0, 5, 5)) diff --git a/Chapter13/Boyer_Moore_String_Matching.py b/Chapter13/Boyer_Moore_String_Matching.py new file mode 100644 index 0000000..a25803b --- /dev/null +++ b/Chapter13/Boyer_Moore_String_Matching.py @@ -0,0 +1,46 @@ +text = "acbaacacababacacac" +pattern = "acacac" + + +matched_indexes = [] + +i=0 +flag = True +while i<=len(text)-len(pattern): + for j in range(len(pattern)-1, -1, -1): #reverse searching + if pattern[j] != text[i+j]: + flag = False #indicates there is a mismatch + if j == len(pattern)-1: #if good-suffix is not present, we test bad character + if text[i+j] in pattern[0:j]: + i=i+j-pattern[0:j].rfind(text[i+j]) + #i+j is index of bad character, this line is used for jumping pattern to match + #bad character of text with same character in pattern + else: + i=i+j+1 #if bad character is not present, jump pattern next to it + else: + k=1 + while text[i+j+k:i+len(pattern)] not in pattern[0:len(pattern)-1]: + #used for finding sub part of a good-suffix + k=k+1 + if len(text[i+j+k:i+len(pattern)]) != 1: #good-suffix should not be of one character + gsshift=i+j+k-pattern[0:len(pattern)-1].rfind(text[i+j+k:i+len(pattern)]) + #jumps pattern to a position where good-suffix of pattern matches with good-suffix of text + else: + #gsshift=i+len(pattern) + gsshift=0 #when good-suffix heuristic is not applicable, + #we prefer bad character heuristic + if text[i+j] in pattern[0:j]: + bcshift=i+j-pattern[0:j].rfind(text[i+j]) + #i+j is index of bad character, this line is used for jumping pattern to match bad character + #of text with same character in pattern + else: + bcshift=i+j+1 + i=max((bcshift, gsshift)) + break + if flag: #if pattern is found then normal iteration + matched_indexes.append(i) + i = i+1 + else: #again set flag to True so new string in text can be examined + flag = True + +print ("Pattern found at", matched_indexes) diff --git a/Chapter13/Brute_force_string_matching.py b/Chapter13/Brute_force_string_matching.py new file mode 100644 index 0000000..bc614e5 --- /dev/null +++ b/Chapter13/Brute_force_string_matching.py @@ -0,0 +1,27 @@ +def brute_force(text, pattern): + l1 = len(text) # The length of the text string + l2 = len(pattern) # The length of the pattern + i = 0 + j = 0 # looping variables are set to 0 + flag = False # If the pattern doesn't appear at all, then set this to false and execute the last if statement + while i < l1: # iterating from the 0th index of text + j = 0 + count = 0 + # Count stores the length upto which the pattern and the text have matched + while j < l2: + if i+j < l1 and text[i+j] == pattern[j]: + # statement to check if a match has occurred or not + count += 1 # Count is incremented if a character is matched + j += 1 + if count == l2: # it shows a matching of pattern in the text + print("\nPattern occurs at index", i) + # print the starting index of the successful match + flag = True + # flag is True as we wish to continue looking for more matching of pattern in the text. + i += 1 + if not flag: + # If the pattern doesn't occurs at all, means no match of pattern in the text string + print('\nPattern is not at all present in the array') + + +brute_force('acbcabccababcaacbcac','acbcac') # function call diff --git a/Chapter13/Rabin_Karp_String_Matching.py b/Chapter13/Rabin_Karp_String_Matching.py new file mode 100644 index 0000000..dda066f --- /dev/null +++ b/Chapter13/Rabin_Karp_String_Matching.py @@ -0,0 +1,46 @@ +def generate_hash(text, pattern): + ord_text = [ord(i) for i in text] # stores unicode value of each character in text + ord_pattern = [ord(j) for j in pattern] # stores unicode value of each character in pattern + len_text = len(text) # stores length of the text + len_pattern = len(pattern) # stores length of the pattern + len_hash_array = len_text - len_pattern + 1 # stores the length of new array that will contain the hash values of text + hash_text = [0]*(len_hash_array) # Initialize all the values in the array to 0. + hash_pattern = sum(ord_pattern) + for i in range(0,len_hash_array): # step size of the loop will be the size of the pattern + if i == 0: # Base condition + hash_text[i] = sum(ord_text[:len_pattern]) # initial value of hash function + else: + hash_text[i] = ((hash_text[i-1] - ord_text[i-1]) + ord_text[i+len_pattern-1]) # calculating next hash value using previous value + return [hash_text, hash_pattern] # return the hash values + + + +def Rabin_Karp_Matcher(text, pattern): + text = str(text) # convert text into string format + pattern = str(pattern) # convert pattern into string format + hash_text, hash_pattern = generate_hash(text, pattern) # generate hash values using generate_hash function + len_text = len(text) # length of text + len_pattern = len(pattern) # length of pattern + flag = False # checks if pattern is present atleast once or not at all + for i in range(len(hash_text)): + if hash_text[i] == hash_pattern: # if the hash value matches + count = 0 # count stores the total characters upto which both are similar + for j in range(len_pattern): + if pattern[j] == text[i+j]: # checking equality for each character + count += 1 # if value is equal, then update the count value + else: + break + if count == len_pattern: # if count is equal to length of pattern, it means match has been found + flag = True # update flag accordingly + print('Pattern occours at index',i) + if not flag: # if pattern doesn't match even once, then this if statement is executed + print('Pattern is not at all present in the text') + + +Rabin_Karp_Matcher("101110000011010010101101","10112") + +# Works for numeric +Rabin_Karp_Matcher("101110000011010010101101","1011") + +# Works for alphabets +Rabin_Karp_Matcher("ABBACCADABBACCEDF","ACCE") diff --git a/Chapter13/example_suffix_prefix.py b/Chapter13/example_suffix_prefix.py new file mode 100644 index 0000000..42d2741 --- /dev/null +++ b/Chapter13/example_suffix_prefix.py @@ -0,0 +1,6 @@ +string = "this is data structures book by packt publisher" +suffix = "publisher" +prefix = "this" +print(string.endswith(suffix)) #Check if string contains given suffix. + +print(string.startswith(prefix)) #Check if string starts with given prefix. From 2752f06ae472744ee7bb8ca6ec0a8312f1493e2e Mon Sep 17 00:00:00 2001 From: packtriannar <73225051+packtriannar@users.noreply.github.com> Date: Tue, 26 Apr 2022 14:47:22 +0530 Subject: [PATCH 02/53] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 138e58f..12ec142 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ -# Data-Structures-and-Algorithms-with-Python-Third-Edition-published-by-Packt -Data Structures and Algorithms with Python – Third Edition +# Hands-On Data-Structures-and-Algorithms-with-Python-Third-Edition-published-by-Packt +Hands-On Data Structures and Algorithms with Python – Third Edition From 7445efb462354dbaddc57cba3a8fe57ac1f87408 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Tue, 26 Apr 2022 15:03:20 +0530 Subject: [PATCH 03/53] Old --- Chapter01/chapter1.py | 578 ------------------ Chapter02/binary_search.py | 16 - Chapter02/linear_search.py | 12 - Chapter02/matrix_chain.py | 14 - Chapter02/merge_sort.py | 37 -- Chapter03/Fibonacci_series.py | 8 - Chapter03/MatrixChain_multiplication.py | 14 - Chapter03/binary_search.py | 16 - Chapter03/dijkstra.py | 80 --- Chapter03/dyna_fib.py | 13 - Chapter03/factorial.py | 10 - Chapter03/merge_sort.py | 35 -- Chapter04/CircularList.py | 99 --- Chapter04/SinglyLinkedList.py | 33 - ...ppend_at_any_location_singly_linkedlist.py | 64 -- .../delete_operation_doubly_linkedlist.py | 75 --- .../delete_operation_singly_linkedlist.py | 74 --- Chapter04/doubly_linked_list.py | 69 --- Chapter04/faster_append_singly_linked_list.py | 31 - Chapter04/list_traversal_singly_linklist.py | 37 -- Chapter05/Linked_list_based_queue.py | 45 -- Chapter05/List_based_queue.py | 37 -- Chapter05/Queue_application.py | 99 --- Chapter05/Stack.py | 68 --- Chapter05/Stack_based_queue.py | 27 - Chapter06/binary_search_tree.py | 145 ----- Chapter06/level_order_traversal.py | 35 -- Chapter06/reverse_polish_expression.py | 46 -- Chapter06/tree_traversal.py | 53 -- Chapter07/heap.py | 50 -- Chapter07/heap_sort.py | 66 -- Chapter08/hashing.py | 10 - Chapter08/hashtable.py | 74 --- Chapter09/breadth_first_search.py | 33 - Chapter09/depth_first_search.py | 36 -- Chapter09/graph.py | 31 - Chapter10/Unordered_linear_search.py | 27 - Chapter10/binary_search_iterative.py | 23 - Chapter10/binary_search_recursive | 17 - Chapter10/interpolation_search.py | 26 - Chapter10/search_ordered_list.py | 30 - Chapter11/Insertion_sort.py | 18 - Chapter11/Quick_sort.py | 35 -- Chapter11/Selection_Sort.py | 14 - Chapter11/bubble_sort.py | 29 - Chapter12/deterministic_selection.py | 85 --- Chapter12/randomized_search.py | 67 -- Chapter13/Boyer_Moore_String_Matching.py | 46 -- Chapter13/Brute_force_string_matching.py | 27 - Chapter13/Rabin_Karp_String_Matching.py | 46 -- Chapter13/example_suffix_prefix.py | 6 - 51 files changed, 2666 deletions(-) delete mode 100644 Chapter01/chapter1.py delete mode 100644 Chapter02/binary_search.py delete mode 100644 Chapter02/linear_search.py delete mode 100644 Chapter02/matrix_chain.py delete mode 100644 Chapter02/merge_sort.py delete mode 100644 Chapter03/Fibonacci_series.py delete mode 100644 Chapter03/MatrixChain_multiplication.py delete mode 100644 Chapter03/binary_search.py delete mode 100644 Chapter03/dijkstra.py delete mode 100644 Chapter03/dyna_fib.py delete mode 100644 Chapter03/factorial.py delete mode 100644 Chapter03/merge_sort.py delete mode 100644 Chapter04/CircularList.py delete mode 100644 Chapter04/SinglyLinkedList.py delete mode 100644 Chapter04/append_at_any_location_singly_linkedlist.py delete mode 100644 Chapter04/delete_operation_doubly_linkedlist.py delete mode 100644 Chapter04/delete_operation_singly_linkedlist.py delete mode 100644 Chapter04/doubly_linked_list.py delete mode 100644 Chapter04/faster_append_singly_linked_list.py delete mode 100644 Chapter04/list_traversal_singly_linklist.py delete mode 100644 Chapter05/Linked_list_based_queue.py delete mode 100644 Chapter05/List_based_queue.py delete mode 100644 Chapter05/Queue_application.py delete mode 100644 Chapter05/Stack.py delete mode 100644 Chapter05/Stack_based_queue.py delete mode 100644 Chapter06/binary_search_tree.py delete mode 100644 Chapter06/level_order_traversal.py delete mode 100644 Chapter06/reverse_polish_expression.py delete mode 100644 Chapter06/tree_traversal.py delete mode 100644 Chapter07/heap.py delete mode 100644 Chapter07/heap_sort.py delete mode 100644 Chapter08/hashing.py delete mode 100644 Chapter08/hashtable.py delete mode 100644 Chapter09/breadth_first_search.py delete mode 100644 Chapter09/depth_first_search.py delete mode 100644 Chapter09/graph.py delete mode 100644 Chapter10/Unordered_linear_search.py delete mode 100644 Chapter10/binary_search_iterative.py delete mode 100644 Chapter10/binary_search_recursive delete mode 100644 Chapter10/interpolation_search.py delete mode 100644 Chapter10/search_ordered_list.py delete mode 100644 Chapter11/Insertion_sort.py delete mode 100644 Chapter11/Quick_sort.py delete mode 100644 Chapter11/Selection_Sort.py delete mode 100644 Chapter11/bubble_sort.py delete mode 100644 Chapter12/deterministic_selection.py delete mode 100644 Chapter12/randomized_search.py delete mode 100644 Chapter13/Boyer_Moore_String_Matching.py delete mode 100644 Chapter13/Brute_force_string_matching.py delete mode 100644 Chapter13/Rabin_Karp_String_Matching.py delete mode 100644 Chapter13/example_suffix_prefix.py diff --git a/Chapter01/chapter1.py b/Chapter01/chapter1.py deleted file mode 100644 index 2631bf5..0000000 --- a/Chapter01/chapter1.py +++ /dev/null @@ -1,578 +0,0 @@ -p = "Hello India" -q = 10 -r = 10.2 -print(type(p)) -print(type(q)) -print(type(r)) -print(type(12+31j)) - -############### - -var = 13.2 -print(var) -#13.2 - -type (var) -# - -var = "Now the type is string" -print(var) - -type(var) -# -var = 13.2 -print(var) -#13.2 - -############# -print(type(bool(22))) -print(type(True)) -print(type(False)) -''' -Output: - - - -''' - -bool(False) -#False -va1 = 0 -print(bool(va1)) -#False - -va2 = 11 -print(bool(va2)) -#True - -va3 = -2.3 -print(bool(va3)) -#True - -#### Strings -Str1 = 'Hello how are you' -str2 = "Hello how are you" -str3 = 'multiline'+'string'; -print(str3) - -f = 'data' -s = 'structure' -print(f + s) -#'datastructure' -print('Data ' + 'structure') -#Data structure - - -st = 'data.' -print(st * 3) -#'data.data.data.' -print(3 * st) -#'data.data.data.' - - -###### Lists ###### - -a = ['food', 'bus', 'apple', 'queen'] -print(a) -#['food', 'bus', 'apple', 'queen'] - - -mylist = [10, "India", "world", 8] -# accessing elements in list. -print(mylist[1]) -#India - - - -###### Ordered List ###### - -[10, 12, 31, 14] == [14, 10, 31, 12] -print([10, 12, 31, 14] == [14, 10, 31, 12]) -#False - - -###### Dynamic List ###### -b = ['data', 'and', 'book', 'structure', 'hello', 'st'] - -b += [32] -print(b) -#['data', 'and', 'book', 'structure', 'hello', 'st', 32] - - -b[2:3] = [] -print(b) -#['data', 'and', 'structure', 'hello', 'st', 32] - -del b[0] -print(b) -#['and', 'structure', 'hello', 'st', 32] - -a = [2.2, 'python', 31, 14, 'data', False, 33.59] -print(a) -#[2.2, 'python', 31, 14, 'data', False, 33.59] - - -a = ['data', 'structures', 'using', 'python', 'happy', 'learning'] -print(a[0]) -'data' -print(a[2]) -'using' -print(a[-1]) -'learning' -print(a[-5]) -'structures' - - -print(a[1:5]) -['structures', 'using'] - -print(a[-3:-1]) -['python', 'happy'] - -######### Mutable #### -a = ['data', 'and', 'book', 'structure', 'hello', 'st'] -print(a) -['data', 'and', 'book', 'structure', 'hello', 'st'] -a[1] = 1 -a[-1] = 120 -print(a) -['data', 1, 'book', 'structure', 'hello', 120] - -a = ['data', 'and', 'book', 'structure', 'hello', 'st'] - -print(a[2:5]) -['book', 'structure', 'hello'] -a[2:5] = [1, 2, 3, 4, 5] -print(a) -['data', 'and', 1, 2, 3, 4, 5, 'st'] - -######### Other operators #### - -a = ['data', 'structures', 'using', 'python', 'happy', 'learning'] -print('data' in a) -#True - -print(a) -#['data', 'structures', 'using', 'python', 'happy', 'learning'] - -a + ['New', 'elements'] -print(a) -#['data', 'structures', 'using', 'python', 'happy', 'learning', 'New', 'elements'] - -print(a * 2) -#['data', 'structures', 'using', 'python', 'happy', 'learning', 'New', 'elements', 'data', 'structures', 'using', 'python', 'happy', 'learning', 'New', 'elements'] - -print(len(a)) -#6 -print(min(a)) - - -############ Membership operators - -#using 'in' operator -mylist1=[100,20,30,40] -mylist2=[10,50,60,90] -if mylist1[1] in mylist2: - print("elements are overlapping") -else: - print("elements are not overlapping") - -#Output: -#elements are not overlapping - - -########## Program to illustrate 'not in' operator -val = 104 -mylist = [100, 210, 430, 840, 108] -if val not in mylist: - print("val is NOT present in mylist") -else: - print("val is present in mylist") - -#Output: -#val is NOT present in mylist - - - -############# Example program to demonstrate the use of 'is' operator -Firstlist = [] -Secondlist = [] -if Firstlist == Secondlist: - print("Both are equal") -else: - print("Both are not equal") -if Firstlist is Secondlist: - print("Both variables are pointing to the same object") -else: - print("Both variables are not pointing to the same object") -thirdList = Firstlist -if thirdList is Secondlist: - print("Both are pointing to the same object") -else: - print("Both are not pointing to the same object ") -''' -Output: -Both are equal -Both variables are not pointing to the same object -Both are pointing to the same object -''' - - - -####### Example program to demonstrate the use of 'is not' operator -Firstlist = [] -Secondlist = [] -if Firstlist is not Secondlist: - print("Both are pointing to the different object") -else: - print("Both are not pointing to the different object ") - -#Output: -# Both are pointing to the different object - - - -############## Logical Operators - -#### Example program to demonstrate the use of 'and' operator -a = 32 -b = 132 -if a > 0 and b > 0: - print("Both a and b are greater than zero") -else: - print("At least one variable is less than 0") - -#Output: -#Both a and b are greater than zero - - - -######### Example program to demonstrate the use of 'or' operator -a = 32 -b = -32 -if a > 0 or b > 0: - print("At least one variable is greater than zero") -else: - print("Both variables are less than 0") - -#Output: -#At least one variable is greater than zero - - -########## Example program to demonstrate the use of 'or' operator -a = 32 -if not a: - print("Boolean value of a is False") -else: - print("Boolean value of a is True") - -#Output: -#Boolean value of a is True - - - - -########## Tuple ########### - -tupleName = ("entry1" , "entry2" , "entry3") -myTuple = ("Shyam", 23 , True , "male") -print(len((4,5, 'hello'))) - -print((4,5)+(10,20)) -print((2,1)*3) -print(3 in ('hi', 'xyz',3)) -for p in (6,7,8): - print(p) - -x = ('hello', 'world', 'india') -print(x[1]) -print(x[-2]) -print(x[1:]) - - -######### Dictionaries ######### -my_dict = { - '1': 'Data', - '2': 'Structure', - '3': 'python', - '4': 'programming', - '5': 'language' -} - - -############ - -person = {} -print(type(person)) -# - -person['name'] = 'ABC' -person['lastname'] = 'XYZ' -person['age'] = 31 -person['address'] = ['Jaipur'] - -print(person) -#{'name': 'ABC', 'lastname': 'XYZ', 'age': 31, 'address': ['Jaipur']} - -print(person['name']) -#'ABC' - - -print('name' in person) -#True -print('fname' not in person) -#True -print(len(person)) -#4 - -mydict = {'a': 1, 'b': 2, 'c': 3} -print(mydict) -#{'a': 1, 'b': 2, 'c': 3} -mydict.clear() -print(mydict) -#{} - -''' -mydict.get('b') -print(mydict) -#2 -mydict.get('z') -print(mydict) -#None - -print(list(mydict.items())) -#[('a', 1), ('b', 2), ('c', 3)] - -print(list(mydict.keys())) -#['a', 'b', 'c'] - -print(list(mydict.values())) -#[1, 2, 3] - -print(mydict.pop('b')) -#2 -print(mydict) -#{'a': 1, 'c': 3} -mydict = {'a': 1,'b': 2,'c': 3} -print(mydict.popitem()) -#('c', 3) -print(mydict) -#{'a': 1, 'b': 2} -d1 = {'a': 10, 'b': 20, 'c': 30} -d2 = {'b': 200, 'd': 400} - -print(d1.update(d2)) -print(d1) -#{'a': 10, 'b': 200, 'c': 30, 'd': 400} -''' - - -############## SETS ############# - -x1 = set(['and', 'python', 'data', 'structure']) -print(x1) -#{'and', 'python', 'data', 'structure'} -print(type(x1)) -# - -x2 = {'and', 'python', 'data', 'structure'} -print(x2) -#{'and', 'python', 'data', 'structure'} -x = {'data', 'structure', 'and', 'python'} -print(len(x)) -#4 -print('structure' in x) -#True -x1 = {'data', 'structure'} -x2 = {'python', 'java', 'c', 'data'} - -######### Union of two sets, x1 and x2. -x3 = x1 | x2 -print(x3) -{'java', 'structure', 'c', 'python', 'data'} - -print(x1.union(x2)) -{'java', 'structure', 'c', 'python', 'data'} - - -########## Intersection of sets -print(x1.intersection(x2)) -#{'data'} -print(x1 & x2) -#{'data'} - - -########## Difference of sets - -print(x1.difference(x2)) -#{'structure'} -print(x1 - x2) -#{'structure'} - - -######### Symmetric difference ########## -print(x1.symmetric_difference(x2)) -#{'structure', 'python', 'c', 'java'} - -print(x1 ^ x2) -#{'structure', 'python', 'c', 'java'} - -####### subset ###### - -print(x1.issubset(x2)) -#False -print(x1 <= x2) -#False - -########## Immutable Sets ######### - -x = frozenset(['data', 'structure', 'and', 'python']) -print(x) -#frozenset({'and', 'python', 'data', 'structure'}) -##### Error in the below code #### -''' -a11 = set(['data']) -a21 = set(['structure']) -a31 = set(['python']) -x1 = {a11, a21, a31} -''' - -a1 = frozenset(['data']) -a2 = frozenset(['structure']) -a3 = frozenset(['python']) -x = {a1, a2, a3} -print(x) - - - -######## Named Tuples ######## - -from collections import namedtuple -Book = namedtuple ('Book', ['name', 'ISBN', 'quantity']) -Book1 = Book('Hands on Data Structures', '9781788995573', '50') -# Accessing data items -print('Using index ISBN:' + Book1[1]) -#Using index ISBN: 9781788995573 -print('Using key ISBN:' + Book1.ISBN) -#Using key ISBN: 9781788995573 - - -######## Deque ############ - -from collections import deque -s = deque() # Creates an empty deque -my_queue = deque([1, 2, 'Name']) -print(my_queue) -#deque([1, 2, 'Name']) -my_queue.append('age') -print(my_queue) -my_queue.appendleft('age') -print(my_queue) -my_queue.pop() -print(my_queue) -my_queue.popleft() -print(my_queue) - - -########## Ordered Dictionaries ######## - -from collections import OrderedDict -od = OrderedDict({'my': 2, 'name ': 4, 'is': 2, 'Mohan' :5}) -od['hello'] = 4 -print(od) -#([('my', 2), ('name', 4), ('is', 2), ('Mohan', 5), ('hello', 4)]) - - -############ Default Dictionary ######## - -from collections import defaultdict -dd = defaultdict(int) -words = str.split('data python data data structure data python') -for word in words: - dd[word] +=1 - -print(dd) -#defaultdict(, {'data': 4, 'python': 2, 'structure': 1}) - - - - -############ ChainMap Object ############## - -from collections import ChainMap -dict1 = {"data": 1, "structure": 2} -dict2 = {"python": 3, "language": 4} -chain = ChainMap(dict1, dict2) - -print(chain) -#ChainMap({'data': 1, 'structure': 2}, {'python': 3, 'language': 4}) -print (list(chain.keys())) -#['python', 'language', 'data', 'structure'] -print (list(chain.values())) -#[3, 4, 1, 2] -print(chain["data"]) -#1 -print(chain["language"]) -#4 - - -################ Counter Objects ########### - -from collections import Counter -inventory = Counter('hello') -print(inventory) -Counter({'l': 2, 'h': 1, 'e': 1, 'o': 1}) - - - -############### UserDict ############# -''' -from collections import UserDict -class MyDict(UserDict): - def push(self, key, value): - raise RuntimeError("Cannot insert") - -d = MyDict({'ab':1, 'bc': 2, 'cd': 3}) -d.push('b', 2) - -Traceback (most recent call last): - File "", line 12, in -File "", line 6, in push -RuntimeError: Cannot insert -''' - -######### UserList ########### -''' -from collections import UserList -class MyList(UserList): - def push(self, key): - raise RuntimeError("Cannot insert in the list") - -d = MyList([11, 12, 13]) -d.push(2) - -Traceback (most recent call last): - Traceback (most recent call last): - File "", line 1, in - File "", line 3, in push -RuntimeError: Cannot insert in the list -''' - -######### UserString ########## - -# create a custom append function for string -from collections import UserString -class MyString(UserString): - def append(self, value): - self.data += value - -s1 = MyString("data") -print("Original:", s1) -#Original: data - -s1.append('h') -print("After append: ", s1) -#After append: datah - - - diff --git a/Chapter02/binary_search.py b/Chapter02/binary_search.py deleted file mode 100644 index 4ca8711..0000000 --- a/Chapter02/binary_search.py +++ /dev/null @@ -1,16 +0,0 @@ -def binary_search(arr, low, high, key): - while low <= high: - mid = int(low + (high - low)/2) - if arr[mid] == key: - return mid - elif arr[mid] < key: - low = mid + 1 - else: - high = mid - 1 - return -1 - - -arr = [ 2, 3, 4, 2, 10, 40] -x = 10 -result = binary_search(arr, 0, len(arr)-1, x) -print(result) diff --git a/Chapter02/linear_search.py b/Chapter02/linear_search.py deleted file mode 100644 index 5f6dda7..0000000 --- a/Chapter02/linear_search.py +++ /dev/null @@ -1,12 +0,0 @@ -# Linear search program to search an element, return the index position of the #array - -def searching(search_arr, x): - for i in range(len(search_arr)): - if search_arr[i] == x: - return i - return -1 - - -search_arr = [3, 4, 1, 6, 14] -x=4 -print("Index position for the element x is:", searching(search_arr, x)) diff --git a/Chapter02/matrix_chain.py b/Chapter02/matrix_chain.py deleted file mode 100644 index 2d30a87..0000000 --- a/Chapter02/matrix_chain.py +++ /dev/null @@ -1,14 +0,0 @@ -import sys - -def matrix_chain(mat, i, j): - if i == j: - return 0 - minimum_computations = sys.maxsize - for k in range(i, j): - count = (MatrixChain(mat, i, k) + MatrixChain(mat, k+1, j)+ mat[i-1] * mat[k] * mat[j]) - if count < minimum_computations: - minimum_computations = count - return minimum_computations - -matrix_sizes = [20, 30, 45, 50] -print("Minimum multiplications are", MatrixChain(matrix_sizes , 1, len(matrix_sizes)-1)) diff --git a/Chapter02/merge_sort.py b/Chapter02/merge_sort.py deleted file mode 100644 index d724aca..0000000 --- a/Chapter02/merge_sort.py +++ /dev/null @@ -1,37 +0,0 @@ -def merge_sort(unsorted_list): - if len(unsorted_list) == 1: - return unsorted_list - mid_point = int(len(unsorted_list)/2) - first_half = unsorted_list[:mid_point] - second_half = unsorted_list[mid_point:] - - half_a = merge_sort(first_half) - half_b = merge_sort(second_half) - - return merge(half_a, half_b) - - -def merge(first_sublist, second_sublist): - i = j = 0 - merged_list = [] - while i < len(first_sublist) and j < len(second_sublist): - if first_sublist[i] < second_sublist[j]: - merged_list.append(first_sublist[i]) - i += 1 - else: - merged_list.append(second_sublist[j]) - j += 1 - - while i < len(first_sublist): - merged_list.append(first_sublist[i]) - i += 1 - - while j < len(second_sublist): - merged_list.append(second_sublist[j]) - j += 1 - return merged_list - - -a= [11, 12, 7, 41, 61, 13, 16, 14] -print(merge_sort(a)) - diff --git a/Chapter03/Fibonacci_series.py b/Chapter03/Fibonacci_series.py deleted file mode 100644 index 99590f2..0000000 --- a/Chapter03/Fibonacci_series.py +++ /dev/null @@ -1,8 +0,0 @@ -def fib(n): - if n <= 1: - return 1 - else: - return fib(n-1) + fib(n-2) - -for i in range(5): - print(fib(i)) diff --git a/Chapter03/MatrixChain_multiplication.py b/Chapter03/MatrixChain_multiplication.py deleted file mode 100644 index 3c14e70..0000000 --- a/Chapter03/MatrixChain_multiplication.py +++ /dev/null @@ -1,14 +0,0 @@ -import sys -def MatrixChain(mat, i, j): - if i == j: - return 0 - minimum_computations = sys.maxsize - for k in range(i, j): - count = (MatrixChain(mat, i, k) + MatrixChain(mat, k+1, j)+ mat[i-1] * mat[k] * mat[j]) - if count < minimum_computations: - minimum_computations = count - return minimum_computations - - -matrix_sizes = [20, 30, 45, 50] -print("Minimum multiplications are", MatrixChain(matrix_sizes , 1, len(matrix_sizes)-1)) diff --git a/Chapter03/binary_search.py b/Chapter03/binary_search.py deleted file mode 100644 index dac62d4..0000000 --- a/Chapter03/binary_search.py +++ /dev/null @@ -1,16 +0,0 @@ -def binary_search(arr, low, high, key): - while low <= high: - mid = int(low + (high - low)/2) - if arr[mid] == key: - return mid - elif arr[mid] < key: - low = mid + 1 - else: - high = mid - 1 - return -1 - - -arr = [ 2, 3, 4, 2, 10, 40] -x = 10 -result = binary_search(arr, 0, len(arr)-1, x) -print(result) diff --git a/Chapter03/dijkstra.py b/Chapter03/dijkstra.py deleted file mode 100644 index 29cab7a..0000000 --- a/Chapter03/dijkstra.py +++ /dev/null @@ -1,80 +0,0 @@ - -def get_shortest_distance(table, vertex): - shortest_distance = table[vertex][DISTANCE] - return shortest_distance - -def set_shortest_distance(table, vertex, new_distance): - table[vertex][DISTANCE] = new_distance - -def set_previous_node(table, vertex, previous_node): - table[vertex][PREVIOUS_NODE] = previous_node - -def get_distance(graph, first_vertex, second_vertex): - return graph[first_vertex][second_vertex] - -def get_next_node(table, visited_nodes): - unvisited_nodes = list(set(table.keys()).difference(set(visited_nodes))) - assumed_min = table[unvisited_nodes[0]][DISTANCE] - min_vertex = unvisited_nodes[0] - for node in unvisited_nodes: - if table[node][DISTANCE] < assumed_min: - assumed_min = table[node][DISTANCE] - min_vertex = node - return min_vertex - -def find_shortest_path(graph, table, origin): - visited_nodes = [] - current_node = origin - starting_node = origin - while True: - adjacent_nodes = graph[current_node] - if set(adjacent_nodes).issubset(set(visited_nodes)): - # Nothing here to do. All adjacent nodes have been visited. - pass - else: - unvisited_nodes = set(adjacent_nodes).difference(set(visited_nodes)) - for vertex in unvisited_nodes: - distance_from_starting_node = get_shortest_distance(table, vertex) - if distance_from_starting_node == INFINITY and current_node == starting_node: - total_distance = get_distance(graph, vertex, current_node) - else: - total_distance = get_shortest_distance (table, - current_node) + get_distance(graph, current_node, vertex) - if total_distance < distance_from_starting_node: - set_shortest_distance(table, vertex, total_distance) - set_previous_node(table, vertex, current_node) - visited_nodes.append(current_node) - #print(visited_nodes) - if len(visited_nodes) == len(table.keys()): - break - current_node = get_next_node(table,visited_nodes) - return(table) - -graph = dict() -graph['A'] = {'B': 5, 'D': 9, 'E': 2} -graph['B'] = {'A': 5, 'C': 2} -graph['C'] = {'B': 2, 'D': 3} -graph['D'] = {'A': 9, 'F': 2, 'C': 3} -graph['E'] = {'A': 2, 'F': 3} -graph['F'] = {'E': 3, 'D': 2} - -table = dict() -table = { - 'A': [0, None], - 'B': [float("inf"), None], - 'C': [float("inf"), None], - 'D': [float("inf"), None], - 'E': [float("inf"), None], - 'F': [float("inf"), None], -} - - -DISTANCE = 0 -PREVIOUS_NODE = 1 -INFINITY = float('inf') - -shortest_distance_table = find_shortest_path(graph, table, 'A') - - -for k in sorted(shortest_distance_table): - print("{} - {}".format(k,shortest_distance_table[k])) diff --git a/Chapter03/dyna_fib.py b/Chapter03/dyna_fib.py deleted file mode 100644 index 5ba97f6..0000000 --- a/Chapter03/dyna_fib.py +++ /dev/null @@ -1,13 +0,0 @@ -def dyna_fib(n, lookup): - if n == 0: - return 0 - if n <= 2: - lookup[n] = 1 - if lookup[n] is None: - lookup[n] = dyna_fib(n-1, lookup) + dyna_fib(n-2, lookup) - return lookup[n] - -lookup = [None]*(1000) - -for i in range(6): - print(dyna_fib(i, lookup)) diff --git a/Chapter03/factorial.py b/Chapter03/factorial.py deleted file mode 100644 index 3469d23..0000000 --- a/Chapter03/factorial.py +++ /dev/null @@ -1,10 +0,0 @@ -def factorial(n): - # test for a base case - if n == 0: - return 1 - else: - return n*factorial(n-1) # make a calculation and a recursive call - - - -print(factorial(4)) diff --git a/Chapter03/merge_sort.py b/Chapter03/merge_sort.py deleted file mode 100644 index e546be9..0000000 --- a/Chapter03/merge_sort.py +++ /dev/null @@ -1,35 +0,0 @@ -def merge_sort(unsorted_list): - if len(unsorted_list) == 1: - return unsorted_list - mid_point = int(len(unsorted_list)/2) - first_half = unsorted_list[:mid_point] - second_half = unsorted_list[mid_point:] - - half_a = merge_sort(first_half) - half_b = merge_sort(second_half) - - return merge(half_a, half_b) - - - -def merge(first_sublist, second_sublist): - i = j = 0 - merged_list = [] - while i < len(first_sublist) and j < len(second_sublist): - if first_sublist[i] < second_sublist[j]: - merged_list.append(first_sublist[i]) - i += 1 - else: - merged_list.append(second_sublist[j]) - j += 1 - while i < len(first_sublist): - merged_list.append(first_sublist[i]) - i += 1 - while j < len(second_sublist): - merged_list.append(second_sublist[j]) - j += 1 - return merged_list - - -a= [11, 12, 7, 41, 61, 13, 16, 14] -print(merge_sort(a)) diff --git a/Chapter04/CircularList.py b/Chapter04/CircularList.py deleted file mode 100644 index 7ddd583..0000000 --- a/Chapter04/CircularList.py +++ /dev/null @@ -1,99 +0,0 @@ -class Node: - """ A Circular linked node. """ - def __init__(self, data=None): - self.data = data - self.next = None - - - -class CircularList: - def __init__ (self): - self.tail = None - self.head = None - self.size = 0 - - def append(self, data): - node = Node(data) - if self.head: - self.head.next = node - self.head = node - else: - self.head = node - self.tail = node - self.head.next = self.tail - self.size += 1 - - def delete(self, data): - current = self.tail - prev = self.tail - while prev == current or prev != self.head: - if current.data == data: - if current == self.tail: - self.tail = current.next - self.head.next = self.tail - else: - prev.next = current.next - self.size -= 1 - return - prev = current - current = current.next - - - def iter(self): - current = self.tail - while current: - val = current.data - current = current.next - yield val - - - -words = CircularList() -words.append('eggs') -words.append('ham') -words.append('spam') - - -counter = 0 -for word in words.iter(): - print(word) - counter += 1 - if counter > 10: - break - -words.append('foo') -words.append('bar') -words.append('bim') -words.append('baz') -words.append('quux') -words.append('duux') - - - -print("Done iterating. Now we try to delete something that isn't there.") -words.delete('socks') -print('back to iterating') -counter = 0 -for item in words.iter(): - print(item) - counter += 1 - if counter > 2: - break - -print('Let us delete something that is there.') -words.delete('foo') -print('back to iterating') -counter = 0 -for item in words.iter(): - print(item) - counter += 1 - if counter > 2: - break - - - - - - - - diff --git a/Chapter04/SinglyLinkedList.py b/Chapter04/SinglyLinkedList.py deleted file mode 100644 index 6859a8c..0000000 --- a/Chapter04/SinglyLinkedList.py +++ /dev/null @@ -1,33 +0,0 @@ -class Node: - """ A singly-linked node. """ - def __init__(self, data=None): - self.data = data - self.next = None - - -class SinglyLinkedList: - def __init__ (self): - self.tail = None - - def append(self, data): - # Encapsulate the data in a Node - node = Node(data) - if self.tail == None: - self.tail = node - else: - current = self.tail - while current.next: - current = current.next - current.next = node - - - -words = SinglyLinkedList() -words.append('egg') -words.append('ham') -words.append('spam') - -current = words.tail -while current: - print(current.data) - current = current.next diff --git a/Chapter04/append_at_any_location_singly_linkedlist.py b/Chapter04/append_at_any_location_singly_linkedlist.py deleted file mode 100644 index e385d76..0000000 --- a/Chapter04/append_at_any_location_singly_linkedlist.py +++ /dev/null @@ -1,64 +0,0 @@ -class Node: - """ A singly-linked node. """ - def __init__(self, data=None): - self.data = data - self.next = None - - -class SinglyLinkedList: - def __init__ (self): - self.tail = None - - def append(self, data): - # Encapsulate the data in a Node - node = Node(data) - if self.tail == None: - self.tail = node - else: - current = self.tail - while current.next: - current = current.next - current.next = node - - def append_at_a_location(self, data, index): - current = self.tail - prev = self.tail - node = Node(data) - count = 1 - while current: - if count == index: - node.next = current - prev.next = node - print(count) - return - elif index == 1: - node.next = current - self.tail = node - return - count += 1 - prev = current - current = current.next - - - -words = SinglyLinkedList() -words.append('egg') -words.append('ham') -words.append('spam') - -current = words.tail -while current: - print(current.data) - current = current.next - - - -words.append_at_a_location('new', 2) - -current = words.tail -while current: - print(current.data) - current = current.next - - - diff --git a/Chapter04/delete_operation_doubly_linkedlist.py b/Chapter04/delete_operation_doubly_linkedlist.py deleted file mode 100644 index 2b129e9..0000000 --- a/Chapter04/delete_operation_doubly_linkedlist.py +++ /dev/null @@ -1,75 +0,0 @@ -class Node(object): - def __init__ (self, data = None, next = None, prev = None): - self.data = data - self.next = next - self.prev = prev - -class DoublyLinkedList(object): - def __init__ (self): - self.head = None - self.tail = None - self.count = 0 - - def append(self, data): - #Append an item to the list. - new_node = Node(data, None, None) - if self.head is None: - self.head = new_node - self.tail = self.head - else: - new_node.prev = self.tail - self.tail.next = new_node - self.tail = new_node - self.count += 1 - - - - def delete(self, data): - # Delete a node from the list. - current = self.head - node_deleted = False - if current is None: #Item to be deleted is not found in the list - node_deleted = False - elif current.data == data: #Item to be deleted is found at starting of list - self.head = current.next - self.head.prev = None - node_deleted = True - elif self.tail.data == data: #Item to be deleted is found at the end of list. - self.tail = self.tail.prev - self.tail.next = None - node_deleted = True - else: - while current: #search item to be deleted, and delete that node - if current.data == data: - current.prev.next = current.next - current.next.prev = current.prev - node_deleted = True - current = current.next - if node_deleted: - self.count -= 1 - - - -#Code to create for a doubly linked list -words = DoublyLinkedList() -words.append('egg') -words.append('ham') -words.append('spam') -current = words.head -while current: - print(current.data) - current = current.next - - -words.delete('ham') -current = words.head -while current: - print(current.data) - current = current.next - - -words.delete('spam') -current = words.head -while current: - print(current.data) - current = current.next diff --git a/Chapter04/delete_operation_singly_linkedlist.py b/Chapter04/delete_operation_singly_linkedlist.py deleted file mode 100644 index b7a344c..0000000 --- a/Chapter04/delete_operation_singly_linkedlist.py +++ /dev/null @@ -1,74 +0,0 @@ -class Node: - """ A singly-linked node. """ - def __init__(self, data=None): - self.data = data - self.next = None - -class SinglyLinkedList: - def __init__ (self): - self.tail = None - - def append(self, data): - # Encapsulate the data in a Node - node = Node(data) - if self.tail == None: - self.tail = node - else: - current = self.tail - while current.next: - current = current.next - current.next = node - - def delete_First_node (self): - current = self.tail - if current == self.tail: - self.tail = current.next - - def delete_last_node (self): - current = self.tail - prev = self.tail - while current: - if current.next == None: - prev.next = current.next - self.size -= 1 - prev = current - current = current.next - - - def delete(self, data): - current = self.tail - prev = self.tail - while current: - if current.data == data: - if current == self.tail: - self.tail = current.next - else: - prev.next = current.next - self.size -= 1 - return - prev = current - current = current.next - - -words = SinglyLinkedList() -words.append('egg') -words.append('ham') -words.append('spam') - - -words.delete_last_node() - -current = words.tail -while current: - print(current.data) - current = current.next - - - -words.delete('ham') -current = words.tail -while current: - print(current.data) - current = current.next - - diff --git a/Chapter04/doubly_linked_list.py b/Chapter04/doubly_linked_list.py deleted file mode 100644 index 63c9762..0000000 --- a/Chapter04/doubly_linked_list.py +++ /dev/null @@ -1,69 +0,0 @@ -class Node(object): - def __init__ (self, data = None, next = None, prev = None): - self.data = data - self.next = next - self.prev = prev - -class DoublyLinkedList(object): - def __init__ (self): - self.head = None - self.tail = None - self.count = 0 - - def append(self, data): - #Append an item to the list. - new_node = Node(data, None, None) - if self.head is None: - self.head = new_node - self.tail = self.head - else: - new_node.prev = self.tail - self.tail.next = new_node - self.tail = new_node - self.count += 1 - - - def append_at_start(self, data): - # Append an item at beginning to the list. - new_node = Node(data, None, None) - if self.head is None: - self.head = new_node - self.tail = self.head - else: - new_node.next = self.head - self.head.prev = new_node - self.head = new_node - self.count += 1 - - def append_at_a_location(self, data): - current = self.head - prev = self.head - new_node = Node(data, None, None) - while current: - if current.data == data: - new_node.prev = prev - new_node.next = current - prev.next = new_node - current.prev = new_node - self.count += 1 - prev = current - current = current.next - - - -words = DoublyLinkedList() -words.append('egg') -words.append('ham') -words.append('spam') - -current = words.head -while current: - print(current.data) - current = current.next - - -words.append_at_a_location('ham') -current = words.head -while current: - print(current.data) - current = current.next diff --git a/Chapter04/faster_append_singly_linked_list.py b/Chapter04/faster_append_singly_linked_list.py deleted file mode 100644 index 7910893..0000000 --- a/Chapter04/faster_append_singly_linked_list.py +++ /dev/null @@ -1,31 +0,0 @@ -class Node: - """ A singly-linked node. """ - def __init__(self, data=None): - self.data = data - self.next = None - - -class SinglyLinkedList: - def __init__ (self): - self.tail = None - self.head = None - - def append(self, data): - node = Node(data) - if self.head: - self.head.next = node - self.head = node - else: - self.tail = node - self.head = node - - -words = SinglyLinkedList() -words.append('egg') -words.append('ham') -words.append('spam') - -current = words.tail -while current: - print(current.data) - current = current.next diff --git a/Chapter04/list_traversal_singly_linklist.py b/Chapter04/list_traversal_singly_linklist.py deleted file mode 100644 index 8a25ad8..0000000 --- a/Chapter04/list_traversal_singly_linklist.py +++ /dev/null @@ -1,37 +0,0 @@ -class Node: - """ A singly-linked node. """ - def __init__(self, data=None): - self.data = data - self.next = None - - -class SinglyLinkedList: - def __init__ (self): - self.tail = None - - def append(self, data): - # Encapsulate the data in a Node - node = Node(data) - if self.tail == None: - self.tail = node - else: - current = self.tail - while current.next: - current = current.next - current.next = node - - def iter(self): - current = self.tail - while current: - val = current.data - current = current.next - yield val - - -words = SinglyLinkedList() -words.append('egg') -words.append('ham') -words.append('spam') - -for word in words.iter(): - print(word) diff --git a/Chapter05/Linked_list_based_queue.py b/Chapter05/Linked_list_based_queue.py deleted file mode 100644 index 8bda557..0000000 --- a/Chapter05/Linked_list_based_queue.py +++ /dev/null @@ -1,45 +0,0 @@ -class Node(object): - def __init__(self, data=None, next=None, prev=None): - self.data = data - self.next = next - self.prev = prev - - -class Queue: - def __init__(self): - self.head = None - self.tail = None - self.count = 0 - - def enqueue(self, data): - new_node = Node(data, None, None) - if self.head is None: - self.head = new_node - self.tail = self.head - else: - new_node.prev = self.tail - self.tail.next = new_node - self.tail = new_node - - self.count += 1 - - - def dequeue(self): - current = self.head - if self.count == 1: - self.count -= 1 - self.head = None - self.tail = None - elif self.count > 1: - self.head = self.head.next - self.head.prev = None - self.count -= 1 - - - -q= Queue() -q.enqueue(4) -q.enqueue('dog') -q.enqueue('True') - -print(q.count) diff --git a/Chapter05/List_based_queue.py b/Chapter05/List_based_queue.py deleted file mode 100644 index 4b4f8eb..0000000 --- a/Chapter05/List_based_queue.py +++ /dev/null @@ -1,37 +0,0 @@ -class Node(object): - def __init__(self, data=None, next=None, prev=None): - self.data = data - self.next = next - self.prev = prev - -class ListQueue: - def __init__(self): - self.items = [] - self.size = 0 - - def empty(self): - return self.items == [] - - def enqueue(self, data): - self.items.insert(0, data) # Always insert items at index 0 - self.size += 1 # increment the size of the queue by 1 - - def dequeue(self): - data = self.items.pop() - self.size -= 1 - return data - - def size1(self): - # print(self.size) - return self.size - - -q= ListQueue() -q.enqueue(4) -q.enqueue('dog') -q.enqueue('cat') -q.enqueue('monday') - - -a= q.size1() -print(a) diff --git a/Chapter05/Queue_application.py b/Chapter05/Queue_application.py deleted file mode 100644 index c456f1a..0000000 --- a/Chapter05/Queue_application.py +++ /dev/null @@ -1,99 +0,0 @@ -from random import randint - - - -class Node(object): - """ A Doubly-linked lists' node. """ - def __init__(self, data=None, next=None, prev=None): - self.data = data - self.next = next - self.prev = prev - - -class Queue(object): - """ A doubly-linked list. """ - def __init__(self): - self.head = None - self.tail = None - self.count = 0 - - def enqueue(self, data): - """ Append an item to the list. """ - - new_node = Node(data, None, None) - if self.head is None: - self.head = new_node - self.tail = self.head - else: - new_node.prev = self.tail - self.tail.next = new_node - self.tail = new_node - - self.count += 1 - - def dequeue(self): - """ Remove elements from the front of the list""" - current = self.head - if self.count == 1: - self.count -= 1 - self.head = None - self.tail = None - elif self.count > 1: - self.head = self.head.next - self.head.prev = None - self.count -= 1 - return current - - - -queue = Queue() - -import time -start_time = time.time() -for i in range(100000): - queue.enqueue(i) -for i in range(100000): - queue.dequeue() -print("--- %s seconds ---" % (time.time() - start_time)) - - -class Track: - - def __init__(self, title=None): - self.title = title - self.length = randint(5, 10) - - - -track1 = Track("white whistle") -track2 = Track("butter butter") -print(track1.length) -print(track2.length) - -import time -class MediaPlayerQueue(Queue): - - def __init__(self): - super(MediaPlayerQueue, self).__init__() - - def add_track(self, track): - self.enqueue(track) - - def play(self): - while self.count > 0: - current_track_node = self.dequeue() - print("Now playing {}".format(current_track_node.data.title)) - time.sleep(current_track_node.data.length) - -track1 = Track("white whistle") -track2 = Track("butter butter") -track3 = Track("Oh black star") -track4 = Track("Watch that chicken") -track5 = Track("Don't go") -media_player = MediaPlayerQueue() -media_player.add_track(track1) -media_player.add_track(track2) -media_player.add_track(track3) -media_player.add_track(track4) -media_player.add_track(track5) -media_player.play() diff --git a/Chapter05/Stack.py b/Chapter05/Stack.py deleted file mode 100644 index eeceffd..0000000 --- a/Chapter05/Stack.py +++ /dev/null @@ -1,68 +0,0 @@ -class Node: - def __init__(self, data=None): - self.data = data - self.next = None - - - -class Stack: - def __init__(self): - self.top = None - self.size = 0 - - def push(self, data): - # create a new node - node = Node(data) - if self.top: - node.next = self.top - self.top = node - else: - self.top = node - self.size += 1 - - - - def pop(self): - if self.top: - data = self.top.data - self.size -= 1 - if self.top.next: #check if there is more than one node. - self.top = self.top.next - else: - self.top = None - return data - else: - return None - - - def peek(self): - if self.top: - return self.top.data - else: - return None - - - -words = Stack() -words.push('4') -words.push('5') -words.push('6') -words.push('7') - -#print the stack elements. -current = words.top -while current: - print(current.data) - current = current.next - - -words.pop() - -current = words.top -while current: - print(current.data) - current = current.next - - -words.peek() - diff --git a/Chapter05/Stack_based_queue.py b/Chapter05/Stack_based_queue.py deleted file mode 100644 index da67178..0000000 --- a/Chapter05/Stack_based_queue.py +++ /dev/null @@ -1,27 +0,0 @@ -class Queue: - def __init__(self): - self.inbound_stack = [] - self.outbound_stack = [] - - def enqueue(self, data): - self.inbound_stack.append(data) - - - def dequeue(self): - if not self.outbound_stack: - while self.inbound_stack: - self.outbound_stack.append(self.inbound_stack.pop()) - return self.outbound_stack.pop() - - -queue = Queue() -queue.enqueue(5) -queue.enqueue(6) -queue.enqueue(7) -print(queue.inbound_stack) - -queue.dequeue() -print(queue.inbound_stack) -print(queue.outbound_stack) -queue.dequeue() -print(queue.outbound_stack) diff --git a/Chapter06/binary_search_tree.py b/Chapter06/binary_search_tree.py deleted file mode 100644 index 49d455b..0000000 --- a/Chapter06/binary_search_tree.py +++ /dev/null @@ -1,145 +0,0 @@ -class Node: - def __init__(self, data): - self.data = data - self.right_child = None - self.left_child = None - -class Tree: - def __init__(self): - self.root_node = None - - def insert(self, data): - node = Node(data) - if self.root_node is None: - self.root_node = node - else: - current = self.root_node - parent = None - while True: - parent = current - if node.data < parent.data: - current = current.left_child - if current is None: - parent.left_child = node - return - else: - current = current.right_child - if current is None: - parent.right_child = node - return - - - def get_node_with_parent(self, data): - parent = None - current = self.root_node - if current is None: - return (parent, None) - while True: - if current.data == data: - return (parent, current) - elif current.data > data: - parent = current - current = current.left_child - else: - parent = current - current = current.right_child - return (parent, current) - - - def remove(self, data): - parent, node = self.get_node_with_parent(data) - - if parent is None and node is None: - return False - - # Get children count - children_count = 0 - - if node.left_child and node.right_child: - children_count = 2 - elif (node.left_child is None) and (node.right_child is None): - children_count = 0 - else: - children_count = 1 - - if children_count == 0: - if parent: - if parent.right_child is node: - parent.right_child = None - else: - parent.left_child = None - else: - self.root_node = None - elif children_count == 1: - next_node = None - if node.left_child: - next_node = node.left_child - else: - next_node = node.right_child - - if parent: - if parent.left_child is node: - parent.left_child = next_node - else: - parent.right_child = next_node - else: - self.root_node = next_node - else: - parent_of_leftmost_node = node - leftmost_node = node.right_child - while leftmost_node.left_child: - parent_of_leftmost_node = leftmost_node - leftmost_node = leftmost_node.left_child - node.data = leftmost_node.data - - if parent_of_leftmost_node.left_child == leftmost_node: - parent_of_leftmost_node.left_child = leftmost_node.right_child - else: - parent_of_leftmost_node.right_child = leftmost_node.right_child - - - - def search(self, data): - current = self.root_node - while True: - if current is None: - return None - elif current.data is data: - return data - elif current.data > data: - current = current.left_child - else: - current = current.right_child - - - def find_min(self): - current = self.root_node - while current.left_child: - current = current.left_child - return current.data - - - def find_max(self): - current = self.root_node - while current.right_child: - current = current.right_child - return current.data - - - -tree = Tree() -tree.insert(5) -tree.insert(2) -tree.insert(7) -tree.insert(9) -tree.insert(1) - -for i in range(1, 10): - found = tree.search(i) - print("{}: {}".format(i, found)) - - -print(tree.find_min()) - -print(tree.find_max()) - diff --git a/Chapter06/level_order_traversal.py b/Chapter06/level_order_traversal.py deleted file mode 100644 index 6278b99..0000000 --- a/Chapter06/level_order_traversal.py +++ /dev/null @@ -1,35 +0,0 @@ -from collections import deque - -class Node: - def __init__(self, data): - self.data = data - self.right_child = None - self.left_child = None - - -n1 = Node("root node") -n2 = Node("left child node") -n3 = Node("right child node") -n4 = Node("left grandchild node") - -n1.left_child = n2 -n1.right_child = n3 -n2.left_child = n4 - - - -def level_order_traversal(root_node): - list_of_nodes = [] - traversal_queue = deque([root_node]) - while len(traversal_queue) > 0: - node = traversal_queue.popleft() - list_of_nodes.append(node.data) - if node.left_child: - traversal_queue.append(node.left_child) - if node.right_child: - traversal_queue.append(node.right_child) - return list_of_nodes - - - -print(breadth_first_traversal(n1)) diff --git a/Chapter06/reverse_polish_expression.py b/Chapter06/reverse_polish_expression.py deleted file mode 100644 index e01080d..0000000 --- a/Chapter06/reverse_polish_expression.py +++ /dev/null @@ -1,46 +0,0 @@ - -class Stack: - def __init__(self): - self.elements = [] - - def push(self, item): - self.elements.append(item) - - def pop(self): - return self.elements.pop() - - -class TreeNode: - def __init__(self, data=None): - self.data = data - self.right = None - self.left = None - -def calc(node): - if node.data == "+": - return calc(node.left) + calc(node.right) - elif node.data == "-": - return calc(node.left) - calc(node.right) - elif node.data == "*": - return calc(node.left) * calc(node.right) - elif node.data == "/": - return calc(node.left) / calc(node.right) - else: - return node.data - -expr = "4 5 + 5 3 - *".split() - -stack = Stack() - -for term in expr: - if term in "+-*/": - node = TreeNode(term) - node.right = stack.pop() - node.left = stack.pop() - else: - node = TreeNode(int(term)) - stack.push(node) - -root = stack.pop() -result = calc(root) -print(result) diff --git a/Chapter06/tree_traversal.py b/Chapter06/tree_traversal.py deleted file mode 100644 index cf3d41d..0000000 --- a/Chapter06/tree_traversal.py +++ /dev/null @@ -1,53 +0,0 @@ -class Node: - def __init__(self, data): - self.data = data - self.right_child = None - self.left_child = None - - -n1 = Node("root node") -n2 = Node("left child node") -n3 = Node("right child node") -n4 = Node("left grandchild node") -n1.left_child = n2 -n1.right_child = n3 -n2.left_child = n4 - -current = n1 -while current: - print(current.data) - current = current.left_child - -print("\n" ) - -def inorder(root_node): - current = root_node - if current is None: - return - inorder(current.left_child) - print(current.data) - inorder(current.right_child) - -def preorder(root_node): - current = root_node - if current is None: - return - print(current.data) - preorder(current.left_child) - preorder(current.right_child) - - -def postorder(root_node): - current = root_node - if current is None: - return - postorder(current.left_child) - postorder(current.right_child) - print(current.data) - - -inorder( n1) -print("\n" ) -preorder( n1) -print("\n" ) -postorder(n1) diff --git a/Chapter07/heap.py b/Chapter07/heap.py deleted file mode 100644 index e3149f0..0000000 --- a/Chapter07/heap.py +++ /dev/null @@ -1,50 +0,0 @@ -class Heap: - def __init__(self): - self.heap = [0] - self.size = 0 - - def arrange(self, k): - while k // 2 > 0: - if self.heap[k] < self.heap[k//2]: - self.heap[k], self.heap[k//2] = self.heap[k//2], self.heap[k] - k //= 2 - - def insert(self, item): - self.heap.append(item) - self.size += 1 - self.arrange(self.size) - - def sink(self, k): - while k * 2 <= self.size: - mc = self.minchild(k) - if self.heap[k] > self.heap[mc]: - self.heap[k], self.heap[mc] = self.heap[mc], self.heap[k] - k = mc - - def minchild(self, k): - if k * 2 + 1 > self.size: - return k * 2 - elif self.heap[k*2] < self.heap[k*2+1]: - return k * 2 - else: - return k * 2 + 1 - - def pop(self): - item = self.heap[1] - self.heap[1] = self.heap[self.size] - self.size -= 1 - self.heap.pop() - self.sink(1) - return item - - -h = Heap() -for i in ( 4, 8, 7, 2, 9, 10, 5, 1, 3, 6): - h.insert(i) - -print(h.heap) - -for i in range(10): - n = h.pop() - print(n) - print(h.heap) diff --git a/Chapter07/heap_sort.py b/Chapter07/heap_sort.py deleted file mode 100644 index f673e01..0000000 --- a/Chapter07/heap_sort.py +++ /dev/null @@ -1,66 +0,0 @@ -class Heap: - def __init__(self): - self.heap = [0] - self.size = 0 - - def arrange(self, k): - while k // 2 > 0: - if self.heap[k] < self.heap[k//2]: - self.heap[k], self.heap[k//2] = self.heap[k//2], self.heap[k] - k //= 2 - - def insert(self, item): - self.heap.append(item) - self.size += 1 - self.arrange(self.size) - - def sink(self, k): - while k * 2 <= self.size: - mc = self.minchild(k) - if self.heap[k] > self.heap[mc]: - self.heap[k], self.heap[mc] = self.heap[mc], self.heap[k] - k = mc - - def minchild(self, k): - if k * 2 + 1 > self.size: - return k * 2 - elif self.heap[k*2] < self.heap[k*2+1]: - return k * 2 - else: - return k * 2 + 1 - - def pop(self): - item = self.heap[1] - self.heap[1] = self.heap[self.size] - self.size -= 1 - self.heap.pop() - self.sink(1) - return item - - def heap_sort(self): - sorted_list = [] - for node in range(self.size): - n = self.pop() - sorted_list.append(n) - return sorted_list - - - -h = Heap() -for i in ( 4, 8, 7, 2, 9, 10, 5, 1, 3, 6): - h.insert(i) - -print(h.heap) - - -h = Heap() -unsorted_list = [4, 8, 7, 2, 9, 10, 5, 1, 3, 6] - - -for i in unsorted_list: - h.insert(i) - -print("Unsorted list: {}".format(unsorted_list)) - - -h.heap_sort() diff --git a/Chapter08/hashing.py b/Chapter08/hashing.py deleted file mode 100644 index 3b49cf3..0000000 --- a/Chapter08/hashing.py +++ /dev/null @@ -1,10 +0,0 @@ -def hash(data): - counter = 1 - sum = 0 - for d in data: - sum += counter * ord(d) - return sum % 256 - -items = ['foo', 'bar', 'bim', 'baz', 'quux', 'duux', 'gnn'] -for item in items: - print("{}: {}".format(item, hash(item))) diff --git a/Chapter08/hashtable.py b/Chapter08/hashtable.py deleted file mode 100644 index 9254f14..0000000 --- a/Chapter08/hashtable.py +++ /dev/null @@ -1,74 +0,0 @@ -class HashItem: - def __init__(self, key, value): - self.key = key - self.value = value - - -class HashTable: - def __init__(self): - self.size = 256 - self.slots = [None for i in range(self.size)] - self.count = 0 - - def _hash(self, key): - mult = 1 - hv = 0 - for ch in key: - hv += mult * ord(ch) - mult += 1 - return hv % self.size - - def put(self, key, value): - item = HashItem(key, value) - h = self._hash(key) - - while self.slots[h] != None: - if self.slots[h].key == key: - break - h = (h + 1) % self.size - if self.slots[h] == None: - self.count += 1 - self.slots[h] = item - - def get(self, key): - h = self._hash(key) - while self.slots[h] != None: - if self.slots[h].key == key: - return self.slots[h].value - h = (h+ 1) % self.size - return None - - def __setitem__(self, key, value): - self.put(key, value) - - def __getitem__(self, key): - return self.get(key) - - -ht = HashTable() -ht.put("good", "eggs") -ht.put("better", "ham") -ht.put("best", "spam") -ht.put("ad", "do not") -ht.put("ga", "collide") - -for key in ("good", "better", "best", "worst", "ad", "ga"): - v = ht.get(key) - print(v) - - - - -ht = HashTable() -ht["good"] = "eggs" -ht["better"] = "ham" -ht["best"] = "spam" -ht["ad"] = "do not" -ht["ga"] = "collide" -ht["data"] = "value" - -for key in ("good", "better", "best", "worst", "ad", "ga"): - v = ht[key] - print(v) - -print("The number of elements is: {}".format(ht.count)) diff --git a/Chapter09/breadth_first_search.py b/Chapter09/breadth_first_search.py deleted file mode 100644 index 28165c9..0000000 --- a/Chapter09/breadth_first_search.py +++ /dev/null @@ -1,33 +0,0 @@ -graph = dict() -graph['A'] = ['B', 'G', 'D'] -graph['B'] = ['A', 'F', 'E'] -graph['C'] = ['F', 'H'] -graph['D'] = ['F', 'A'] -graph['E'] = ['B', 'G'] -graph['F'] = ['B', 'D', 'C'] -graph['G'] = ['A', 'E'] -graph['H'] = ['C'] - - -from collections import deque - -def breadth_first_search(graph, root): - visited_vertices = list() - graph_queue = deque([root]) - visited_vertices.append(root) - node = root - - while len(graph_queue) > 0: - node = graph_queue.popleft() - adj_nodes = graph[node] - - remaining_elements = set(adj_nodes).difference(set(visited_vertices)) - if len(remaining_elements) > 0: - for elem in sorted(remaining_elements): - visited_vertices.append(elem) - graph_queue.append(elem) - - return visited_vertices - - -print(breadth_first_search(graph, 'A')) diff --git a/Chapter09/depth_first_search.py b/Chapter09/depth_first_search.py deleted file mode 100644 index 36232b4..0000000 --- a/Chapter09/depth_first_search.py +++ /dev/null @@ -1,36 +0,0 @@ -graph = dict() -graph['A'] = ['B', 'S'] -graph['B'] = ['A'] -graph['S'] = ['A','G','C'] -graph['D'] = ['C'] -graph['G'] = ['S','F','H'] -graph['H'] = ['G','E'] -graph['E'] = ['C','H'] -graph['F'] = ['C','G'] -graph['C'] = ['D','S','E','F'] - -def depth_first_search(graph, root): - visited_vertices = list() - graph_stack = list() - graph_stack.append(root) - node = root - while len(graph_stack) > 0: - if node not in visited_vertices: - visited_vertices.append(node) - adj_nodes = graph[node] - if set(adj_nodes).issubset(set(visited_vertices)): - graph_stack.pop() - if len(graph_stack) > 0: - node = graph_stack[-1] - continue - else: - remaining_elements = set(adj_nodes).difference(set(visited_vertices)) - - first_adj_node = sorted(remaining_elements)[0] - graph_stack.append(first_adj_node) - node = first_adj_node - return visited_vertices - - - -print(depth_first_search(graph, 'A')) diff --git a/Chapter09/graph.py b/Chapter09/graph.py deleted file mode 100644 index 58cc88b..0000000 --- a/Chapter09/graph.py +++ /dev/null @@ -1,31 +0,0 @@ -graph = dict() -graph['A'] = ['B', 'C'] -graph['B'] = ['E','C', 'A'] -graph['C'] = ['A', 'B', 'E','F'] -graph['E'] = ['B', 'C'] -graph['F'] = ['C'] - -matrix_elements = sorted(graph.keys()) -cols = rows = len(matrix_elements) - -adjacency_matrix = [[0 for x in range(rows)] for y in range(cols)] - -edges_list = [] - - -for key in matrix_elements: - for neighbor in graph[key]: - edges_list.append((key,neighbor)) - - -print(edges_list) - - - -for edge in edges_list: - index_of_first_vertex = matrix_elements.index(edge[0]) - index_of_second_vertex = matrix_elements.index(edge[1]) - adjacency_matrix[index_of_first_vertex][index_of_second_vertex] = 1 - - -print(adjacency_matrix) diff --git a/Chapter10/Unordered_linear_search.py b/Chapter10/Unordered_linear_search.py deleted file mode 100644 index 66a037a..0000000 --- a/Chapter10/Unordered_linear_search.py +++ /dev/null @@ -1,27 +0,0 @@ - -def search(unordered_list, term): - unordered_list_size = len(unordered_list) - for i in range(unordered_list_size): - if term == unordered_list[i]: - return i - return None - - - -scores = [60, 1, 88, 10, 11, 600] - -search_term = 65 -position = search(scores, search_term) - -if position is None: - print("{} not found".format(search_term)) -else: - print("{} found at position {}".format(search_term, position)) - - -search_term = 600 -position = search(scores, search_term) -if position is None: - print("{} not found".format(search_term)) -else: - print("{} found at position {}".format(search_term, position)) diff --git a/Chapter10/binary_search_iterative.py b/Chapter10/binary_search_iterative.py deleted file mode 100644 index c8cc4cd..0000000 --- a/Chapter10/binary_search_iterative.py +++ /dev/null @@ -1,23 +0,0 @@ -def binary_search_iterative(ordered_list, term): - size_of_list = len(ordered_list) - 1 - index_of_first_element = 0 - index_of_last_element = size_of_list - while index_of_first_element <= index_of_last_element: - mid_point = (index_of_first_element + index_of_last_element)//2 - if ordered_list[mid_point] == term: - return mid_point - if term > ordered_list[mid_point]: - index_of_first_element = mid_point + 1 - else: - index_of_last_element = mid_point - 1 - - - -store = [1, 4, 5, 12, 43, 54, 60, 77] -a = binary_search_iterative(store, 2) -print("Index position of value 2 is", a) - - -print(binary_search_iterative(store, 7)) - -print(binary_search_iterative(store, 60)) diff --git a/Chapter10/binary_search_recursive b/Chapter10/binary_search_recursive deleted file mode 100644 index 914b1d4..0000000 --- a/Chapter10/binary_search_recursive +++ /dev/null @@ -1,17 +0,0 @@ -def binary_search_recursive(ordered_list, first_element_index, last_element_index, term): - if (last_element_index < first_element_index): - return None - else: - mid_point = first_element_index + ((last_element_index - first_element_index) // 2) - - if ordered_list[mid_point] > term: - return binary_search(ordered_list, first_element_index, mid_point-1,term) - elif ordered_list[mid_point] < term: - return binary_search(ordered_list, mid_point+1, last_element_index, term) - else: - return mid_point - - -store = [2, 4, 5, 12, 43, 54, 60, 77] -print(binary_search_recursive(store, 0, 7, 12)) - diff --git a/Chapter10/interpolation_search.py b/Chapter10/interpolation_search.py deleted file mode 100644 index 6301267..0000000 --- a/Chapter10/interpolation_search.py +++ /dev/null @@ -1,26 +0,0 @@ - -def nearest_mid(input_list, lower_bound_index, upper_bound_index, search_value): - return lower_bound_index + (( upper_bound_index - lower_bound_index)// - (input_list[upper_bound_index] - input_list[lower_bound_index])) * (search_value - input_list[lower_bound_index]) - - -def interpolation_search(ordered_list, term): - size_of_list = len(ordered_list) - 1 - index_of_first_element = 0 - index_of_last_element = size_of_list - while index_of_first_element <= index_of_last_element: - mid_point = nearest_mid(ordered_list, index_of_first_element, index_of_last_element, term) - if mid_point > index_of_last_element or mid_point < index_of_first_element: - return None - if ordered_list[mid_point] == term: - return mid_point - if term > ordered_list[mid_point]: - index_of_first_element = mid_point + 1 - else: - index_of_last_element = mid_point - 1 - - - -store = [2, 4, 5, 12, 43, 54, 60, 77] -a = interpolation_search(store, 2) -print("Index position of value 2 is ",a) diff --git a/Chapter10/search_ordered_list.py b/Chapter10/search_ordered_list.py deleted file mode 100644 index f819076..0000000 --- a/Chapter10/search_ordered_list.py +++ /dev/null @@ -1,30 +0,0 @@ - -def search_ordered(ordered_list, term): - ordered_list_size = len(ordered_list) - for i in range(ordered_list_size): - if term == ordered_list[i]: - return i - elif ordered_list[i] > term: - return None - - return None - - - -scores = [2, 3, 4, 6, 7] - -search_term = 5 -position = search_ordered(scores, search_term) - -if position is None: - print("{} not found".format(search_term)) -else: - print("{} found at position {}".format(search_term, position)) - - -search_term = 2 -position = search_ordered(scores, search_term) -if position is None: - print("{} not found".format(search_term)) -else: - print("{} found at position {}".format(search_term, position)) diff --git a/Chapter11/Insertion_sort.py b/Chapter11/Insertion_sort.py deleted file mode 100644 index fd1634b..0000000 --- a/Chapter11/Insertion_sort.py +++ /dev/null @@ -1,18 +0,0 @@ - -def insertion_sort(unsorted_list): - for index in range(1, len(unsorted_list)): - search_index = index - insert_value = unsorted_list[index] - while search_index > 0 and unsorted_list[search_index-1] > insert_value : - unsorted_list[search_index] = unsorted_list[search_index-1] - search_index -= 1 - unsorted_list[search_index] = insert_value - - - - - -my_list = [10, 11, 12, 1, 2, 3] -print(my_list) -insertion_sort(my_list) -print(my_list) diff --git a/Chapter11/Quick_sort.py b/Chapter11/Quick_sort.py deleted file mode 100644 index 96efa57..0000000 --- a/Chapter11/Quick_sort.py +++ /dev/null @@ -1,35 +0,0 @@ -def partition(unsorted_array, first_index, last_index): - pivot = unsorted_array[first_index] - pivot_index = first_index - index_of_last_element = last_index - less_than_pivot_index = index_of_last_element - greater_than_pivot_index = first_index + 1 - while True: - while unsorted_array[greater_than_pivot_index] < pivot and greater_than_pivot_index < last_index: - greater_than_pivot_index += 1 - while unsorted_array[less_than_pivot_index] > pivot and less_than_pivot_index >= first_index: - less_than_pivot_index -= 1 - if greater_than_pivot_index < less_than_pivot_index: - temp = unsorted_array[greater_than_pivot_index] - unsorted_array[greater_than_pivot_index] = unsorted_array[less_than_pivot_index] - unsorted_array[less_than_pivot_index] = temp - else: - break - unsorted_array[pivot_index] = unsorted_array[less_than_pivot_index] - unsorted_array[less_than_pivot_index] = pivot - return less_than_pivot_index - - -def quick_sort(unsorted_array, first, last): - if last - first <= 0: - return - else: - partition_point = partition(unsorted_array, first, last) - quick_sort(unsorted_array, first, partition_point-1) - quick_sort(unsorted_array, partition_point+1, last) - - -my_array = [43, 3, 77, 89, 4, 20] -print(my_array) -quick_sort(my_array, 0, 5) -print(my_array) diff --git a/Chapter11/Selection_Sort.py b/Chapter11/Selection_Sort.py deleted file mode 100644 index fa39989..0000000 --- a/Chapter11/Selection_Sort.py +++ /dev/null @@ -1,14 +0,0 @@ - -def selection_sort(unsorted_list): - size_of_list = len(unsorted_list) - for i in range(size_of_list): - for j in range(i+1, size_of_list): - if unsorted_list[j] < unsorted_list[i]: - temp = unsorted_list[i] - unsorted_list[i] = unsorted_list[j] - unsorted_list[j] = temp - - -a_list = [3, 2, 35, 4, 32, 94, 5, 7] -selection_sort(a_list) -print(a_list) diff --git a/Chapter11/bubble_sort.py b/Chapter11/bubble_sort.py deleted file mode 100644 index 58e2f81..0000000 --- a/Chapter11/bubble_sort.py +++ /dev/null @@ -1,29 +0,0 @@ -unordered_list = [5, 2] - -temp = unordered_list[0] -unordered_list[0] = unordered_list[1] -unordered_list[1] = temp - -print(unordered_list) - - - -def bubble_sort(unordered_list): - iteration_number = len(unordered_list)-1 - for i in range(iteration_number,0,-1): - for j in range(i): - if unordered_list[j] > unordered_list[j+1]: - temp = unordered_list[j] - unordered_list[j] = unordered_list[j+1] - unordered_list[j+1] = temp - - - - -my_list = [4,3,2,1] -bubble_sort(my_list) -print(my_list) - -my_list = [1,12,3,4] -bubble_sort(my_list) -print(my_list) diff --git a/Chapter12/deterministic_selection.py b/Chapter12/deterministic_selection.py deleted file mode 100644 index 8258e3b..0000000 --- a/Chapter12/deterministic_selection.py +++ /dev/null @@ -1,85 +0,0 @@ -def partition(unsorted_array, first_index, last_index): - if first_index == last_index: - return first_index - else: - nearest_median = median_of_medians(unsorted_array[first_index:last_index]) - - index_of_nearest_median = get_index_of_nearest_median(unsorted_array, first_index, - last_index, nearest_median) - swap(unsorted_array, first_index, index_of_nearest_median) - - pivot = unsorted_array[first_index] - pivot_index = first_index - index_of_last_element = last_index - less_than_pivot_index = index_of_last_element - greater_than_pivot_index = first_index + 1 - - ## This while loop is used to correctly place pivot element at its correct position - while 1: - while unsorted_array[greater_than_pivot_index] < pivot and greater_than_pivot_index < last_index: - greater_than_pivot_index += 1 - while unsorted_array[less_than_pivot_index] > pivot and less_than_pivot_index >= first_index: - less_than_pivot_index -= 1 - - if greater_than_pivot_index < less_than_pivot_index: - temp = unsorted_array[greater_than_pivot_index] - unsorted_array[greater_than_pivot_index] = unsorted_array[less_than_pivot_index] - unsorted_array[less_than_pivot_index] = temp - else: - break - - unsorted_array[pivot_index]=unsorted_array[less_than_pivot_index] - unsorted_array[less_than_pivot_index]=pivot - return less_than_pivot_index - - -def median_of_medians(elems): - - sublists = [elems[j:j+5] for j in range(0, len(elems), 5)] - medians = [] - for sublist in sublists: - medians.append(sorted(sublist)[int(len(sublist)/2)]) - - if len(medians) <= 5: - return sorted(medians)[int(len(medians)/2)] - else: - return median_of_medians(medians) - - - -def get_index_of_nearest_median(array_list, first, second, median): - if first == second: - return first - else: - return first + array_list[first:second].index(median) - - - - -def swap(array_list, first, second): - temp = array_list[first] - array_list[first] = array_list[second] - array_list[second] = temp - - - - -def deterministic_select(array_list, left, right, k): - - split = partition(array_list, left, right) - if split == k: - return array_list[split] - elif split < k: - return deterministic_select(array_list, split + 1, right, k) - else: - return deterministic_select(array_list, left, split-1, k) - - - - -stored = [3,1,10,4,6, 5] -print(deterministic_select(stored, 0, 5, 2)) - - - - diff --git a/Chapter12/randomized_search.py b/Chapter12/randomized_search.py deleted file mode 100644 index 655afbb..0000000 --- a/Chapter12/randomized_search.py +++ /dev/null @@ -1,67 +0,0 @@ -def partition(unsorted_array, first_index, last_index): - - pivot = unsorted_array[first_index] - pivot_index = first_index - index_of_last_element = last_index - - less_than_pivot_index = index_of_last_element - greater_than_pivot_index = first_index + 1 - - while True: - - while unsorted_array[greater_than_pivot_index] < pivot and greater_than_pivot_index < last_index: - greater_than_pivot_index += 1 - while unsorted_array[less_than_pivot_index] > pivot and less_than_pivot_index >= first_index: - less_than_pivot_index -= 1 - - if greater_than_pivot_index < less_than_pivot_index: - temp = unsorted_array[greater_than_pivot_index] - unsorted_array[greater_than_pivot_index] = unsorted_array[less_than_pivot_index] - unsorted_array[less_than_pivot_index] = temp - else: - break - - unsorted_array[pivot_index] = unsorted_array[less_than_pivot_index] - unsorted_array[less_than_pivot_index] = pivot - - return less_than_pivot_index - - -def quick_select(array_list, left, right, k): - - split = partition(array_list, left, right) - - if split == k: - return array_list[split] - elif split < k: - return quick_select(array_list, split + 1, right, k) - else: - return quick_select(array_list, left, split-1, k) - - -stored = [5, 3] -print(stored) -print(quick_select(stored, 0, 1, 0)) - -stored = [3, 5] -print(stored) -print(quick_select(stored, 0, 1, 0)) - - - - - - -stored = [3,1,10,4,6,5] -print(stored) -print(quick_select(stored, 0, 5, 0)) -stored = [3,1,10,4,6, 5] -print(quick_select(stored, 0, 5, 1)) -stored = [3,1,10,4,6, 5] -print(quick_select(stored, 0, 5, 2)) -stored = [3,1,10,4,6, 5] -print(quick_select(stored, 0, 5, 3)) -stored = [3,1,10,4,6, 5] -print(quick_select(stored, 0, 5, 4)) -stored = [3,1,10,4,6, 5] -print(quick_select(stored, 0, 5, 5)) diff --git a/Chapter13/Boyer_Moore_String_Matching.py b/Chapter13/Boyer_Moore_String_Matching.py deleted file mode 100644 index a25803b..0000000 --- a/Chapter13/Boyer_Moore_String_Matching.py +++ /dev/null @@ -1,46 +0,0 @@ -text = "acbaacacababacacac" -pattern = "acacac" - - -matched_indexes = [] - -i=0 -flag = True -while i<=len(text)-len(pattern): - for j in range(len(pattern)-1, -1, -1): #reverse searching - if pattern[j] != text[i+j]: - flag = False #indicates there is a mismatch - if j == len(pattern)-1: #if good-suffix is not present, we test bad character - if text[i+j] in pattern[0:j]: - i=i+j-pattern[0:j].rfind(text[i+j]) - #i+j is index of bad character, this line is used for jumping pattern to match - #bad character of text with same character in pattern - else: - i=i+j+1 #if bad character is not present, jump pattern next to it - else: - k=1 - while text[i+j+k:i+len(pattern)] not in pattern[0:len(pattern)-1]: - #used for finding sub part of a good-suffix - k=k+1 - if len(text[i+j+k:i+len(pattern)]) != 1: #good-suffix should not be of one character - gsshift=i+j+k-pattern[0:len(pattern)-1].rfind(text[i+j+k:i+len(pattern)]) - #jumps pattern to a position where good-suffix of pattern matches with good-suffix of text - else: - #gsshift=i+len(pattern) - gsshift=0 #when good-suffix heuristic is not applicable, - #we prefer bad character heuristic - if text[i+j] in pattern[0:j]: - bcshift=i+j-pattern[0:j].rfind(text[i+j]) - #i+j is index of bad character, this line is used for jumping pattern to match bad character - #of text with same character in pattern - else: - bcshift=i+j+1 - i=max((bcshift, gsshift)) - break - if flag: #if pattern is found then normal iteration - matched_indexes.append(i) - i = i+1 - else: #again set flag to True so new string in text can be examined - flag = True - -print ("Pattern found at", matched_indexes) diff --git a/Chapter13/Brute_force_string_matching.py b/Chapter13/Brute_force_string_matching.py deleted file mode 100644 index bc614e5..0000000 --- a/Chapter13/Brute_force_string_matching.py +++ /dev/null @@ -1,27 +0,0 @@ -def brute_force(text, pattern): - l1 = len(text) # The length of the text string - l2 = len(pattern) # The length of the pattern - i = 0 - j = 0 # looping variables are set to 0 - flag = False # If the pattern doesn't appear at all, then set this to false and execute the last if statement - while i < l1: # iterating from the 0th index of text - j = 0 - count = 0 - # Count stores the length upto which the pattern and the text have matched - while j < l2: - if i+j < l1 and text[i+j] == pattern[j]: - # statement to check if a match has occurred or not - count += 1 # Count is incremented if a character is matched - j += 1 - if count == l2: # it shows a matching of pattern in the text - print("\nPattern occurs at index", i) - # print the starting index of the successful match - flag = True - # flag is True as we wish to continue looking for more matching of pattern in the text. - i += 1 - if not flag: - # If the pattern doesn't occurs at all, means no match of pattern in the text string - print('\nPattern is not at all present in the array') - - -brute_force('acbcabccababcaacbcac','acbcac') # function call diff --git a/Chapter13/Rabin_Karp_String_Matching.py b/Chapter13/Rabin_Karp_String_Matching.py deleted file mode 100644 index dda066f..0000000 --- a/Chapter13/Rabin_Karp_String_Matching.py +++ /dev/null @@ -1,46 +0,0 @@ -def generate_hash(text, pattern): - ord_text = [ord(i) for i in text] # stores unicode value of each character in text - ord_pattern = [ord(j) for j in pattern] # stores unicode value of each character in pattern - len_text = len(text) # stores length of the text - len_pattern = len(pattern) # stores length of the pattern - len_hash_array = len_text - len_pattern + 1 # stores the length of new array that will contain the hash values of text - hash_text = [0]*(len_hash_array) # Initialize all the values in the array to 0. - hash_pattern = sum(ord_pattern) - for i in range(0,len_hash_array): # step size of the loop will be the size of the pattern - if i == 0: # Base condition - hash_text[i] = sum(ord_text[:len_pattern]) # initial value of hash function - else: - hash_text[i] = ((hash_text[i-1] - ord_text[i-1]) + ord_text[i+len_pattern-1]) # calculating next hash value using previous value - return [hash_text, hash_pattern] # return the hash values - - - -def Rabin_Karp_Matcher(text, pattern): - text = str(text) # convert text into string format - pattern = str(pattern) # convert pattern into string format - hash_text, hash_pattern = generate_hash(text, pattern) # generate hash values using generate_hash function - len_text = len(text) # length of text - len_pattern = len(pattern) # length of pattern - flag = False # checks if pattern is present atleast once or not at all - for i in range(len(hash_text)): - if hash_text[i] == hash_pattern: # if the hash value matches - count = 0 # count stores the total characters upto which both are similar - for j in range(len_pattern): - if pattern[j] == text[i+j]: # checking equality for each character - count += 1 # if value is equal, then update the count value - else: - break - if count == len_pattern: # if count is equal to length of pattern, it means match has been found - flag = True # update flag accordingly - print('Pattern occours at index',i) - if not flag: # if pattern doesn't match even once, then this if statement is executed - print('Pattern is not at all present in the text') - - -Rabin_Karp_Matcher("101110000011010010101101","10112") - -# Works for numeric -Rabin_Karp_Matcher("101110000011010010101101","1011") - -# Works for alphabets -Rabin_Karp_Matcher("ABBACCADABBACCEDF","ACCE") diff --git a/Chapter13/example_suffix_prefix.py b/Chapter13/example_suffix_prefix.py deleted file mode 100644 index 42d2741..0000000 --- a/Chapter13/example_suffix_prefix.py +++ /dev/null @@ -1,6 +0,0 @@ -string = "this is data structures book by packt publisher" -suffix = "publisher" -prefix = "this" -print(string.endswith(suffix)) #Check if string contains given suffix. - -print(string.startswith(prefix)) #Check if string starts with given prefix. From 3c0cf64cb74711993073ddc0913053eb96997cde Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Tue, 26 Apr 2022 15:04:15 +0530 Subject: [PATCH 04/53] Updated --- .DS_Store | Bin 0 -> 12292 bytes Chapter01/chapter1.py | 578 ++++++++++++++++++ Chapter02/binary_search.py | 16 + Chapter02/linear_search.py | 13 + Chapter02/matrix_chain.py | 14 + Chapter02/merge_sort.py | 37 ++ Chapter03/Fibonacci_series.py | 8 + Chapter03/MatrixChain_multiplication.py | 14 + Chapter03/binary_search.py | 16 + Chapter03/dijkstra.py | 80 +++ Chapter03/dyna_fib.py | 13 + Chapter03/factorial.py | 10 + Chapter03/merge_sort.py | 35 ++ Chapter04/CircularList.py | 103 ++++ Chapter04/SinglyLinkedList.py | 34 ++ ...ppend_at_any_location_singly_linkedlist.py | 69 +++ .../delete_operation_doubly_linkedlist.py | 80 +++ .../delete_operation_singly_linkedlist.py | 78 +++ Chapter04/doubly_linked_list.py | 69 +++ Chapter04/faster_append_singly_linked_list.py | 32 + Chapter04/list_traversal_singly_linklist.py | 38 ++ Chapter05/.DS_Store | Bin 0 -> 6148 bytes Chapter05/Linked_list_based_queue.py | 50 ++ Chapter05/List_based_queue.py | 34 ++ Chapter05/Queue_application.py | 98 +++ Chapter05/Stack.py | 68 +++ Chapter05/Stack_application.py | 68 +++ Chapter05/Stack_based_queue.py | 31 + Chapter05/Stack_using_array.py | 51 ++ Chapter06/binary_search_tree.py | 156 +++++ Chapter06/level_order_traversal.py | 35 ++ Chapter06/reverse_polish_expression.py | 46 ++ Chapter06/tree_traversal.py | 53 ++ Chapter07/.DS_Store | Bin 0 -> 6148 bytes Chapter07/heap.py | 73 +++ Chapter07/heap_sort.py | 90 +++ Chapter07/priorityQueue.py | 57 ++ Chapter07/priorityQueueHeap.py | 59 ++ Chapter08/.DS_Store | Bin 0 -> 6148 bytes Chapter08/hashing.py | 10 + Chapter08/hashtable.py | 160 +++++ Chapter08/hashtable_chaining.py | 102 ++++ Chapter09/breadth_first_search.py | 33 + Chapter09/depth_first_search.py | 36 ++ Chapter09/graph.py | 31 + Chapter10/.DS_Store | Bin 0 -> 6148 bytes Chapter10/Unordered_linear_search.py | 33 + Chapter10/binary_search_iterative.py | 44 ++ Chapter10/binary_search_recursive.py | 37 ++ Chapter10/exponential_search.py | 28 + Chapter10/interpolation_search.py | 29 + Chapter10/jump_search.py | 42 ++ Chapter10/search_ordered_list.py | 33 + Chapter11/.DS_Store | Bin 0 -> 6148 bytes Chapter11/Insertion_sort.py | 19 + Chapter11/Quick_sort.py | 35 ++ Chapter11/Selection_Sort.py | 21 + Chapter11/Tim_sort.py | 55 ++ Chapter11/bubble_sort.py | 29 + Chapter12/.DS_Store | Bin 0 -> 6148 bytes Chapter12/deterministic_selection.py | 85 +++ Chapter12/randomized_search.py | 63 ++ Chapter13/.DS_Store | Bin 0 -> 6148 bytes Chapter13/Boyer_Moore_String_Matching.py | 46 ++ Chapter13/Brute_force_string_matching.py | 27 + Chapter13/KMP.py | 35 ++ Chapter13/Rabin_Karp_String_Matching.py | 46 ++ Chapter13/example_suffix_prefix.py | 6 + 68 files changed, 3391 insertions(+) create mode 100644 .DS_Store create mode 100644 Chapter01/chapter1.py create mode 100644 Chapter02/binary_search.py create mode 100644 Chapter02/linear_search.py create mode 100644 Chapter02/matrix_chain.py create mode 100644 Chapter02/merge_sort.py create mode 100644 Chapter03/Fibonacci_series.py create mode 100644 Chapter03/MatrixChain_multiplication.py create mode 100644 Chapter03/binary_search.py create mode 100644 Chapter03/dijkstra.py create mode 100644 Chapter03/dyna_fib.py create mode 100644 Chapter03/factorial.py create mode 100644 Chapter03/merge_sort.py create mode 100644 Chapter04/CircularList.py create mode 100644 Chapter04/SinglyLinkedList.py create mode 100644 Chapter04/append_at_any_location_singly_linkedlist.py create mode 100644 Chapter04/delete_operation_doubly_linkedlist.py create mode 100644 Chapter04/delete_operation_singly_linkedlist.py create mode 100644 Chapter04/doubly_linked_list.py create mode 100644 Chapter04/faster_append_singly_linked_list.py create mode 100644 Chapter04/list_traversal_singly_linklist.py create mode 100644 Chapter05/.DS_Store create mode 100644 Chapter05/Linked_list_based_queue.py create mode 100644 Chapter05/List_based_queue.py create mode 100644 Chapter05/Queue_application.py create mode 100644 Chapter05/Stack.py create mode 100644 Chapter05/Stack_application.py create mode 100644 Chapter05/Stack_based_queue.py create mode 100644 Chapter05/Stack_using_array.py create mode 100644 Chapter06/binary_search_tree.py create mode 100644 Chapter06/level_order_traversal.py create mode 100644 Chapter06/reverse_polish_expression.py create mode 100644 Chapter06/tree_traversal.py create mode 100644 Chapter07/.DS_Store create mode 100644 Chapter07/heap.py create mode 100644 Chapter07/heap_sort.py create mode 100644 Chapter07/priorityQueue.py create mode 100644 Chapter07/priorityQueueHeap.py create mode 100644 Chapter08/.DS_Store create mode 100644 Chapter08/hashing.py create mode 100644 Chapter08/hashtable.py create mode 100644 Chapter08/hashtable_chaining.py create mode 100644 Chapter09/breadth_first_search.py create mode 100644 Chapter09/depth_first_search.py create mode 100644 Chapter09/graph.py create mode 100644 Chapter10/.DS_Store create mode 100644 Chapter10/Unordered_linear_search.py create mode 100644 Chapter10/binary_search_iterative.py create mode 100644 Chapter10/binary_search_recursive.py create mode 100644 Chapter10/exponential_search.py create mode 100644 Chapter10/interpolation_search.py create mode 100644 Chapter10/jump_search.py create mode 100644 Chapter10/search_ordered_list.py create mode 100644 Chapter11/.DS_Store create mode 100644 Chapter11/Insertion_sort.py create mode 100644 Chapter11/Quick_sort.py create mode 100644 Chapter11/Selection_Sort.py create mode 100644 Chapter11/Tim_sort.py create mode 100644 Chapter11/bubble_sort.py create mode 100644 Chapter12/.DS_Store create mode 100644 Chapter12/deterministic_selection.py create mode 100644 Chapter12/randomized_search.py create mode 100644 Chapter13/.DS_Store create mode 100644 Chapter13/Boyer_Moore_String_Matching.py create mode 100644 Chapter13/Brute_force_string_matching.py create mode 100644 Chapter13/KMP.py create mode 100644 Chapter13/Rabin_Karp_String_Matching.py create mode 100644 Chapter13/example_suffix_prefix.py diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..cecaf8ae0afb7e4d2b76d4ab89003fe02f0b3f24 GIT binary patch literal 12292 zcmeI2-EPw`6vt2Y!O{Vu5}?6dZjgpFp`_mxnpC>&ViF)k5nKS;T3WG6T{E>E6@;SR z@D2l>fHwhdxa2{20Qes#t5PRR&;+b%eI)1Dj-AE7xk>)VCL*nTSht8)iAYCcpS*x- z6pZsI_>9kU3fMeqG^CqI$R~-abU;07P>0Mw>&dH_!!7asFCZmogZ9SmKVR#24{9yD zhO^&l2d!qeXPQ5>x%q{~b4$9utS?_&eqPzL`;}g`ci1ggJ5RavpxWE3dHF}S-5TYq zwa3jye9>WDBXmAfd0^u-3PC_g}wp-VWY<#NEO)9v9ms*Nu*!j$4mvR7Md{1QY>9 zVAcqD?+9Ib-_IHbHC{zP5eOl`&j$mEeaZ7f*NaC74*Utt=lK&_81m2oqR#Mq$@4?k zi>~M+y286%HBVw_ZgyDyl~{U~kKPo;!a`=BMOG}ol*I3SEWgwY z@k_<>OH2HI#_~(g5Wlp9KoL*`W{SXNj5esiB!wWA__tzXJ zZRVg*^RB$lLg|NXHemSAW`yA6iW3MX$pV1|YBWB-K$z~}h%66+d^6)8{2I&C zXnGl+yqW}h|0+0QQbrP2L3&w<9*fgxdRZU6=?;#Vl#S(=8|NnkYBax`kKZKBz6^qy z>69e`nYxZH0@F!ATiC2@ zmNB;DWg2;yyw+|Y?IN*pyCG*_$cv?Tc(D`@FP7rrM|*&gFL`Z;u15{*|8D|N@BcsE ZD2)G4$k$Qq8%(|bd1i+%Y);bq|2HNbIHCXm literal 0 HcmV?d00001 diff --git a/Chapter01/chapter1.py b/Chapter01/chapter1.py new file mode 100644 index 0000000..2631bf5 --- /dev/null +++ b/Chapter01/chapter1.py @@ -0,0 +1,578 @@ +p = "Hello India" +q = 10 +r = 10.2 +print(type(p)) +print(type(q)) +print(type(r)) +print(type(12+31j)) + +############### + +var = 13.2 +print(var) +#13.2 + +type (var) +# + +var = "Now the type is string" +print(var) + +type(var) +# +var = 13.2 +print(var) +#13.2 + +############# +print(type(bool(22))) +print(type(True)) +print(type(False)) +''' +Output: + + + +''' + +bool(False) +#False +va1 = 0 +print(bool(va1)) +#False + +va2 = 11 +print(bool(va2)) +#True + +va3 = -2.3 +print(bool(va3)) +#True + +#### Strings +Str1 = 'Hello how are you' +str2 = "Hello how are you" +str3 = 'multiline'+'string'; +print(str3) + +f = 'data' +s = 'structure' +print(f + s) +#'datastructure' +print('Data ' + 'structure') +#Data structure + + +st = 'data.' +print(st * 3) +#'data.data.data.' +print(3 * st) +#'data.data.data.' + + +###### Lists ###### + +a = ['food', 'bus', 'apple', 'queen'] +print(a) +#['food', 'bus', 'apple', 'queen'] + + +mylist = [10, "India", "world", 8] +# accessing elements in list. +print(mylist[1]) +#India + + + +###### Ordered List ###### + +[10, 12, 31, 14] == [14, 10, 31, 12] +print([10, 12, 31, 14] == [14, 10, 31, 12]) +#False + + +###### Dynamic List ###### +b = ['data', 'and', 'book', 'structure', 'hello', 'st'] + +b += [32] +print(b) +#['data', 'and', 'book', 'structure', 'hello', 'st', 32] + + +b[2:3] = [] +print(b) +#['data', 'and', 'structure', 'hello', 'st', 32] + +del b[0] +print(b) +#['and', 'structure', 'hello', 'st', 32] + +a = [2.2, 'python', 31, 14, 'data', False, 33.59] +print(a) +#[2.2, 'python', 31, 14, 'data', False, 33.59] + + +a = ['data', 'structures', 'using', 'python', 'happy', 'learning'] +print(a[0]) +'data' +print(a[2]) +'using' +print(a[-1]) +'learning' +print(a[-5]) +'structures' + + +print(a[1:5]) +['structures', 'using'] + +print(a[-3:-1]) +['python', 'happy'] + +######### Mutable #### +a = ['data', 'and', 'book', 'structure', 'hello', 'st'] +print(a) +['data', 'and', 'book', 'structure', 'hello', 'st'] +a[1] = 1 +a[-1] = 120 +print(a) +['data', 1, 'book', 'structure', 'hello', 120] + +a = ['data', 'and', 'book', 'structure', 'hello', 'st'] + +print(a[2:5]) +['book', 'structure', 'hello'] +a[2:5] = [1, 2, 3, 4, 5] +print(a) +['data', 'and', 1, 2, 3, 4, 5, 'st'] + +######### Other operators #### + +a = ['data', 'structures', 'using', 'python', 'happy', 'learning'] +print('data' in a) +#True + +print(a) +#['data', 'structures', 'using', 'python', 'happy', 'learning'] + +a + ['New', 'elements'] +print(a) +#['data', 'structures', 'using', 'python', 'happy', 'learning', 'New', 'elements'] + +print(a * 2) +#['data', 'structures', 'using', 'python', 'happy', 'learning', 'New', 'elements', 'data', 'structures', 'using', 'python', 'happy', 'learning', 'New', 'elements'] + +print(len(a)) +#6 +print(min(a)) + + +############ Membership operators + +#using 'in' operator +mylist1=[100,20,30,40] +mylist2=[10,50,60,90] +if mylist1[1] in mylist2: + print("elements are overlapping") +else: + print("elements are not overlapping") + +#Output: +#elements are not overlapping + + +########## Program to illustrate 'not in' operator +val = 104 +mylist = [100, 210, 430, 840, 108] +if val not in mylist: + print("val is NOT present in mylist") +else: + print("val is present in mylist") + +#Output: +#val is NOT present in mylist + + + +############# Example program to demonstrate the use of 'is' operator +Firstlist = [] +Secondlist = [] +if Firstlist == Secondlist: + print("Both are equal") +else: + print("Both are not equal") +if Firstlist is Secondlist: + print("Both variables are pointing to the same object") +else: + print("Both variables are not pointing to the same object") +thirdList = Firstlist +if thirdList is Secondlist: + print("Both are pointing to the same object") +else: + print("Both are not pointing to the same object ") +''' +Output: +Both are equal +Both variables are not pointing to the same object +Both are pointing to the same object +''' + + + +####### Example program to demonstrate the use of 'is not' operator +Firstlist = [] +Secondlist = [] +if Firstlist is not Secondlist: + print("Both are pointing to the different object") +else: + print("Both are not pointing to the different object ") + +#Output: +# Both are pointing to the different object + + + +############## Logical Operators + +#### Example program to demonstrate the use of 'and' operator +a = 32 +b = 132 +if a > 0 and b > 0: + print("Both a and b are greater than zero") +else: + print("At least one variable is less than 0") + +#Output: +#Both a and b are greater than zero + + + +######### Example program to demonstrate the use of 'or' operator +a = 32 +b = -32 +if a > 0 or b > 0: + print("At least one variable is greater than zero") +else: + print("Both variables are less than 0") + +#Output: +#At least one variable is greater than zero + + +########## Example program to demonstrate the use of 'or' operator +a = 32 +if not a: + print("Boolean value of a is False") +else: + print("Boolean value of a is True") + +#Output: +#Boolean value of a is True + + + + +########## Tuple ########### + +tupleName = ("entry1" , "entry2" , "entry3") +myTuple = ("Shyam", 23 , True , "male") +print(len((4,5, 'hello'))) + +print((4,5)+(10,20)) +print((2,1)*3) +print(3 in ('hi', 'xyz',3)) +for p in (6,7,8): + print(p) + +x = ('hello', 'world', 'india') +print(x[1]) +print(x[-2]) +print(x[1:]) + + +######### Dictionaries ######### +my_dict = { + '1': 'Data', + '2': 'Structure', + '3': 'python', + '4': 'programming', + '5': 'language' +} + + +############ + +person = {} +print(type(person)) +# + +person['name'] = 'ABC' +person['lastname'] = 'XYZ' +person['age'] = 31 +person['address'] = ['Jaipur'] + +print(person) +#{'name': 'ABC', 'lastname': 'XYZ', 'age': 31, 'address': ['Jaipur']} + +print(person['name']) +#'ABC' + + +print('name' in person) +#True +print('fname' not in person) +#True +print(len(person)) +#4 + +mydict = {'a': 1, 'b': 2, 'c': 3} +print(mydict) +#{'a': 1, 'b': 2, 'c': 3} +mydict.clear() +print(mydict) +#{} + +''' +mydict.get('b') +print(mydict) +#2 +mydict.get('z') +print(mydict) +#None + +print(list(mydict.items())) +#[('a', 1), ('b', 2), ('c', 3)] + +print(list(mydict.keys())) +#['a', 'b', 'c'] + +print(list(mydict.values())) +#[1, 2, 3] + +print(mydict.pop('b')) +#2 +print(mydict) +#{'a': 1, 'c': 3} +mydict = {'a': 1,'b': 2,'c': 3} +print(mydict.popitem()) +#('c', 3) +print(mydict) +#{'a': 1, 'b': 2} +d1 = {'a': 10, 'b': 20, 'c': 30} +d2 = {'b': 200, 'd': 400} + +print(d1.update(d2)) +print(d1) +#{'a': 10, 'b': 200, 'c': 30, 'd': 400} +''' + + +############## SETS ############# + +x1 = set(['and', 'python', 'data', 'structure']) +print(x1) +#{'and', 'python', 'data', 'structure'} +print(type(x1)) +# + +x2 = {'and', 'python', 'data', 'structure'} +print(x2) +#{'and', 'python', 'data', 'structure'} +x = {'data', 'structure', 'and', 'python'} +print(len(x)) +#4 +print('structure' in x) +#True +x1 = {'data', 'structure'} +x2 = {'python', 'java', 'c', 'data'} + +######### Union of two sets, x1 and x2. +x3 = x1 | x2 +print(x3) +{'java', 'structure', 'c', 'python', 'data'} + +print(x1.union(x2)) +{'java', 'structure', 'c', 'python', 'data'} + + +########## Intersection of sets +print(x1.intersection(x2)) +#{'data'} +print(x1 & x2) +#{'data'} + + +########## Difference of sets + +print(x1.difference(x2)) +#{'structure'} +print(x1 - x2) +#{'structure'} + + +######### Symmetric difference ########## +print(x1.symmetric_difference(x2)) +#{'structure', 'python', 'c', 'java'} + +print(x1 ^ x2) +#{'structure', 'python', 'c', 'java'} + +####### subset ###### + +print(x1.issubset(x2)) +#False +print(x1 <= x2) +#False + +########## Immutable Sets ######### + +x = frozenset(['data', 'structure', 'and', 'python']) +print(x) +#frozenset({'and', 'python', 'data', 'structure'}) +##### Error in the below code #### +''' +a11 = set(['data']) +a21 = set(['structure']) +a31 = set(['python']) +x1 = {a11, a21, a31} +''' + +a1 = frozenset(['data']) +a2 = frozenset(['structure']) +a3 = frozenset(['python']) +x = {a1, a2, a3} +print(x) + + + +######## Named Tuples ######## + +from collections import namedtuple +Book = namedtuple ('Book', ['name', 'ISBN', 'quantity']) +Book1 = Book('Hands on Data Structures', '9781788995573', '50') +# Accessing data items +print('Using index ISBN:' + Book1[1]) +#Using index ISBN: 9781788995573 +print('Using key ISBN:' + Book1.ISBN) +#Using key ISBN: 9781788995573 + + +######## Deque ############ + +from collections import deque +s = deque() # Creates an empty deque +my_queue = deque([1, 2, 'Name']) +print(my_queue) +#deque([1, 2, 'Name']) +my_queue.append('age') +print(my_queue) +my_queue.appendleft('age') +print(my_queue) +my_queue.pop() +print(my_queue) +my_queue.popleft() +print(my_queue) + + +########## Ordered Dictionaries ######## + +from collections import OrderedDict +od = OrderedDict({'my': 2, 'name ': 4, 'is': 2, 'Mohan' :5}) +od['hello'] = 4 +print(od) +#([('my', 2), ('name', 4), ('is', 2), ('Mohan', 5), ('hello', 4)]) + + +############ Default Dictionary ######## + +from collections import defaultdict +dd = defaultdict(int) +words = str.split('data python data data structure data python') +for word in words: + dd[word] +=1 + +print(dd) +#defaultdict(, {'data': 4, 'python': 2, 'structure': 1}) + + + + +############ ChainMap Object ############## + +from collections import ChainMap +dict1 = {"data": 1, "structure": 2} +dict2 = {"python": 3, "language": 4} +chain = ChainMap(dict1, dict2) + +print(chain) +#ChainMap({'data': 1, 'structure': 2}, {'python': 3, 'language': 4}) +print (list(chain.keys())) +#['python', 'language', 'data', 'structure'] +print (list(chain.values())) +#[3, 4, 1, 2] +print(chain["data"]) +#1 +print(chain["language"]) +#4 + + +################ Counter Objects ########### + +from collections import Counter +inventory = Counter('hello') +print(inventory) +Counter({'l': 2, 'h': 1, 'e': 1, 'o': 1}) + + + +############### UserDict ############# +''' +from collections import UserDict +class MyDict(UserDict): + def push(self, key, value): + raise RuntimeError("Cannot insert") + +d = MyDict({'ab':1, 'bc': 2, 'cd': 3}) +d.push('b', 2) + +Traceback (most recent call last): + File "", line 12, in +File "", line 6, in push +RuntimeError: Cannot insert +''' + +######### UserList ########### +''' +from collections import UserList +class MyList(UserList): + def push(self, key): + raise RuntimeError("Cannot insert in the list") + +d = MyList([11, 12, 13]) +d.push(2) + +Traceback (most recent call last): + Traceback (most recent call last): + File "", line 1, in + File "", line 3, in push +RuntimeError: Cannot insert in the list +''' + +######### UserString ########## + +# create a custom append function for string +from collections import UserString +class MyString(UserString): + def append(self, value): + self.data += value + +s1 = MyString("data") +print("Original:", s1) +#Original: data + +s1.append('h') +print("After append: ", s1) +#After append: datah + + + diff --git a/Chapter02/binary_search.py b/Chapter02/binary_search.py new file mode 100644 index 0000000..4ca8711 --- /dev/null +++ b/Chapter02/binary_search.py @@ -0,0 +1,16 @@ +def binary_search(arr, low, high, key): + while low <= high: + mid = int(low + (high - low)/2) + if arr[mid] == key: + return mid + elif arr[mid] < key: + low = mid + 1 + else: + high = mid - 1 + return -1 + + +arr = [ 2, 3, 4, 2, 10, 40] +x = 10 +result = binary_search(arr, 0, len(arr)-1, x) +print(result) diff --git a/Chapter02/linear_search.py b/Chapter02/linear_search.py new file mode 100644 index 0000000..a66c676 --- /dev/null +++ b/Chapter02/linear_search.py @@ -0,0 +1,13 @@ +# Linear search program to search an element, return the index position of the #array + +def linear_search(input_list, element): + for index, value in enumerate(input_list): + if value == element: + return index + + return -1 + + +input_list = [3, 4, 1, 6, 14] +element = 4 +print("Index position for the element x is:", linear_search(input_list,element)) diff --git a/Chapter02/matrix_chain.py b/Chapter02/matrix_chain.py new file mode 100644 index 0000000..2d30a87 --- /dev/null +++ b/Chapter02/matrix_chain.py @@ -0,0 +1,14 @@ +import sys + +def matrix_chain(mat, i, j): + if i == j: + return 0 + minimum_computations = sys.maxsize + for k in range(i, j): + count = (MatrixChain(mat, i, k) + MatrixChain(mat, k+1, j)+ mat[i-1] * mat[k] * mat[j]) + if count < minimum_computations: + minimum_computations = count + return minimum_computations + +matrix_sizes = [20, 30, 45, 50] +print("Minimum multiplications are", MatrixChain(matrix_sizes , 1, len(matrix_sizes)-1)) diff --git a/Chapter02/merge_sort.py b/Chapter02/merge_sort.py new file mode 100644 index 0000000..d724aca --- /dev/null +++ b/Chapter02/merge_sort.py @@ -0,0 +1,37 @@ +def merge_sort(unsorted_list): + if len(unsorted_list) == 1: + return unsorted_list + mid_point = int(len(unsorted_list)/2) + first_half = unsorted_list[:mid_point] + second_half = unsorted_list[mid_point:] + + half_a = merge_sort(first_half) + half_b = merge_sort(second_half) + + return merge(half_a, half_b) + + +def merge(first_sublist, second_sublist): + i = j = 0 + merged_list = [] + while i < len(first_sublist) and j < len(second_sublist): + if first_sublist[i] < second_sublist[j]: + merged_list.append(first_sublist[i]) + i += 1 + else: + merged_list.append(second_sublist[j]) + j += 1 + + while i < len(first_sublist): + merged_list.append(first_sublist[i]) + i += 1 + + while j < len(second_sublist): + merged_list.append(second_sublist[j]) + j += 1 + return merged_list + + +a= [11, 12, 7, 41, 61, 13, 16, 14] +print(merge_sort(a)) + diff --git a/Chapter03/Fibonacci_series.py b/Chapter03/Fibonacci_series.py new file mode 100644 index 0000000..99590f2 --- /dev/null +++ b/Chapter03/Fibonacci_series.py @@ -0,0 +1,8 @@ +def fib(n): + if n <= 1: + return 1 + else: + return fib(n-1) + fib(n-2) + +for i in range(5): + print(fib(i)) diff --git a/Chapter03/MatrixChain_multiplication.py b/Chapter03/MatrixChain_multiplication.py new file mode 100644 index 0000000..3c14e70 --- /dev/null +++ b/Chapter03/MatrixChain_multiplication.py @@ -0,0 +1,14 @@ +import sys +def MatrixChain(mat, i, j): + if i == j: + return 0 + minimum_computations = sys.maxsize + for k in range(i, j): + count = (MatrixChain(mat, i, k) + MatrixChain(mat, k+1, j)+ mat[i-1] * mat[k] * mat[j]) + if count < minimum_computations: + minimum_computations = count + return minimum_computations + + +matrix_sizes = [20, 30, 45, 50] +print("Minimum multiplications are", MatrixChain(matrix_sizes , 1, len(matrix_sizes)-1)) diff --git a/Chapter03/binary_search.py b/Chapter03/binary_search.py new file mode 100644 index 0000000..dac62d4 --- /dev/null +++ b/Chapter03/binary_search.py @@ -0,0 +1,16 @@ +def binary_search(arr, low, high, key): + while low <= high: + mid = int(low + (high - low)/2) + if arr[mid] == key: + return mid + elif arr[mid] < key: + low = mid + 1 + else: + high = mid - 1 + return -1 + + +arr = [ 2, 3, 4, 2, 10, 40] +x = 10 +result = binary_search(arr, 0, len(arr)-1, x) +print(result) diff --git a/Chapter03/dijkstra.py b/Chapter03/dijkstra.py new file mode 100644 index 0000000..29cab7a --- /dev/null +++ b/Chapter03/dijkstra.py @@ -0,0 +1,80 @@ + +def get_shortest_distance(table, vertex): + shortest_distance = table[vertex][DISTANCE] + return shortest_distance + +def set_shortest_distance(table, vertex, new_distance): + table[vertex][DISTANCE] = new_distance + +def set_previous_node(table, vertex, previous_node): + table[vertex][PREVIOUS_NODE] = previous_node + +def get_distance(graph, first_vertex, second_vertex): + return graph[first_vertex][second_vertex] + +def get_next_node(table, visited_nodes): + unvisited_nodes = list(set(table.keys()).difference(set(visited_nodes))) + assumed_min = table[unvisited_nodes[0]][DISTANCE] + min_vertex = unvisited_nodes[0] + for node in unvisited_nodes: + if table[node][DISTANCE] < assumed_min: + assumed_min = table[node][DISTANCE] + min_vertex = node + return min_vertex + +def find_shortest_path(graph, table, origin): + visited_nodes = [] + current_node = origin + starting_node = origin + while True: + adjacent_nodes = graph[current_node] + if set(adjacent_nodes).issubset(set(visited_nodes)): + # Nothing here to do. All adjacent nodes have been visited. + pass + else: + unvisited_nodes = set(adjacent_nodes).difference(set(visited_nodes)) + for vertex in unvisited_nodes: + distance_from_starting_node = get_shortest_distance(table, vertex) + if distance_from_starting_node == INFINITY and current_node == starting_node: + total_distance = get_distance(graph, vertex, current_node) + else: + total_distance = get_shortest_distance (table, + current_node) + get_distance(graph, current_node, vertex) + if total_distance < distance_from_starting_node: + set_shortest_distance(table, vertex, total_distance) + set_previous_node(table, vertex, current_node) + visited_nodes.append(current_node) + #print(visited_nodes) + if len(visited_nodes) == len(table.keys()): + break + current_node = get_next_node(table,visited_nodes) + return(table) + +graph = dict() +graph['A'] = {'B': 5, 'D': 9, 'E': 2} +graph['B'] = {'A': 5, 'C': 2} +graph['C'] = {'B': 2, 'D': 3} +graph['D'] = {'A': 9, 'F': 2, 'C': 3} +graph['E'] = {'A': 2, 'F': 3} +graph['F'] = {'E': 3, 'D': 2} + +table = dict() +table = { + 'A': [0, None], + 'B': [float("inf"), None], + 'C': [float("inf"), None], + 'D': [float("inf"), None], + 'E': [float("inf"), None], + 'F': [float("inf"), None], +} + + +DISTANCE = 0 +PREVIOUS_NODE = 1 +INFINITY = float('inf') + +shortest_distance_table = find_shortest_path(graph, table, 'A') + + +for k in sorted(shortest_distance_table): + print("{} - {}".format(k,shortest_distance_table[k])) diff --git a/Chapter03/dyna_fib.py b/Chapter03/dyna_fib.py new file mode 100644 index 0000000..5ba97f6 --- /dev/null +++ b/Chapter03/dyna_fib.py @@ -0,0 +1,13 @@ +def dyna_fib(n, lookup): + if n == 0: + return 0 + if n <= 2: + lookup[n] = 1 + if lookup[n] is None: + lookup[n] = dyna_fib(n-1, lookup) + dyna_fib(n-2, lookup) + return lookup[n] + +lookup = [None]*(1000) + +for i in range(6): + print(dyna_fib(i, lookup)) diff --git a/Chapter03/factorial.py b/Chapter03/factorial.py new file mode 100644 index 0000000..3469d23 --- /dev/null +++ b/Chapter03/factorial.py @@ -0,0 +1,10 @@ +def factorial(n): + # test for a base case + if n == 0: + return 1 + else: + return n*factorial(n-1) # make a calculation and a recursive call + + + +print(factorial(4)) diff --git a/Chapter03/merge_sort.py b/Chapter03/merge_sort.py new file mode 100644 index 0000000..e546be9 --- /dev/null +++ b/Chapter03/merge_sort.py @@ -0,0 +1,35 @@ +def merge_sort(unsorted_list): + if len(unsorted_list) == 1: + return unsorted_list + mid_point = int(len(unsorted_list)/2) + first_half = unsorted_list[:mid_point] + second_half = unsorted_list[mid_point:] + + half_a = merge_sort(first_half) + half_b = merge_sort(second_half) + + return merge(half_a, half_b) + + + +def merge(first_sublist, second_sublist): + i = j = 0 + merged_list = [] + while i < len(first_sublist) and j < len(second_sublist): + if first_sublist[i] < second_sublist[j]: + merged_list.append(first_sublist[i]) + i += 1 + else: + merged_list.append(second_sublist[j]) + j += 1 + while i < len(first_sublist): + merged_list.append(first_sublist[i]) + i += 1 + while j < len(second_sublist): + merged_list.append(second_sublist[j]) + j += 1 + return merged_list + + +a= [11, 12, 7, 41, 61, 13, 16, 14] +print(merge_sort(a)) diff --git a/Chapter04/CircularList.py b/Chapter04/CircularList.py new file mode 100644 index 0000000..16eed02 --- /dev/null +++ b/Chapter04/CircularList.py @@ -0,0 +1,103 @@ +class Node: + """ A Circular linked node. """ + def __init__(self, data=None): + self.data = data + self.next = None + + + + +class CircularList: + def __init__ (self): + self.tail = None + self.head = None + self.size = 0 + + def append(self, data): + node = Node(data) + if self.tail: + self.tail.next = node + self.tail = node + node.next = self.head + else: + self.head = node + self.tail = node + self.tail.next = self.tail + self.size += 1 + + def delete(self, data): + current = self.head + prev = self.head + while prev == current or prev != self.tail: + if current.data == data: + if current == self.head: + self.head = current.next + self.tail.next = self.head + else: + prev.next = current.next + self.size -= 1 + return + prev = current + current = current.next + + + def iter(self): + current = self.head + while current: + val = current.data + current = current.next + yield val + + + +words = CircularList() +words.append('eggs') +words.append('ham') +words.append('spam') + + +counter = 0 +for word in words.iter(): + print(word) + counter += 1 + if counter > 2: + break + + + +words.append('foo') +words.append('bar') +words.append('bim') +words.append('baz') +words.append('quux') +words.append('duux') + + + +print("Done iterating. Now we try to delete something that isn't there.") +words.delete('socks') +print('back to iterating') +counter = 0 +for item in words.iter(): + print(item) + counter += 1 + if counter > 2: + break + +print('Let us delete something that is there.') +words.delete('foo') +print('back to iterating') +counter = 0 +for item in words.iter(): + print(item) + counter += 1 + if counter > 2: + break + + + + + + + + diff --git a/Chapter04/SinglyLinkedList.py b/Chapter04/SinglyLinkedList.py new file mode 100644 index 0000000..01647cf --- /dev/null +++ b/Chapter04/SinglyLinkedList.py @@ -0,0 +1,34 @@ +class Node: + """ A singly-linked node. """ + def __init__(self, data=None): + self.data = data + self.next = None + + +class SinglyLinkedList: + def __init__ (self): + self.head = None + self.size = 0 + + def append(self, data): + # Encapsulate the data in a Node + node = Node(data) + if self.head is None: + self.head = node + else: + current = self.head + while current.next: + current = current.next + current.next = node + + + +words = SinglyLinkedList() +words.append('egg') +words.append('ham') +words.append('spam') + +current = words.head +while current: + print(current.data) + current = current.next diff --git a/Chapter04/append_at_any_location_singly_linkedlist.py b/Chapter04/append_at_any_location_singly_linkedlist.py new file mode 100644 index 0000000..b5e8f80 --- /dev/null +++ b/Chapter04/append_at_any_location_singly_linkedlist.py @@ -0,0 +1,69 @@ +class Node: + """ A singly-linked node. """ + def __init__(self, data=None): + self.data = data + self.next = None + + +class SinglyLinkedList: + def __init__ (self): + self.head = None + self.size = 0 + + def append(self, data): + # Encapsulate the data in a Node + node = Node(data) + if self.head is None: + self.head = node + else: + current = self.head + while current.next: + current = current.next + current.next = node + + def append_at_a_location(self, data, index): + current = self.head + prev = self.head + node = Node(data) + count = 1 + while current: + if count == 1: + node.next = current + self.head = node + print(count) + return + elif index == index: + node.next = current + prev.next = node + return + count += 1 + prev = current + current = current.next + if count < index: + print("The list has less number of elements") + + + + + +words = SinglyLinkedList() +words.append('egg') +words.append('ham') +words.append('spam') + +current = words.head +while current: + print(current.data) + current = current.next + + + +words.append_at_a_location('new', 2) + +current = words.head +while current: + print(current.data) + current = current.next + + + diff --git a/Chapter04/delete_operation_doubly_linkedlist.py b/Chapter04/delete_operation_doubly_linkedlist.py new file mode 100644 index 0000000..8bdf96d --- /dev/null +++ b/Chapter04/delete_operation_doubly_linkedlist.py @@ -0,0 +1,80 @@ +class Node: + def __init__ (self, data = None, next = None, prev = None): + self.data = data + self.next = next + self.prev = prev + +class DoublyLinkedList: + def __init__ (self): + self.head = None + self.tail = None + self.count = 0 + + def append(self, data): + #Append an item to the list. + new_node = Node(data, None, None) + if self.head is None: + self.head = new_node + self.tail = self.head + else: + new_node.prev = self.tail + self.tail.next = new_node + self.tail = new_node + self.count += 1 + + + + def delete(self, data): + # Delete a node from the list. + current = self.head + node_deleted = False + if current is None: #List is empty + print("List is empty") + elif current.data == data: #Item to be deleted is found at starting of list + self.head.prev = None + node_deleted = True + self.head = current.next + + elif self.tail.data == data: #Item to be deleted is found at the end of list. + self.tail = self.tail.prev + self.tail.next = None + node_deleted = True + + else: + while current: #search item to be deleted, and delete that node + if current.data == data: + current.prev.next = current.next + current.next.prev = current.prev + node_deleted = True + current = current.next + if node_deleted == False: #Item to be deleted is not found in the list + print("Item not found") + if node_deleted: + self.count -= 1 + + + + +#Code to create for a doubly linked list +words = DoublyLinkedList() +words.append('egg') +words.append('ham') +words.append('spam') +current = words.head +while current: + print(current.data) + current = current.next + + +words.delete('ham') +current = words.head +while current: + print(current.data) + current = current.next + + +words.delete('spam') +current = words.head +while current: + print(current.data) + current = current.next diff --git a/Chapter04/delete_operation_singly_linkedlist.py b/Chapter04/delete_operation_singly_linkedlist.py new file mode 100644 index 0000000..be5c04c --- /dev/null +++ b/Chapter04/delete_operation_singly_linkedlist.py @@ -0,0 +1,78 @@ +class Node: + """ A singly-linked node. """ + def __init__(self, data=None): + self.data = data + self.next = None + +class SinglyLinkedList: + def __init__ (self): + self.tail = None + self.size = 0 + + def append(self, data): + # Encapsulate the data in a Node + node = Node(data) + if self.tail is None: + self.tail = node + else: + current = self.tail + while current.next: + current = current.next + current.next = node + + def delete_first_node (self): + current = self.head + if self.head is None: + print("No data element to delete") + elif current == self.head: + self.head = current.next + + + def delete_last_node (self): + current = self.tail + prev = self.tail + while current: + if current.next is None: + prev.next = current.next + self.size -= 1 + prev = current + current = current.next + + + def delete(self, data): + current = self.tail + prev = self.tail + while current: + if current.data == data: + if current == self.tail: + self.tail = current.next + else: + prev.next = current.next + self.size -= 1 + return + prev = current + current = current.next + + +words = SinglyLinkedList() +words.append('egg') +words.append('ham') +words.append('spam') + + +words.delete_last_node() + +current = words.tail +while current: + print(current.data) + current = current.next + + + +words.delete('ham') +current = words.tail +while current: + print(current.data) + current = current.next + + diff --git a/Chapter04/doubly_linked_list.py b/Chapter04/doubly_linked_list.py new file mode 100644 index 0000000..44a9511 --- /dev/null +++ b/Chapter04/doubly_linked_list.py @@ -0,0 +1,69 @@ +class Node(object): + def __init__ (self, data = None, next = None, prev = None): + self.data = data + self.next = next + self.prev = prev + +class DoublyLinkedList(object): + def __init__ (self): + self.head = None + self.tail = None + self.count = 0 + + def append(self, data): + #Append an item to the list. + new_node = Node(data, None, None) + if self.head is None: + self.head = new_node + self.tail = self.head + else: + new_node.prev = self.tail + self.tail.next = new_node + self.tail = new_node + self.count += 1 + + + def append_at_start(self, data): + # Append an item at beginning to the list. + new_node = Node(data, None, None) + if self.head is None: + self.head = new_node + self.tail = self.head + else: + new_node.next = self.head + self.head.prev = new_node + self.head = new_node + self.count += 1 + + def append_at_a_location(self, data): + current = self.head + prev = self.head + new_node = Node(data, None, None) + while current: + if current.data == data: + new_node.prev = prev + new_node.next = current + prev.next = new_node + current.prev = new_node + self.count += 1 + prev = current + current = current.next + + + +words = DoublyLinkedList() +words.append('egg') +words.append('ham') +words.append('spam') + +current = words.head +while current: + print(current.data) + current = current.next + + +words.append_at_a_location('ham') +current = words.head +while current: + print(current.data) + current = current.next diff --git a/Chapter04/faster_append_singly_linked_list.py b/Chapter04/faster_append_singly_linked_list.py new file mode 100644 index 0000000..1d0b25b --- /dev/null +++ b/Chapter04/faster_append_singly_linked_list.py @@ -0,0 +1,32 @@ +class Node: + """ A singly-linked node. """ + def __init__(self, data=None): + self.data = data + self.next = None + + +class SinglyLinkedList: + def __init__ (self): + self.tail = None + self.head = None + self.size = 0 + + def append(self, data): + node = Node(data) + if self.tail: + self.tail.next = node + self.tail = node + else: + self.head = node + self.tail = node + + +words = SinglyLinkedList() +words.append('egg') +words.append('ham') +words.append('spam') + +current = words.head +while current: + print(current.data) + current = current.next diff --git a/Chapter04/list_traversal_singly_linklist.py b/Chapter04/list_traversal_singly_linklist.py new file mode 100644 index 0000000..5b6d259 --- /dev/null +++ b/Chapter04/list_traversal_singly_linklist.py @@ -0,0 +1,38 @@ +class Node: + """ A singly-linked node. """ + def __init__(self, data=None): + self.data = data + self.next = None + + +class SinglyLinkedList: + def __init__ (self): + self.head = None + self.size = 0 + + def append(self, data): + # Encapsulate the data in a Node + node = Node(data) + if self.head is None: + self.head = node + else: + current = self.head + while current.next: + current = current.next + current.next = node + + def iter(self): + current = self.head + while current: + val = current.data + current = current.next + yield val + + +words = SinglyLinkedList() +words.append('egg') +words.append('ham') +words.append('spam') + +for word in words.iter(): + print(word) diff --git a/Chapter05/.DS_Store b/Chapter05/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..fd3fa0cfdd9bc7bc3cf4cdc38227cb4c5af4fbc9 GIT binary patch literal 6148 zcmeHK!AiqG5Pee%R=gA}D4ufkBzX1`N<9c(q#sa|RzzBCwe6v|T>J-r!SC|}^v%vv z+B6k=5s{fN`!7OxfSn2;!@^7v9?=Ws);cbP5 z^*ldjQ(nKF&zv>UdOfg08D4m0SX8a6mX-4G*2Nic2Alyhz&%@~acJnRGvEw314{<< z`;br-(};y(_;j!dM*w1-<{<3r@1Vvc5z~l;A)iphLWveC@rWT7PJ0sl(ujqjg+t=u zL*mF1Pbd;bXZ|F(LsCO;odIWHoq;{OZR-Aiwf+3R9^`k 1: + self.head = self.head.next + self.head.prev = None + elif self.count <1: + print("Queue is empty") + self.count -= 1 + + + +q= Queue() +q.enqueue(4) +q.enqueue('dog') +q.enqueue('True') + +print(q.count) + +q.dequeue() + +print(q.count) diff --git a/Chapter05/List_based_queue.py b/Chapter05/List_based_queue.py new file mode 100644 index 0000000..a9f72e2 --- /dev/null +++ b/Chapter05/List_based_queue.py @@ -0,0 +1,34 @@ +class ListQueue: + def __init__(self): + self.items = [] + self.front = self.rear = 0 + self.size = 3 # maximum capacity of the queue + + def enqueue(self, data): + if self.size == self.rear: + print("\nQueue is full") + else: + self.items.append(data) + self.rear += 1 + + + + def dequeue(self): + if self.front == self.rear: + print("Queue is empty") + else: + data = self.items.pop(0) # delete the item from front end of the queue + self.rear -= 1 + return data + + + +q= ListQueue() +q.enqueue(4) +q.enqueue('dog') +q.enqueue('cat') +q.enqueue('monday') + + +a= q.size1() +print(a) diff --git a/Chapter05/Queue_application.py b/Chapter05/Queue_application.py new file mode 100644 index 0000000..3526aad --- /dev/null +++ b/Chapter05/Queue_application.py @@ -0,0 +1,98 @@ +from random import randint + + + +class Node(object): + """ A Doubly-linked lists' node. """ + def __init__(self, data=None, next=None, prev=None): + self.data = data + self.next = next + self.prev = prev + + +class Queue(object): + """ A doubly-linked list. """ + def __init__(self): + self.head = None + self.tail = None + self.count = 0 + + def enqueue(self, data): + """ Append an item to the list. """ + + new_node = Node(data, None, None) + if self.head is None: + self.head = new_node + self.tail = self.head + else: + new_node.prev = self.tail + self.tail.next = new_node + self.tail = new_node + + self.count += 1 + + def dequeue(self): + """ Remove elements from the front of the list""" + current = self.head + if self.count == 1: + self.count -= 1 + self.head = None + self.tail = None + elif self.count > 1: + self.head = self.head.next + self.head.prev = None + self.count -= 1 + return current + + + +queue = Queue() + +import time +start_time = time.time() +for i in range(100000): + queue.enqueue(i) +for i in range(100000): + queue.dequeue() +print("--- %s seconds ---" % (time.time() - start_time)) + + +class Track: + + def __init__(self, title=None): + self.title = title + self.length = randint(5, 10) + + + +track1 = Track("white whistle") +track2 = Track("butter butter") +print(track1.length) +print(track2.length) + +import time +class MediaPlayerQueue(Queue): + + + def add_track(self, track): + self.enqueue(track) + + def play(self): + while self.count > 0: + current_track_node = self.dequeue() + print("Now playing {}".format(current_track_node.data.title)) + time.sleep(current_track_node.data.length) + +track1 = Track("white whistle") +track2 = Track("butter butter") +track3 = Track("Oh black star") +track4 = Track("Watch that chicken") +track5 = Track("Don't go") + +media_player = MediaPlayerQueue() +media_player.add_track(track1) +media_player.add_track(track2) +media_player.add_track(track3) +media_player.add_track(track4) +media_player.add_track(track5) +media_player.play() diff --git a/Chapter05/Stack.py b/Chapter05/Stack.py new file mode 100644 index 0000000..0c1db3d --- /dev/null +++ b/Chapter05/Stack.py @@ -0,0 +1,68 @@ +class Node: + def __init__(self, data=None): + self.data = data + self.next = None + + + +class Stack: + def __init__(self): + self.top = None + self.size = 0 + + def push(self, data): + # create a new node + node = Node(data) + if self.top: + node.next = self.top + self.top = node + else: + self.top = node + self.size += 1 + + + + def pop(self): + if self.top: + data = self.top.data + self.size -= 1 + if self.top.next: #check if there is more than one node. + self.top = self.top.next + else: + self.top = None + return data + else: + print("Stack is empty") + + + def peek(self): + if self.top: + return self.top.data + else: + print("Stack is empty") + + + +words = stack() +words.push('4') +words.push('5') +words.push('6') +words.push('7') + +#print the stack elements. +current = words.top +while current: + print(current.data) + current = current.next + + +words.pop() + +current = words.top +while current: + print(current.data) + current = current.next + + +words.peek() + diff --git a/Chapter05/Stack_application.py b/Chapter05/Stack_application.py new file mode 100644 index 0000000..afc3006 --- /dev/null +++ b/Chapter05/Stack_application.py @@ -0,0 +1,68 @@ +class Node: + def __init__(self, data=None): + self.data = data + self.next = None + + + +class stack: + def __init__(self): + self.top = None + self.size = 0 + + def push(self, data): + # create a new node + node = Node(data) + if self.top: + node.next = self.top + self.top = node + else: + self.top = node + self.size += 1 + + + + def pop(self): + if self.top: + data = self.top.data + self.size -= 1 + if self.top.next: #check if there is more than one node. + self.top = self.top.next + else: + self.top = None + return data + else: + print("Stack is empty") + + + def peek(self): + if self.top: + return self.top.data + else: + print("Stack is empty") + + + +words = stack() +words.push('4') +words.push('5') +words.push('6') +words.push('7') + +#print the stack elements. +current = words.top +while current: + print(current.data) + current = current.next + + +words.pop() + +current = words.top +while current: + print(current.data) + current = current.next + + +words.peek() + diff --git a/Chapter05/Stack_based_queue.py b/Chapter05/Stack_based_queue.py new file mode 100644 index 0000000..5591d47 --- /dev/null +++ b/Chapter05/Stack_based_queue.py @@ -0,0 +1,31 @@ +class Queue: + def __init__(self): + self.Stack1 = [] + self.Stack2 = [] + + def enqueue(self, data): + self.Stack1.append(data) + + + + def dequeue(self): + if not self.Stack2: + while self.Stack1: + self.Stack2.append(self.Stack1.pop()) + if not self.Stack2: + print("No element to dequeue") + return + return self.Stack2.pop() + + +queue = Queue() +queue.enqueue(5) +queue.enqueue(6) +queue.enqueue(7) +print(queue.Stack1) + +queue.dequeue() +print(queue.Stack1) +print(queue.Stack2) +queue.dequeue() +print(queue.Stack2) diff --git a/Chapter05/Stack_using_array.py b/Chapter05/Stack_using_array.py new file mode 100644 index 0000000..20ad138 --- /dev/null +++ b/Chapter05/Stack_using_array.py @@ -0,0 +1,51 @@ +size = 3 +data = [0]*(size) #Initialize the stack +top = -1 + +def push(x): + global top + if top >= size-1: + print("Stack Overflow") + else: + top = top + 1 + data[top] = x + + +def pop(): + global top + if top == -1: + print("Stack Underflow") + else: + top = top-1 + data[top] = 0 + return data[top+1] + + +def peek(): + global top + if top == -1: + print("Stack is empty") + else: + print(data[top]) + + + + +push('egg') +push('ham') +push('spam') +push('new') +push('new2') + +print(data[0 : top + 1]) + +print(data[0 : top + 1]) +pop() +pop() +pop() +pop() +print(data[0:top+1]) + +peek() + +print(data[0:top+1]) diff --git a/Chapter06/binary_search_tree.py b/Chapter06/binary_search_tree.py new file mode 100644 index 0000000..1487152 --- /dev/null +++ b/Chapter06/binary_search_tree.py @@ -0,0 +1,156 @@ +class Node: + def __init__(self, data): + self.data = data + self.right_child = None + self.left_child = None + +class Tree: + def __init__(self): + self.root_node = None + + def insert(self, data): + node = Node(data) + if self.root_node is None: + self.root_node = node + return + else: + current = self.root_node + parent = None + while True: + parent = current + if node.data < parent.data: + current = current.left_child + if current is None: + parent.left_child = node + return + else: + current = current.right_child + if current is None: + parent.right_child = node + return + + def inorder(self): + current = self.root_node + if current is None: + return + inorder(current.left_child) + print(current.data) + inorder(current.right_child) + + + def get_node_with_parent(self, data): + parent = None + current = self.root_node + if current is None: + return (parent, None) + while True: + if current.data == data: + return (parent, current) + elif current.data > data: + parent = current + current = current.left_child + else: + parent = current + current = current.right_child + return (parent, current) + + + def remove(self, data): + parent, node = self.get_node_with_parent(data) + + if parent is None and node is None: + return False + + # Get children count + children_count = 0 + + if node.left_child and node.right_child: + children_count = 2 + elif (node.left_child is None) and (node.right_child is None): + children_count = 0 + else: + children_count = 1 + + if children_count == 0: + if parent: + if parent.right_child is node: + parent.right_child = None + else: + parent.left_child = None + else: + self.root_node = None + elif children_count == 1: + next_node = None + if node.left_child: + next_node = node.left_child + else: + next_node = node.right_child + + if parent: + if parent.left_child is node: + parent.left_child = next_node + else: + parent.right_child = next_node + else: + self.root_node = next_node + else: + parent_of_leftmost_node = node + leftmost_node = node.right_child + while leftmost_node.left_child: + parent_of_leftmost_node = leftmost_node + leftmost_node = leftmost_node.left_child + node.data = leftmost_node.data + + if parent_of_leftmost_node.left_child == leftmost_node: + parent_of_leftmost_node.left_child = leftmost_node.right_child + else: + parent_of_leftmost_node.right_child = leftmost_node.right_child + + + + def search(self, data): + current = self.root_node + while True: + if current is None: + return None + elif current.data is data: + return data + elif current.data > data: + current = current.left_child + else: + current = current.right_child + + + def find_min(self): + current = self.root_node + while current.left_child: + current = current.left_child + return current.data + + + def find_max(self): + current = self.root_node + while current.right_child: + current = current.right_child + return current.data + + + +tree = Tree() +tree.insert(5) +tree.insert(2) +tree.insert(7) +tree.insert(9) +tree.insert(1) + +tree.inorder() + +for i in range(1, 10): + found = tree.search(i) + print("{}: {}".format(i, found)) + + +print(tree.find_min()) + +print(tree.find_max()) + diff --git a/Chapter06/level_order_traversal.py b/Chapter06/level_order_traversal.py new file mode 100644 index 0000000..e14a551 --- /dev/null +++ b/Chapter06/level_order_traversal.py @@ -0,0 +1,35 @@ +from collections import deque + +class Node: + def __init__(self, data): + self.data = data + self.right_child = None + self.left_child = None + + +n1 = Node("root node") +n2 = Node("left child node") +n3 = Node("right child node") +n4 = Node("left grandchild node") + +n1.left_child = n2 +n1.right_child = n3 +n2.left_child = n4 + + + +def level_order_traversal(root_node): + list_of_nodes = [] + traversal_queue = deque([root_node]) + while len(traversal_queue) > 0: + node = traversal_queue.popleft() + list_of_nodes.append(node.data) + if node.left_child: + traversal_queue.append(node.left_child) + if node.right_child: + traversal_queue.append(node.right_child) + return list_of_nodes + + + +print(level_order_traversal(n1)) diff --git a/Chapter06/reverse_polish_expression.py b/Chapter06/reverse_polish_expression.py new file mode 100644 index 0000000..e01080d --- /dev/null +++ b/Chapter06/reverse_polish_expression.py @@ -0,0 +1,46 @@ + +class Stack: + def __init__(self): + self.elements = [] + + def push(self, item): + self.elements.append(item) + + def pop(self): + return self.elements.pop() + + +class TreeNode: + def __init__(self, data=None): + self.data = data + self.right = None + self.left = None + +def calc(node): + if node.data == "+": + return calc(node.left) + calc(node.right) + elif node.data == "-": + return calc(node.left) - calc(node.right) + elif node.data == "*": + return calc(node.left) * calc(node.right) + elif node.data == "/": + return calc(node.left) / calc(node.right) + else: + return node.data + +expr = "4 5 + 5 3 - *".split() + +stack = Stack() + +for term in expr: + if term in "+-*/": + node = TreeNode(term) + node.right = stack.pop() + node.left = stack.pop() + else: + node = TreeNode(int(term)) + stack.push(node) + +root = stack.pop() +result = calc(root) +print(result) diff --git a/Chapter06/tree_traversal.py b/Chapter06/tree_traversal.py new file mode 100644 index 0000000..cf3d41d --- /dev/null +++ b/Chapter06/tree_traversal.py @@ -0,0 +1,53 @@ +class Node: + def __init__(self, data): + self.data = data + self.right_child = None + self.left_child = None + + +n1 = Node("root node") +n2 = Node("left child node") +n3 = Node("right child node") +n4 = Node("left grandchild node") +n1.left_child = n2 +n1.right_child = n3 +n2.left_child = n4 + +current = n1 +while current: + print(current.data) + current = current.left_child + +print("\n" ) + +def inorder(root_node): + current = root_node + if current is None: + return + inorder(current.left_child) + print(current.data) + inorder(current.right_child) + +def preorder(root_node): + current = root_node + if current is None: + return + print(current.data) + preorder(current.left_child) + preorder(current.right_child) + + +def postorder(root_node): + current = root_node + if current is None: + return + postorder(current.left_child) + postorder(current.right_child) + print(current.data) + + +inorder( n1) +print("\n" ) +preorder( n1) +print("\n" ) +postorder(n1) diff --git a/Chapter07/.DS_Store b/Chapter07/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..2167c4063aad94f11befd37f53f64dbf216809ab GIT binary patch literal 6148 zcmeHKJxc>Y5PhQo16o`mXt|}8V4da&5wsM4fEpDH1TI8Vq`Sr+} zUZc$z>!n#aDPx_nbz~1soJw@6-)frnyr$h4NL-Ne;j~B7oIexNqNbMM9 zC=d#C71;J_rRV=Cf0^PVze|Z)C=d$#F$H8WxtxsoQTc5B^m%&LCi*p9P4ij}XpB3T j09JG#IkZmiPZ~3?&e%HYDB5mxVq64FkSIcdA5h>8uhUB? literal 0 HcmV?d00001 diff --git a/Chapter07/heap.py b/Chapter07/heap.py new file mode 100644 index 0000000..4d9b8f2 --- /dev/null +++ b/Chapter07/heap.py @@ -0,0 +1,73 @@ +class MinHeap: + def __init__(self): + self.heap = [0] + self.size = 0 + + def arrange(self, k): + while k // 2 > 0: + if self.heap[k] < self.heap[k//2]: + self.heap[k], self.heap[k//2] = self.heap[k//2], self.heap[k] + k //= 2 + + def insert(self, item): + self.heap.append(item) + self.size += 1 + self.arrange(self.size) + + def sink(self, k): + while k * 2 <= self.size: + mc = self.minchild(k) + if self.heap[k] > self.heap[mc]: + self.heap[k], self.heap[mc] = self.heap[mc], self.heap[k] + k = mc + + def minchild(self, k): + if k * 2 + 1 > self.size: + return k * 2 + elif self.heap[k*2] < self.heap[k*2+1]: + return k * 2 + else: + return k * 2 + 1 + + def delete_at_root(self): + item = self.heap[1] + self.heap[1] = self.heap[self.size] + self.size -= 1 + self.heap.pop() + self.sink(1) + return item + + + def delete_at_location(self, location): + item = self.heap[location] + self.heap[location] = self.heap[self.size] + self.size -= 1 + self.heap.pop() + self.sink(location) + return item + + + +h = MinHeap() +for i in ( 4, 8, 7, 2, 9, 10, 5, 1, 3, 6): + h.insert(i) + +print(h.heap) + +n = h.delete_at_root() +print(n) +print(h.heap) + +h = MinHeap() +for i in (4, 8, 7, 2, 9, 10, 5, 1, 3, 6): + h.insert(i) +print(h.heap) + +n = h.delete_at_location(2) +print(n) +print(h.heap) + + + + + diff --git a/Chapter07/heap_sort.py b/Chapter07/heap_sort.py new file mode 100644 index 0000000..085f18a --- /dev/null +++ b/Chapter07/heap_sort.py @@ -0,0 +1,90 @@ +class minHeap: + def __init__(self): + self.heap = [0] + self.size = 0 + + def arrange(self, k): + while k // 2 > 0: + if self.heap[k] < self.heap[k//2]: + self.heap[k], self.heap[k//2] = self.heap[k//2], self.heap[k] + k //= 2 + + def insert(self, item): + self.heap.append(item) + self.size += 1 + self.arrange(self.size) + + def sink(self, k): + while k * 2 <= self.size: + mc = self.minchild(k) + if self.heap[k] > self.heap[mc]: + self.heap[k], self.heap[mc] = self.heap[mc], self.heap[k] + k = mc + + def minchild(self, k): + if k * 2 + 1 > self.size: + return k * 2 + elif self.heap[k*2] < self.heap[k*2+1]: + return k * 2 + else: + return k * 2 + 1 + + def delete_at_root(self): + item = self.heap[1] + self.heap[1] = self.heap[self.size] + self.size -= 1 + self.heap.pop() + self.sink(1) + return item + + + def delete_at_location(self, location): + item = self.heap[location] + self.heap[location] = self.heap[self.size] + self.size -= 1 + self.heap.pop() + self.sink(location) + return item + + def heap_sort(self): + sorted_list = [] + for node in range(self.size): + n = self.pop() + sorted_list.append(n) + return sorted_list + + + +h = minHeap() +for i in ( 4, 8, 7, 2, 9, 10, 5, 1, 3, 6): + h.insert(i) + +print(h.heap) + + +h = minHeap() +unsorted_list = [4, 8, 7, 2, 9, 10, 5, 1, 3, 6] + + +for i in unsorted_list: + h.insert(i) + +print("Unsorted list: {}".format(unsorted_list)) + + + + + +h = minHeap() +unsorted_list = [4, 8, 7, 2, 9, 10, 5, 1, 3, 6] + + +for i in unsorted_list: + h.insert(i) + +print("Unsorted list: {}".format(unsorted_list)) + + +print("Sorted list: {}".format(h.heap_sort())) + + diff --git a/Chapter07/priorityQueue.py b/Chapter07/priorityQueue.py new file mode 100644 index 0000000..6508c2f --- /dev/null +++ b/Chapter07/priorityQueue.py @@ -0,0 +1,57 @@ +# class for Node with data and priority +class Node: + def __init__(self, info, priority): + self.info = info + self.priority = priority + +# class for Priority queue +class PriorityQueue: + def __init__(self): + self.queue = [] + + def size(self): + return (len(self.queue)) + + def show(self): + for x in self.queue: + print(str(x.info)+ " - "+ str(x.priority)) + + + def insert(self, node): + if len(self.queue) == 0: + # add the new node + self.queue.append(node) + else: + # traverse the queue to find the right place for new node + for x in range(0, len(self.queue)): + # if the priority of new node is greater + if node.priority >= self.queue[x].priority: + # if we have traversed the complete queue + if x == (len(self.queue)-1): + # add new node at the end + self.queue.insert(x+1, node) + else: + continue + else: + self.queue.insert(x, node) + return True + + def delete(self): + # remove the first node from the queue + x = self.queue.pop(0) + print("Deleted data with the given priority-", x.info, x.priority) + return x + + + +p = PriorityQueue() +p.insert(Node("Cat", 13)) +p.insert(Node("Bat", 2)) +p.insert(Node("Rat", 1)) +p.insert(Node("Ant", 26)) +p.insert(Node("Lion", 25)) +p.show() + + +p.delete() +p.show() diff --git a/Chapter07/priorityQueueHeap.py b/Chapter07/priorityQueueHeap.py new file mode 100644 index 0000000..ff47587 --- /dev/null +++ b/Chapter07/priorityQueueHeap.py @@ -0,0 +1,59 @@ +class PriorityQueueHeap: + def __init__(self): + self.heap = [()] + self.size = 0 + + def arrange(self, k): + while k // 2 > 0: + if self.heap[k][0] < self.heap[k//2][0]: + self.heap[k], self.heap[k//2] = self.heap[k//2], self.heap[k] + k //= 2 + + def insert(self,priority, item): + self.heap.append((priority, item)) + self.size += 1 + self.arrange(self.size) + + def sink(self, k): + while k * 2 <= self.size: + mc = self.minchild(k) + if self.heap[k][0] > self.heap[mc][0]: + self.heap[k], self.heap[mc] = self.heap[mc], self.heap[k] + k = mc + + def minchild(self, k): + if k * 2 + 1 > self.size: + return k * 2 + elif self.heap[k*2][0] < self.heap[k*2+1][0]: + return k * 2 + else: + return k * 2 + 1 + + def delete_at_root(self): + item = self.heap[1][1] + self.heap[1] = self.heap[self.size] + self.size -= 1 + self.heap.pop() + self.sink(1) + return item + + + +h = PriorityQueueHeap() +h.insert(2, "Bat") +h.insert(13,"Cat") +h.insert(18, "Rat") +h.insert(26, "Ant") +h.insert(3, "Lion") +h.insert(4, "Bear") + +h.heap + + +for i in range(h.size): + n = h.delete_at_root() + print(n) + print(h.heap) + + + diff --git a/Chapter08/.DS_Store b/Chapter08/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..3bfb2fc00c7b2a389408eb51bce370b4641da4cc GIT binary patch literal 6148 zcmeHKJxc^Z41Lin4z;*Ow4BmPu(nx_v#|CDsCSAAizlds-TobarM{PphqtbUjff;L zdD%=d9}jkB0>GxvS4Y4Ez?e;FG6qEM!LE%Oyh$`4;|}+@!66>-GBD6zbZPBdxWy$N zsXwj%v|TRd?Q+h3k#o#;@a94b*jeQ~F?Ws@*Rk(j-fJ&!cOdT^3-@aFZ&zS@y^*wv zlw=?oNCuLDWZ>rv@XnTuw*ylr1Ia)#uwp>xLtzs(6}vz`I;gw^AdcvEp{?h#a!SRf zVi(9BibX0hQmvL47U}et8rM|p0wWz(iw~2n?!M)3<~YFM*u%`j_iA9^cUHT XYbthu8by9jC+0)I2}zX<`~m~-Uk5t* literal 0 HcmV?d00001 diff --git a/Chapter08/hashing.py b/Chapter08/hashing.py new file mode 100644 index 0000000..3b49cf3 --- /dev/null +++ b/Chapter08/hashing.py @@ -0,0 +1,10 @@ +def hash(data): + counter = 1 + sum = 0 + for d in data: + sum += counter * ord(d) + return sum % 256 + +items = ['foo', 'bar', 'bim', 'baz', 'quux', 'duux', 'gnn'] +for item in items: + print("{}: {}".format(item, hash(item))) diff --git a/Chapter08/hashtable.py b/Chapter08/hashtable.py new file mode 100644 index 0000000..2429567 --- /dev/null +++ b/Chapter08/hashtable.py @@ -0,0 +1,160 @@ +class HashItem: + def __init__(self, key, value): + self.key = key + self.value = value + + +class HashTable: + def __init__(self): + self.size = 256 + self.slots = [None for i in range(self.size)] + self.count = 0 + self.MAXLOADFACTOR = 0.65 + + + def check_growth(self): + loadfactor = self.count / self.size + if loadfactor > self.MAXLOADFACTOR: + print("Load factor before growing the hash table", self.count / self.size ) + self.growth() + print("Load factor after growing the hash table", self.count / self.size ) + + + def growth(self): + New_Hash_Table = HashTable() + New_Hash_Table.size = 2 * self.size + New_Hash_Table.slots = [None for i in range(New_Hash_Table.size)] + + for i in range(self.size): + if self.slots[i] != None: + New_Hash_Table.put(self.slots[i].key, self.slots[i].value) + + self.size = New_Hash_Table.size + self.slots = New_Hash_Table.slots + + + def _hash(self, key): + mult = 1 + hv = 0 + for ch in key: + hv += mult * ord(ch) + mult += 1 + return hv % self.size + + def put(self, key, value): + item = HashItem(key, value) + h = self._hash(key) + + while self.slots[h] != None: + if self.slots[h].key == key: + break + h = (h + 1) % self.size + if self.slots[h] == None: + self.count += 1 + self.slots[h] = item + self.check_growth() + + def get(self, key): + h = self._hash(key) + while self.slots[h] != None: + if self.slots[h].key == key: + return self.slots[h].value + h = (h+ 1) % self.size + return None + + def put_quadratic(self, key, value): + item = HashItem(key, value) + h = self._hash(key) + j = 1 + while self.slots[h] != None: + if self.slots[h].key == key: + break + h = (h + j*j) % self.size + j = j+1 + if self.slots[h] == None: + self.count += 1 + self.slots[h] = item + self.check_growth() + + + def get_quadratic(self, key): + h = self._hash(key) + j = 1 + while self.slots[h] != None: + if self.slots[h].key == key: + return self.slots[h].value + h = (h+ j*j) % self.size + j = j + 1 + return None + + + def h2(self, key): + mult = 1 + hv = 0 + for ch in key: + hv += mult * ord(ch) + mult += 1 + return hv + + + def put_doubleHashing(self, key, value): + item = HashItem(key, value) + h = self._hash(key) + j = 1 + while self.slots[h] != None: + if self.slots[h].key == key: + break + h = (h + j * (self.prime_num - (self.h2(key) % self.prime_num))) % self.size + j = j+1 + if self.slots[h] == None: + self.count += 1 + self.slots[h] = item + self.check_growth() + + def get_doubleHashing(self, key): + h = self._hash(key) + j = 1 + while self.slots[h] != None: + if self.slots[h].key == key: + return self.slots[h].value + h = (h + j * (self.prime_num - (self.h2(key) % self.prime_num))) % self.size + j = j + 1 + return None + + + + + def __setitem__(self, key, value): + self.put(key, value) + + def __getitem__(self, key): + return self.get(key) + + +ht = HashTable() +ht.put("good", "eggs") +ht.put("better", "ham") +ht.put("best", "spam") +ht.put("ad", "do not") +ht.put("ga", "collide") + +for key in ("good", "better", "best", "worst", "ad", "ga"): + v = ht.get(key) + print(v) + + + + +ht = HashTable() +ht["good"] = "eggs" +ht["better"] = "ham" +ht["best"] = "spam" +ht["ad"] = "do not" +ht["ga"] = "collide" +ht["data"] = "value" + +for key in ("good", "better", "best", "worst", "ad", "ga"): + v = ht[key] + print(v) + +print("The number of elements is: {}".format(ht.count)) diff --git a/Chapter08/hashtable_chaining.py b/Chapter08/hashtable_chaining.py new file mode 100644 index 0000000..96dcc12 --- /dev/null +++ b/Chapter08/hashtable_chaining.py @@ -0,0 +1,102 @@ +class HashItem: + def __init__(self, key, value): + self.key = key + self.value = value + +class Node: + def __init__(self, key=None, value=None): + self.key = key + self.value = value + self.next = None + + +class SinglyLinkedList: + def __init__ (self): + self.tail = None + self.head = None + + def append(self, key, value): + node = Node(key, value) + if self.tail: + self.tail.next = node + self.tail = node + else: + self.head = node + self.tail = node + + def traverse(self): + current = self.head + while current: + print("\"", current.key, "--", current.value, "\"") + current = current.next + + def search(self, key): + current = self.head + while current: + if current.key == key: + print("list ",current.key, current.value) + return True + current = current.next + return False + + + +class HashTable: + def __init__(self): + self.size = 6 + self.slots = [None for i in range(self.size)] + for x in range(self.size) : + self.slots[x] = SinglyLinkedList() + + + def _hash(self, key): + mult = 1 + hv = 0 + for ch in key: + hv += mult * ord(ch) + mult += 1 + return hv % self.size + + def put(self, key, value): + #self.resize() + node = Node(key, value) + h = self._hash(key) + self.slots[h].append(key, value) + + + def get(self, key): + h = self._hash(key) + v = self.slots[h].search(key) + + + def printHashTable(self) : + print("Hash table is :- \n") + print("Index \t\tValues\n") + for x in range(self.size) : + print(x,end="\t\n") + self.slots[x].traverse() + + + + +ht = HashTable() +ht.put("good", "eggs") +ht.put("better", "ham") +ht.put("best", "spam") +ht.put("ad", "do not") +ht.put("ga", "collide") +ht.put("awd", "do not") + + + + +v = ht.get("ad") +print(v) + + +for key in ("good", "better", "best", "worst", "ad", "ga"): + v = ht.get(key) + print(v) + + +ht.printHashTable() diff --git a/Chapter09/breadth_first_search.py b/Chapter09/breadth_first_search.py new file mode 100644 index 0000000..28165c9 --- /dev/null +++ b/Chapter09/breadth_first_search.py @@ -0,0 +1,33 @@ +graph = dict() +graph['A'] = ['B', 'G', 'D'] +graph['B'] = ['A', 'F', 'E'] +graph['C'] = ['F', 'H'] +graph['D'] = ['F', 'A'] +graph['E'] = ['B', 'G'] +graph['F'] = ['B', 'D', 'C'] +graph['G'] = ['A', 'E'] +graph['H'] = ['C'] + + +from collections import deque + +def breadth_first_search(graph, root): + visited_vertices = list() + graph_queue = deque([root]) + visited_vertices.append(root) + node = root + + while len(graph_queue) > 0: + node = graph_queue.popleft() + adj_nodes = graph[node] + + remaining_elements = set(adj_nodes).difference(set(visited_vertices)) + if len(remaining_elements) > 0: + for elem in sorted(remaining_elements): + visited_vertices.append(elem) + graph_queue.append(elem) + + return visited_vertices + + +print(breadth_first_search(graph, 'A')) diff --git a/Chapter09/depth_first_search.py b/Chapter09/depth_first_search.py new file mode 100644 index 0000000..1894b2a --- /dev/null +++ b/Chapter09/depth_first_search.py @@ -0,0 +1,36 @@ +graph = dict() +graph['A'] = ['B', 'S'] +graph['B'] = ['A'] +graph['S'] = ['A','G','C'] +graph['D'] = ['C'] +graph['G'] = ['S','F','H'] +graph['H'] = ['G','E'] +graph['E'] = ['C','H'] +graph['F'] = ['C','G'] +graph['C'] = ['D','S','E','F'] + +def depth_first_search(graph, root): + visited_vertices = list() + graph_stack = list() + graph_stack.append(root) + node = root + while graph_stack: + if node not in visited_vertices: + visited_vertices.append(node) + adj_nodes = graph[node] + if set(adj_nodes).issubset(set(visited_vertices)): + graph_stack.pop() + if len(graph_stack) > 0: + node = graph_stack[-1] + continue + else: + remaining_elements = set(adj_nodes).difference(set(visited_vertices)) + + first_adj_node = sorted(remaining_elements)[0] + graph_stack.append(first_adj_node) + node = first_adj_node + return visited_vertices + + + +print(depth_first_search(graph, 'A')) diff --git a/Chapter09/graph.py b/Chapter09/graph.py new file mode 100644 index 0000000..58cc88b --- /dev/null +++ b/Chapter09/graph.py @@ -0,0 +1,31 @@ +graph = dict() +graph['A'] = ['B', 'C'] +graph['B'] = ['E','C', 'A'] +graph['C'] = ['A', 'B', 'E','F'] +graph['E'] = ['B', 'C'] +graph['F'] = ['C'] + +matrix_elements = sorted(graph.keys()) +cols = rows = len(matrix_elements) + +adjacency_matrix = [[0 for x in range(rows)] for y in range(cols)] + +edges_list = [] + + +for key in matrix_elements: + for neighbor in graph[key]: + edges_list.append((key,neighbor)) + + +print(edges_list) + + + +for edge in edges_list: + index_of_first_vertex = matrix_elements.index(edge[0]) + index_of_second_vertex = matrix_elements.index(edge[1]) + adjacency_matrix[index_of_first_vertex][index_of_second_vertex] = 1 + + +print(adjacency_matrix) diff --git a/Chapter10/.DS_Store b/Chapter10/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..eb64c3e4bd6d6eb4e645f3e041a0dbdff88f1de6 GIT binary patch literal 6148 zcmeHKJx{|h5PdF{s6awppr}(uCM0H-s44?9VlMrXC<+9nEuvc%ehj~cAHxrTclNbv z(^T0Is_vxob8O$s`9-#40IoA1T>(u14Z2|ch((D>zxbBbwB?ZKJV%BFdYEF2{?=$~ zFa=D3|E7Sf-8Kf8;Du{;ef?$_;*qO)f*IFy#@-q0Z>(S96^q*>9S)LozBB)i&IfvLqviI;f^U!t=U z=H>pilg+gXY$tf)T%O5P8H>+C?3wPCOSMyGH1c_ki9KdE;fPt8=I*1w)y6&ZFJlnB z=~SNAWq` a8~Y-u5M#wWAX{kmBj9DQ!W8&Z1%3gJE0X2_ literal 0 HcmV?d00001 diff --git a/Chapter10/Unordered_linear_search.py b/Chapter10/Unordered_linear_search.py new file mode 100644 index 0000000..0d400b4 --- /dev/null +++ b/Chapter10/Unordered_linear_search.py @@ -0,0 +1,33 @@ + +def search(unordered_list, term): + for i, item in enumerate(unordered_list): + if term == unordered_list[i]: + return i + return None + + + +list1 = [60, 1, 88, 10, 11, 600] + +search_term = 10 +index_position = search(list1, search_term) +print(index_position) + + + +list2 = ['packt', 'publish', 'data'] +search_term2 = 'data' +index_position2 = search(list2, search_term2) +print(index_position2) + + +if index_position is None: + print("{} not found".format(search_term)) +else: + print("{} found at position {}".format(search_term, index_position)) + + +if index_position2 is None: + print("{} not found".format(search_term2)) +else: + print("{} found at position {}".format(search_term2, index_position2)) diff --git a/Chapter10/binary_search_iterative.py b/Chapter10/binary_search_iterative.py new file mode 100644 index 0000000..718d4d4 --- /dev/null +++ b/Chapter10/binary_search_iterative.py @@ -0,0 +1,44 @@ +def binary_search_iterative(ordered_list, term): + + size_of_list = len(ordered_list) - 1 + index_of_first_element = 0 + index_of_last_element = size_of_list + while index_of_first_element <= index_of_last_element: + mid_point = (index_of_first_element + index_of_last_element)//2 + if ordered_list[mid_point] == term: + return mid_point + if term > ordered_list[mid_point]: + index_of_first_element = mid_point + 1 + else: + index_of_last_element = mid_point - 1 + if index_of_first_element > index_of_last_element: + return None + +store = [1, 4, 5, 12, 43, 54, 60, 77] +a = binary_search_iterative(store, 2) +print("Index position of value 2 is", a) + + +print(binary_search_iterative(store, 7)) + +print(binary_search_iterative(store, 60)) + + +list1 = [10, 30, 100, 120, 500] + +search_term = 10 +index_position1 = binary_search(list1, search_term) +if index_position1 is None: + print("The data item {} is not found".format(search_term)) +else: + print("The data item {} is found at position {}".format(search_term, index_position1)) + + +list2 = ['book','data','packt', 'structure'] + +search_term2 = 'structure' +index_position2 = search_ordered(list2, search_term2) +if index_position2 is None: + print("The data item {} is not found".format(search_term2)) +else: + print("The data item {} is found at position {}".format(search_term2, index_position2)) diff --git a/Chapter10/binary_search_recursive.py b/Chapter10/binary_search_recursive.py new file mode 100644 index 0000000..33c7e2a --- /dev/null +++ b/Chapter10/binary_search_recursive.py @@ -0,0 +1,37 @@ +def binary_search_recursive(ordered_list, first_element_index, last_element_index, term): + if (last_element_index < first_element_index): + return None + else: + mid_point = first_element_index + ((last_element_index - first_element_index) // 2) + + if ordered_list[mid_point] > term: + return binary_search_recursive(ordered_list, first_element_index, mid_point-1,term) + elif ordered_list[mid_point] < term: + return binary_search_recursive(ordered_list, mid_point+1, last_element_index, term) + else: + return mid_point + + +store = [2, 4, 5, 12, 43, 54, 60, 77] +print(binary_search_recursive(store, 0, 7, 12)) + + + +list1 = [10, 30, 100, 120, 500] + +search_term = 10 +index_position1 = binary_search_recursive(list1, 0, len(list1)-1, search_term) +if index_position1 is None: + print("The data item {} is not found".format(search_term)) +else: + print("The data item {} is found at position {}".format(search_term, index_position1)) + + +list2 = ['book','data','packt', 'structure'] + +search_term2 = 'data' +index_position2 = binary_search_recursive(list2, 0, len(list1)-1, search_term2) +if index_position2 is None: + print("The data item {} is not found".format(search_term2)) +else: + print("The data item {} is found at position {}".format(search_term2, index_position2)) diff --git a/Chapter10/exponential_search.py b/Chapter10/exponential_search.py new file mode 100644 index 0000000..870728b --- /dev/null +++ b/Chapter10/exponential_search.py @@ -0,0 +1,28 @@ +def binary_search_recursive(ordered_list, first_element_index, last_element_index, term): + if (last_element_index < first_element_index): + return None + else: + mid_point = first_element_index + ((last_element_index - first_element_index) // 2) + if ordered_list[mid_point] > term: + return binary_search_recursive (ordered_list, first_element_index, mid_point-1, term) + elif ordered_list[mid_point] < term: + return binary_search_recursive (ordered_list, mid_point+1, last_element_index, term) + else: + return mid_point + + + + + +def exponentialSearch(A, search_value): + if (A[0] == search_value): + return 0 + index = 1 + while index < len(A) and A[index] < search_value: + index *= 2 + return binary_search_recursive(A, index // 2, min(index, len(A) - 1), search_value) + + + + +print(exponentialSearch([1,2,3,4,5,6,7,8,9, 10, 11, 12, 34, 40], 34)) diff --git a/Chapter10/interpolation_search.py b/Chapter10/interpolation_search.py new file mode 100644 index 0000000..8bec8be --- /dev/null +++ b/Chapter10/interpolation_search.py @@ -0,0 +1,29 @@ + +def nearest_mid(input_list, low_index, upper_index, search_value): + mid = low_index + (( upper_index - low_index)/(input_list[upper_index] - input_list[low_index])) * (search_value - input_list[low_index]) + return int(mid) + + +def interpolation_search(ordered_list, search_value): + low_index = 0 + upper_index = len(ordered_list) - 1 + while low_index <= upper_index: + mid_point = nearest_mid(ordered_list, low_index, upper_index, search_value) + if mid_point > upper_index or mid_point < low_index: + return None + if ordered_list[mid_point] == search_value: + return mid_point + if search_value > ordered_list[mid_point]: + low_index = mid_point + 1 + else: + upper_index = mid_point - 1 + if low_index > upper_index: + return None + + + +store = [44, 60, 75, 100, 120, 230, 250] +a = interpolation_search(store, 120) +print("Index position of value 2 is ", a) + +print(nearest_mid(store, 0, 6, 120)) diff --git a/Chapter10/jump_search.py b/Chapter10/jump_search.py new file mode 100644 index 0000000..71a218f --- /dev/null +++ b/Chapter10/jump_search.py @@ -0,0 +1,42 @@ +def search_ordered(ordered_list, term): + print("Entering Linear Search") + ordered_list_size = len(ordered_list) + for i in range(ordered_list_size): + if term == ordered_list[i]: + return i + elif ordered_list[i] > term: + return -1 + return -1 + + + +def jump_search(A, item): + print("Entering Jump Search") + n = len(A) + m = int(math.sqrt(n)) + i = 0 + while i != len(A)-1 and A[i] <= item: + print("Block under consideration - {}".format(A[i: i+m])) + if i+m > len(A): + m = len(A) - i + B = A[i: i+m] + j = search_ordered(B, item) + if j == -1: + print("Element not found") + return + return i + j + if A[i+m-1] == item: + return i+m-1 + elif A[i+m-1] > item: + B = A[i: i+m-1] + j = search_ordered(B, item) + if j == -1: + print("Element not found") + return + return i + j + i += m + + + +print(jump_search([1,2,3,4,5,6,7,8,9, 10, 11], 10)) + diff --git a/Chapter10/search_ordered_list.py b/Chapter10/search_ordered_list.py new file mode 100644 index 0000000..ee829e0 --- /dev/null +++ b/Chapter10/search_ordered_list.py @@ -0,0 +1,33 @@ + +def search_ordered(ordered_list, term): + ordered_list_size = len(ordered_list) + for i in range(ordered_list_size): + if term == ordered_list[i]: + return i + elif ordered_list[i] > term: + return None + + return None + + + +list1 = [2, 3, 4, 6, 7] + +search_term = 6 +index_position1 = search_ordered(list1, search_term) + +if index_position1 is None: + print("{} not found".format(search_term)) +else: + print("{} found at position {}".format(search_term, index_position1)) + + + +list2 = ['book','data','packt', 'structure'] + +search_term2 = 'structure' +index_position2 = search_ordered(list2, search_term2) +if index_position2 is None: + print("{} not found".format(search_term2)) +else: + print("{} found at position {}".format(search_term2, index_position2)) diff --git a/Chapter11/.DS_Store b/Chapter11/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..7bdd748cf94d0cafd69b71172f4083af2c1f76b6 GIT binary patch literal 6148 zcmeHKu};G<5PesQR8)c52}X}hNX#rzRfdiz?4X1W6`?`U4s2QY7`~4WfOobPwMi%& z0(2*xpMAdbCC^qa1|XC5-8nDv&a1Yh7cKil@oN;A;|9+t@znA*!*66j z_wEQ8*3=A}`?taw9`Q0O$~-H|jDC7ZE~uv;Uf2W1m|@8spL54oSa9c;^$F-+;jOX4 zA+DHxfgJa{BjvaeIY!F7`po%8?$n>Y&fN0aSYe23W`6i4?|UPPLla}b7%&F@Gy|;J zDuZD_YmEV8z!<0*(C>qzDkc%Dfd13L#$N%5eVVELz z3E{N6=$AyS0)}u%ynIN^Eb)dSK0DWU-W`$zwAL6f2DTa43&WAt|I4rM|Jy+}G6sx+ zf5m|Gr|ERUSBkZ@^>SKk9rc!~qJCAtI)oixis`GR_=M_(cBdU;60r(M3&nl}JPp 0 and unsorted_list[search_index-1] > insert_value : + unsorted_list[search_index] = unsorted_list[search_index-1] + search_index -= 1 + unsorted_list[search_index] = insert_value + + + + + + +my_list = [10, 11, 12, 1, 2, 3] +print("List before sorting", my_list) +insertion_sort(my_list) +print("List before sorting", my_list) diff --git a/Chapter11/Quick_sort.py b/Chapter11/Quick_sort.py new file mode 100644 index 0000000..96efa57 --- /dev/null +++ b/Chapter11/Quick_sort.py @@ -0,0 +1,35 @@ +def partition(unsorted_array, first_index, last_index): + pivot = unsorted_array[first_index] + pivot_index = first_index + index_of_last_element = last_index + less_than_pivot_index = index_of_last_element + greater_than_pivot_index = first_index + 1 + while True: + while unsorted_array[greater_than_pivot_index] < pivot and greater_than_pivot_index < last_index: + greater_than_pivot_index += 1 + while unsorted_array[less_than_pivot_index] > pivot and less_than_pivot_index >= first_index: + less_than_pivot_index -= 1 + if greater_than_pivot_index < less_than_pivot_index: + temp = unsorted_array[greater_than_pivot_index] + unsorted_array[greater_than_pivot_index] = unsorted_array[less_than_pivot_index] + unsorted_array[less_than_pivot_index] = temp + else: + break + unsorted_array[pivot_index] = unsorted_array[less_than_pivot_index] + unsorted_array[less_than_pivot_index] = pivot + return less_than_pivot_index + + +def quick_sort(unsorted_array, first, last): + if last - first <= 0: + return + else: + partition_point = partition(unsorted_array, first, last) + quick_sort(unsorted_array, first, partition_point-1) + quick_sort(unsorted_array, partition_point+1, last) + + +my_array = [43, 3, 77, 89, 4, 20] +print(my_array) +quick_sort(my_array, 0, 5) +print(my_array) diff --git a/Chapter11/Selection_Sort.py b/Chapter11/Selection_Sort.py new file mode 100644 index 0000000..fae399b --- /dev/null +++ b/Chapter11/Selection_Sort.py @@ -0,0 +1,21 @@ +def selection_sort(unsorted_list): + size_of_list = len(unsorted_list) + for i in range(size_of_list): + small = i + for j in range(i+1, size_of_list): + if unsorted_list[j] < unsorted_list[small]: + small = j + temp = unsorted_list[i] + unsorted_list[i] = unsorted_list[small] + unsorted_list[small] = temp + + + + +a_list = [3, 2, 35, 4, 32, 94, 5, 7] + +print("List before sorting", a_list) + +selection_sort(a_list) + +print("List after sorting", a_list) diff --git a/Chapter11/Tim_sort.py b/Chapter11/Tim_sort.py new file mode 100644 index 0000000..7646fa6 --- /dev/null +++ b/Chapter11/Tim_sort.py @@ -0,0 +1,55 @@ +def Insertion_Sort(unsorted_list): + for index in range(1, len(unsorted_list)): + search_index = index + insert_value = unsorted_list[index] + while search_index > 0 and unsorted_list[search_index-1] > insert_value : + unsorted_list[search_index] = unsorted_list[search_index-1] + search_index -= 1 + unsorted_list[search_index] = insert_value + return unsorted_list + + + +def Merge(first_sublist, second_sublist): + i = j = 0 + merged_list = [] + while i < len(first_sublist) and j < len(second_sublist): + if first_sublist[i] < second_sublist[j]: + merged_list.append(first_sublist[i]) + i += 1 + else: + merged_list.append(second_sublist[j]) + j += 1 + while i < len(first_sublist): + merged_list.append(first_sublist[i]) + i += 1 + while j < len(second_sublist): + merged_list.append(second_sublist[j]) + j += 1 + return merged_list + + +def Tim_Sort(arr,run): + for x in range(0, len(arr), run): + arr[x : x + run] = InsertionSort(arr[x : x + run]) + runSize = run + + while runSize < len(arr): + for x in range(0, len(arr), 2 * runSize): + arr[x : x + 2 * runSize] = Merge(arr[x : x + runSize], arr[x + runSize: x + 2 * runSize]) + + runSize = runSize * 2 + +arr = [4, 6, 3, 9, 2, 8, 7, 5] +run = 2 + + +Tim_Sort(arr,run) +print(arr) + + +import random +array = [random.randint(0, 1000) for i in range(1000)] + +Tim_Sort(array,run) +print(array) diff --git a/Chapter11/bubble_sort.py b/Chapter11/bubble_sort.py new file mode 100644 index 0000000..58e2f81 --- /dev/null +++ b/Chapter11/bubble_sort.py @@ -0,0 +1,29 @@ +unordered_list = [5, 2] + +temp = unordered_list[0] +unordered_list[0] = unordered_list[1] +unordered_list[1] = temp + +print(unordered_list) + + + +def bubble_sort(unordered_list): + iteration_number = len(unordered_list)-1 + for i in range(iteration_number,0,-1): + for j in range(i): + if unordered_list[j] > unordered_list[j+1]: + temp = unordered_list[j] + unordered_list[j] = unordered_list[j+1] + unordered_list[j+1] = temp + + + + +my_list = [4,3,2,1] +bubble_sort(my_list) +print(my_list) + +my_list = [1,12,3,4] +bubble_sort(my_list) +print(my_list) diff --git a/Chapter12/.DS_Store b/Chapter12/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..af1f6241c997c13069e144cb4b3f8200dee28ff0 GIT binary patch literal 6148 zcmeHKyGjH>5UkM)4oogE5Tgl=1Y?usI0IupK<{=BJXl@PGtg*%$FJ0?=~i6bP(-8~ zda7soF*^l24*+TY*qi_}08^?k$ruq0kGgg|SeQzUd)#1yTk69|p}#n!Z$CtXHMZ2x z-@oN5YFu(9YqZpw5gT+|-7)U)bl!ILs_jHI(AFEjecAErbv7zhUb83SpuxLC}&C_h`jEl+1{re0AcitA-iXb&y{ i>}Vf3C{FWd*^H|kdqY*xcu6P5MW7H8O)&5a47>s7Q8RG> literal 0 HcmV?d00001 diff --git a/Chapter12/deterministic_selection.py b/Chapter12/deterministic_selection.py new file mode 100644 index 0000000..8258e3b --- /dev/null +++ b/Chapter12/deterministic_selection.py @@ -0,0 +1,85 @@ +def partition(unsorted_array, first_index, last_index): + if first_index == last_index: + return first_index + else: + nearest_median = median_of_medians(unsorted_array[first_index:last_index]) + + index_of_nearest_median = get_index_of_nearest_median(unsorted_array, first_index, + last_index, nearest_median) + swap(unsorted_array, first_index, index_of_nearest_median) + + pivot = unsorted_array[first_index] + pivot_index = first_index + index_of_last_element = last_index + less_than_pivot_index = index_of_last_element + greater_than_pivot_index = first_index + 1 + + ## This while loop is used to correctly place pivot element at its correct position + while 1: + while unsorted_array[greater_than_pivot_index] < pivot and greater_than_pivot_index < last_index: + greater_than_pivot_index += 1 + while unsorted_array[less_than_pivot_index] > pivot and less_than_pivot_index >= first_index: + less_than_pivot_index -= 1 + + if greater_than_pivot_index < less_than_pivot_index: + temp = unsorted_array[greater_than_pivot_index] + unsorted_array[greater_than_pivot_index] = unsorted_array[less_than_pivot_index] + unsorted_array[less_than_pivot_index] = temp + else: + break + + unsorted_array[pivot_index]=unsorted_array[less_than_pivot_index] + unsorted_array[less_than_pivot_index]=pivot + return less_than_pivot_index + + +def median_of_medians(elems): + + sublists = [elems[j:j+5] for j in range(0, len(elems), 5)] + medians = [] + for sublist in sublists: + medians.append(sorted(sublist)[int(len(sublist)/2)]) + + if len(medians) <= 5: + return sorted(medians)[int(len(medians)/2)] + else: + return median_of_medians(medians) + + + +def get_index_of_nearest_median(array_list, first, second, median): + if first == second: + return first + else: + return first + array_list[first:second].index(median) + + + + +def swap(array_list, first, second): + temp = array_list[first] + array_list[first] = array_list[second] + array_list[second] = temp + + + + +def deterministic_select(array_list, left, right, k): + + split = partition(array_list, left, right) + if split == k: + return array_list[split] + elif split < k: + return deterministic_select(array_list, split + 1, right, k) + else: + return deterministic_select(array_list, left, split-1, k) + + + + +stored = [3,1,10,4,6, 5] +print(deterministic_select(stored, 0, 5, 2)) + + + + diff --git a/Chapter12/randomized_search.py b/Chapter12/randomized_search.py new file mode 100644 index 0000000..a8bf324 --- /dev/null +++ b/Chapter12/randomized_search.py @@ -0,0 +1,63 @@ +def partition(unsorted_array, first_index, last_index): + + pivot = unsorted_array[first_index] + pivot_index = first_index + index_of_last_element = last_index + + less_than_pivot_index = index_of_last_element + greater_than_pivot_index = first_index + 1 + + while True: + + while unsorted_array[greater_than_pivot_index] < pivot and greater_than_pivot_index < last_index: + greater_than_pivot_index += 1 + while unsorted_array[less_than_pivot_index] > pivot and less_than_pivot_index >= first_index: + less_than_pivot_index -= 1 + + if greater_than_pivot_index < less_than_pivot_index: + temp = unsorted_array[greater_than_pivot_index] + unsorted_array[greater_than_pivot_index] = unsorted_array[less_than_pivot_index] + unsorted_array[less_than_pivot_index] = temp + else: + break + + unsorted_array[pivot_index] = unsorted_array[less_than_pivot_index] + unsorted_array[less_than_pivot_index] = pivot + + return less_than_pivot_index + + +def quick_select(array_list, start, end, k): + split = partition(array_list, start, end) + if split == k: + return array_list[split] + elif split < k: + return quick_select(array_list, split + 1, end, k) + else: + return quick_select(array_list, start, split-1, k) + + + + +list1 = [3,1,10, 4, 6, 5] + +print("The 2nd smallest element is", quick_select(list1, 0, 5, 1)) + +print("The 3nd smallest element is", quick_select(list1, 0, 5, 2)) + + + + +stored = [3,1,10,4,6,5] +print(stored) +print(quick_select(stored, 0, 5, 0)) +stored = [3,1,10,4,6, 5] +print(quick_select(stored, 0, 5, 1)) +stored = [3,1,10,4,6, 5] +print(quick_select(stored, 0, 5, 2)) +stored = [3,1,10,4,6, 5] +print(quick_select(stored, 0, 5, 3)) +stored = [3,1,10,4,6, 5] +print(quick_select(stored, 0, 5, 4)) +stored = [3,1,10,4,6, 5] +print(quick_select(stored, 0, 5, 5)) diff --git a/Chapter13/.DS_Store b/Chapter13/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..a8320f1f073be8120b281692768ee7399c0b1817 GIT binary patch literal 6148 zcmeHKy-EW?5T1!qA~xwvqg-hvSlb*S79xU}2Z%{bRJfQB4J6$)K8(-j1L!wDB;+n4 z2#UzeG5hV#&dlz8yWHLq5jSVICq#83szC)SyC^n@^oy3H;+Ab7YmO;(=#s{GrX}w% z{6z+2?GCAl6Ak=*BH5{Omq;}#aNT?Fvc&1%xH!L1HnKr@WTw?%oeHb8Acfl1Ovgq zk^%WXBv8TBF*npt2MWCc0IM*opf10G5|cQlj=3RvAZ(#P3uV7zu!X~(xL@j+8(KKA zUq0AJX1}4Zj*k3^x)Y~{Q3eCSz&Zn4)~w6X;kC0*N01r6G!7;8z*=0NE66qW}N^ literal 0 HcmV?d00001 diff --git a/Chapter13/Boyer_Moore_String_Matching.py b/Chapter13/Boyer_Moore_String_Matching.py new file mode 100644 index 0000000..a25803b --- /dev/null +++ b/Chapter13/Boyer_Moore_String_Matching.py @@ -0,0 +1,46 @@ +text = "acbaacacababacacac" +pattern = "acacac" + + +matched_indexes = [] + +i=0 +flag = True +while i<=len(text)-len(pattern): + for j in range(len(pattern)-1, -1, -1): #reverse searching + if pattern[j] != text[i+j]: + flag = False #indicates there is a mismatch + if j == len(pattern)-1: #if good-suffix is not present, we test bad character + if text[i+j] in pattern[0:j]: + i=i+j-pattern[0:j].rfind(text[i+j]) + #i+j is index of bad character, this line is used for jumping pattern to match + #bad character of text with same character in pattern + else: + i=i+j+1 #if bad character is not present, jump pattern next to it + else: + k=1 + while text[i+j+k:i+len(pattern)] not in pattern[0:len(pattern)-1]: + #used for finding sub part of a good-suffix + k=k+1 + if len(text[i+j+k:i+len(pattern)]) != 1: #good-suffix should not be of one character + gsshift=i+j+k-pattern[0:len(pattern)-1].rfind(text[i+j+k:i+len(pattern)]) + #jumps pattern to a position where good-suffix of pattern matches with good-suffix of text + else: + #gsshift=i+len(pattern) + gsshift=0 #when good-suffix heuristic is not applicable, + #we prefer bad character heuristic + if text[i+j] in pattern[0:j]: + bcshift=i+j-pattern[0:j].rfind(text[i+j]) + #i+j is index of bad character, this line is used for jumping pattern to match bad character + #of text with same character in pattern + else: + bcshift=i+j+1 + i=max((bcshift, gsshift)) + break + if flag: #if pattern is found then normal iteration + matched_indexes.append(i) + i = i+1 + else: #again set flag to True so new string in text can be examined + flag = True + +print ("Pattern found at", matched_indexes) diff --git a/Chapter13/Brute_force_string_matching.py b/Chapter13/Brute_force_string_matching.py new file mode 100644 index 0000000..bc614e5 --- /dev/null +++ b/Chapter13/Brute_force_string_matching.py @@ -0,0 +1,27 @@ +def brute_force(text, pattern): + l1 = len(text) # The length of the text string + l2 = len(pattern) # The length of the pattern + i = 0 + j = 0 # looping variables are set to 0 + flag = False # If the pattern doesn't appear at all, then set this to false and execute the last if statement + while i < l1: # iterating from the 0th index of text + j = 0 + count = 0 + # Count stores the length upto which the pattern and the text have matched + while j < l2: + if i+j < l1 and text[i+j] == pattern[j]: + # statement to check if a match has occurred or not + count += 1 # Count is incremented if a character is matched + j += 1 + if count == l2: # it shows a matching of pattern in the text + print("\nPattern occurs at index", i) + # print the starting index of the successful match + flag = True + # flag is True as we wish to continue looking for more matching of pattern in the text. + i += 1 + if not flag: + # If the pattern doesn't occurs at all, means no match of pattern in the text string + print('\nPattern is not at all present in the array') + + +brute_force('acbcabccababcaacbcac','acbcac') # function call diff --git a/Chapter13/KMP.py b/Chapter13/KMP.py new file mode 100644 index 0000000..26ec373 --- /dev/null +++ b/Chapter13/KMP.py @@ -0,0 +1,35 @@ +def pfun(pattern): # function to generate prefix function for the given pattern + n = len(pattern) # length of the pattern + prefix_fun = [0]*(n) # initialize all elements of the list to 0 + k = 0 + for q in range(2,n): + while k>0 and pattern[k+1] != pattern[q]: + k = prefix_fun[k] + if pattern[k+1] == pattern[q]: # If the kth element of the pattern is equal to the qth element + k += 1 # update k accordingly + prefix_fun[q] = k + return prefix_fun # return the prefix function + + +def KMP_Matcher(text,pattern): # KMP matcher function + m = len(text) + n = len(pattern) + flag = False + text = '-' + text # append dummy character to make it 1-based indexing + pattern = '-' + pattern # append dummy character to the pattern also + prefix_fun = pfun(pattern) # generate prefix function for the pattern + q = 0 + for i in range(1,m+1): + while q>0 and pattern[q+1] != text[i]: # while pattern and text are not equal, decrement the value of q if it is > 0 + q = prefix_fun[q] + if pattern[q+1] == text[i]: # if pattern and text are equal, update value of q + q += 1 + if q == n: # if q is equal to the length of the pattern, it means that the pattern has been found. + print("Pattern occours with shift",i-n) # print the index, where first match occours. + flag = True + q = prefix_fun[q] + if not flag: + print('\nNo match found') + + +KMP_Matcher('aabaacaadaabaaba','aabaa') # function call, with two parameters,text and pattern diff --git a/Chapter13/Rabin_Karp_String_Matching.py b/Chapter13/Rabin_Karp_String_Matching.py new file mode 100644 index 0000000..dda066f --- /dev/null +++ b/Chapter13/Rabin_Karp_String_Matching.py @@ -0,0 +1,46 @@ +def generate_hash(text, pattern): + ord_text = [ord(i) for i in text] # stores unicode value of each character in text + ord_pattern = [ord(j) for j in pattern] # stores unicode value of each character in pattern + len_text = len(text) # stores length of the text + len_pattern = len(pattern) # stores length of the pattern + len_hash_array = len_text - len_pattern + 1 # stores the length of new array that will contain the hash values of text + hash_text = [0]*(len_hash_array) # Initialize all the values in the array to 0. + hash_pattern = sum(ord_pattern) + for i in range(0,len_hash_array): # step size of the loop will be the size of the pattern + if i == 0: # Base condition + hash_text[i] = sum(ord_text[:len_pattern]) # initial value of hash function + else: + hash_text[i] = ((hash_text[i-1] - ord_text[i-1]) + ord_text[i+len_pattern-1]) # calculating next hash value using previous value + return [hash_text, hash_pattern] # return the hash values + + + +def Rabin_Karp_Matcher(text, pattern): + text = str(text) # convert text into string format + pattern = str(pattern) # convert pattern into string format + hash_text, hash_pattern = generate_hash(text, pattern) # generate hash values using generate_hash function + len_text = len(text) # length of text + len_pattern = len(pattern) # length of pattern + flag = False # checks if pattern is present atleast once or not at all + for i in range(len(hash_text)): + if hash_text[i] == hash_pattern: # if the hash value matches + count = 0 # count stores the total characters upto which both are similar + for j in range(len_pattern): + if pattern[j] == text[i+j]: # checking equality for each character + count += 1 # if value is equal, then update the count value + else: + break + if count == len_pattern: # if count is equal to length of pattern, it means match has been found + flag = True # update flag accordingly + print('Pattern occours at index',i) + if not flag: # if pattern doesn't match even once, then this if statement is executed + print('Pattern is not at all present in the text') + + +Rabin_Karp_Matcher("101110000011010010101101","10112") + +# Works for numeric +Rabin_Karp_Matcher("101110000011010010101101","1011") + +# Works for alphabets +Rabin_Karp_Matcher("ABBACCADABBACCEDF","ACCE") diff --git a/Chapter13/example_suffix_prefix.py b/Chapter13/example_suffix_prefix.py new file mode 100644 index 0000000..42d2741 --- /dev/null +++ b/Chapter13/example_suffix_prefix.py @@ -0,0 +1,6 @@ +string = "this is data structures book by packt publisher" +suffix = "publisher" +prefix = "this" +print(string.endswith(suffix)) #Check if string contains given suffix. + +print(string.startswith(prefix)) #Check if string starts with given prefix. From c4cba8347340a5e53ae630b2ba51ac599a49e55a Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Fri, 3 Jun 2022 14:38:44 +0530 Subject: [PATCH 05/53] Removed --- Chapter03/Fibonacci_series.py | 8 ---- Chapter03/binary_search.py | 16 ------- Chapter03/dijkstra.py | 80 ----------------------------------- Chapter03/dyna_fib.py | 13 ------ Chapter03/factorial.py | 10 ----- Chapter03/merge_sort.py | 35 --------------- 6 files changed, 162 deletions(-) delete mode 100644 Chapter03/Fibonacci_series.py delete mode 100644 Chapter03/binary_search.py delete mode 100644 Chapter03/dijkstra.py delete mode 100644 Chapter03/dyna_fib.py delete mode 100644 Chapter03/factorial.py delete mode 100644 Chapter03/merge_sort.py diff --git a/Chapter03/Fibonacci_series.py b/Chapter03/Fibonacci_series.py deleted file mode 100644 index 99590f2..0000000 --- a/Chapter03/Fibonacci_series.py +++ /dev/null @@ -1,8 +0,0 @@ -def fib(n): - if n <= 1: - return 1 - else: - return fib(n-1) + fib(n-2) - -for i in range(5): - print(fib(i)) diff --git a/Chapter03/binary_search.py b/Chapter03/binary_search.py deleted file mode 100644 index dac62d4..0000000 --- a/Chapter03/binary_search.py +++ /dev/null @@ -1,16 +0,0 @@ -def binary_search(arr, low, high, key): - while low <= high: - mid = int(low + (high - low)/2) - if arr[mid] == key: - return mid - elif arr[mid] < key: - low = mid + 1 - else: - high = mid - 1 - return -1 - - -arr = [ 2, 3, 4, 2, 10, 40] -x = 10 -result = binary_search(arr, 0, len(arr)-1, x) -print(result) diff --git a/Chapter03/dijkstra.py b/Chapter03/dijkstra.py deleted file mode 100644 index 29cab7a..0000000 --- a/Chapter03/dijkstra.py +++ /dev/null @@ -1,80 +0,0 @@ - -def get_shortest_distance(table, vertex): - shortest_distance = table[vertex][DISTANCE] - return shortest_distance - -def set_shortest_distance(table, vertex, new_distance): - table[vertex][DISTANCE] = new_distance - -def set_previous_node(table, vertex, previous_node): - table[vertex][PREVIOUS_NODE] = previous_node - -def get_distance(graph, first_vertex, second_vertex): - return graph[first_vertex][second_vertex] - -def get_next_node(table, visited_nodes): - unvisited_nodes = list(set(table.keys()).difference(set(visited_nodes))) - assumed_min = table[unvisited_nodes[0]][DISTANCE] - min_vertex = unvisited_nodes[0] - for node in unvisited_nodes: - if table[node][DISTANCE] < assumed_min: - assumed_min = table[node][DISTANCE] - min_vertex = node - return min_vertex - -def find_shortest_path(graph, table, origin): - visited_nodes = [] - current_node = origin - starting_node = origin - while True: - adjacent_nodes = graph[current_node] - if set(adjacent_nodes).issubset(set(visited_nodes)): - # Nothing here to do. All adjacent nodes have been visited. - pass - else: - unvisited_nodes = set(adjacent_nodes).difference(set(visited_nodes)) - for vertex in unvisited_nodes: - distance_from_starting_node = get_shortest_distance(table, vertex) - if distance_from_starting_node == INFINITY and current_node == starting_node: - total_distance = get_distance(graph, vertex, current_node) - else: - total_distance = get_shortest_distance (table, - current_node) + get_distance(graph, current_node, vertex) - if total_distance < distance_from_starting_node: - set_shortest_distance(table, vertex, total_distance) - set_previous_node(table, vertex, current_node) - visited_nodes.append(current_node) - #print(visited_nodes) - if len(visited_nodes) == len(table.keys()): - break - current_node = get_next_node(table,visited_nodes) - return(table) - -graph = dict() -graph['A'] = {'B': 5, 'D': 9, 'E': 2} -graph['B'] = {'A': 5, 'C': 2} -graph['C'] = {'B': 2, 'D': 3} -graph['D'] = {'A': 9, 'F': 2, 'C': 3} -graph['E'] = {'A': 2, 'F': 3} -graph['F'] = {'E': 3, 'D': 2} - -table = dict() -table = { - 'A': [0, None], - 'B': [float("inf"), None], - 'C': [float("inf"), None], - 'D': [float("inf"), None], - 'E': [float("inf"), None], - 'F': [float("inf"), None], -} - - -DISTANCE = 0 -PREVIOUS_NODE = 1 -INFINITY = float('inf') - -shortest_distance_table = find_shortest_path(graph, table, 'A') - - -for k in sorted(shortest_distance_table): - print("{} - {}".format(k,shortest_distance_table[k])) diff --git a/Chapter03/dyna_fib.py b/Chapter03/dyna_fib.py deleted file mode 100644 index 5ba97f6..0000000 --- a/Chapter03/dyna_fib.py +++ /dev/null @@ -1,13 +0,0 @@ -def dyna_fib(n, lookup): - if n == 0: - return 0 - if n <= 2: - lookup[n] = 1 - if lookup[n] is None: - lookup[n] = dyna_fib(n-1, lookup) + dyna_fib(n-2, lookup) - return lookup[n] - -lookup = [None]*(1000) - -for i in range(6): - print(dyna_fib(i, lookup)) diff --git a/Chapter03/factorial.py b/Chapter03/factorial.py deleted file mode 100644 index 3469d23..0000000 --- a/Chapter03/factorial.py +++ /dev/null @@ -1,10 +0,0 @@ -def factorial(n): - # test for a base case - if n == 0: - return 1 - else: - return n*factorial(n-1) # make a calculation and a recursive call - - - -print(factorial(4)) diff --git a/Chapter03/merge_sort.py b/Chapter03/merge_sort.py deleted file mode 100644 index e546be9..0000000 --- a/Chapter03/merge_sort.py +++ /dev/null @@ -1,35 +0,0 @@ -def merge_sort(unsorted_list): - if len(unsorted_list) == 1: - return unsorted_list - mid_point = int(len(unsorted_list)/2) - first_half = unsorted_list[:mid_point] - second_half = unsorted_list[mid_point:] - - half_a = merge_sort(first_half) - half_b = merge_sort(second_half) - - return merge(half_a, half_b) - - - -def merge(first_sublist, second_sublist): - i = j = 0 - merged_list = [] - while i < len(first_sublist) and j < len(second_sublist): - if first_sublist[i] < second_sublist[j]: - merged_list.append(first_sublist[i]) - i += 1 - else: - merged_list.append(second_sublist[j]) - j += 1 - while i < len(first_sublist): - merged_list.append(first_sublist[i]) - i += 1 - while j < len(second_sublist): - merged_list.append(second_sublist[j]) - j += 1 - return merged_list - - -a= [11, 12, 7, 41, 61, 13, 16, 14] -print(merge_sort(a)) From 6e2d46ad3d9cd007a4c7b891534f18f9ec7f0e3c Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Fri, 3 Jun 2022 14:39:21 +0530 Subject: [PATCH 06/53] Updated --- Chapter03/Fibonacci_series.py | 8 ++++ Chapter03/binary_search.py | 18 ++++++++ Chapter03/dijkstra.py | 80 +++++++++++++++++++++++++++++++++++ Chapter03/dyna_fib.py | 17 ++++++++ Chapter03/factorial.py | 10 +++++ Chapter03/merge_sort.py | 35 +++++++++++++++ 6 files changed, 168 insertions(+) create mode 100644 Chapter03/Fibonacci_series.py create mode 100644 Chapter03/binary_search.py create mode 100644 Chapter03/dijkstra.py create mode 100644 Chapter03/dyna_fib.py create mode 100644 Chapter03/factorial.py create mode 100644 Chapter03/merge_sort.py diff --git a/Chapter03/Fibonacci_series.py b/Chapter03/Fibonacci_series.py new file mode 100644 index 0000000..99590f2 --- /dev/null +++ b/Chapter03/Fibonacci_series.py @@ -0,0 +1,8 @@ +def fib(n): + if n <= 1: + return 1 + else: + return fib(n-1) + fib(n-2) + +for i in range(5): + print(fib(i)) diff --git a/Chapter03/binary_search.py b/Chapter03/binary_search.py new file mode 100644 index 0000000..d07b955 --- /dev/null +++ b/Chapter03/binary_search.py @@ -0,0 +1,18 @@ +def binary_search(arr, start, end, key): + while start <= end: + mid = start + (end - start)/2) + if arr[mid] == key: + return mid + elif arr[mid] < key: + start = mid + 1 + else: + end = mid - 1 + return -1 + + +arr = [ 4, 6, 9, 13, 14, 18, 21, 24, 38] +x = 13 +result = binary_search(arr, 0, len(arr)-1, x) +print(result) + + diff --git a/Chapter03/dijkstra.py b/Chapter03/dijkstra.py new file mode 100644 index 0000000..29cab7a --- /dev/null +++ b/Chapter03/dijkstra.py @@ -0,0 +1,80 @@ + +def get_shortest_distance(table, vertex): + shortest_distance = table[vertex][DISTANCE] + return shortest_distance + +def set_shortest_distance(table, vertex, new_distance): + table[vertex][DISTANCE] = new_distance + +def set_previous_node(table, vertex, previous_node): + table[vertex][PREVIOUS_NODE] = previous_node + +def get_distance(graph, first_vertex, second_vertex): + return graph[first_vertex][second_vertex] + +def get_next_node(table, visited_nodes): + unvisited_nodes = list(set(table.keys()).difference(set(visited_nodes))) + assumed_min = table[unvisited_nodes[0]][DISTANCE] + min_vertex = unvisited_nodes[0] + for node in unvisited_nodes: + if table[node][DISTANCE] < assumed_min: + assumed_min = table[node][DISTANCE] + min_vertex = node + return min_vertex + +def find_shortest_path(graph, table, origin): + visited_nodes = [] + current_node = origin + starting_node = origin + while True: + adjacent_nodes = graph[current_node] + if set(adjacent_nodes).issubset(set(visited_nodes)): + # Nothing here to do. All adjacent nodes have been visited. + pass + else: + unvisited_nodes = set(adjacent_nodes).difference(set(visited_nodes)) + for vertex in unvisited_nodes: + distance_from_starting_node = get_shortest_distance(table, vertex) + if distance_from_starting_node == INFINITY and current_node == starting_node: + total_distance = get_distance(graph, vertex, current_node) + else: + total_distance = get_shortest_distance (table, + current_node) + get_distance(graph, current_node, vertex) + if total_distance < distance_from_starting_node: + set_shortest_distance(table, vertex, total_distance) + set_previous_node(table, vertex, current_node) + visited_nodes.append(current_node) + #print(visited_nodes) + if len(visited_nodes) == len(table.keys()): + break + current_node = get_next_node(table,visited_nodes) + return(table) + +graph = dict() +graph['A'] = {'B': 5, 'D': 9, 'E': 2} +graph['B'] = {'A': 5, 'C': 2} +graph['C'] = {'B': 2, 'D': 3} +graph['D'] = {'A': 9, 'F': 2, 'C': 3} +graph['E'] = {'A': 2, 'F': 3} +graph['F'] = {'E': 3, 'D': 2} + +table = dict() +table = { + 'A': [0, None], + 'B': [float("inf"), None], + 'C': [float("inf"), None], + 'D': [float("inf"), None], + 'E': [float("inf"), None], + 'F': [float("inf"), None], +} + + +DISTANCE = 0 +PREVIOUS_NODE = 1 +INFINITY = float('inf') + +shortest_distance_table = find_shortest_path(graph, table, 'A') + + +for k in sorted(shortest_distance_table): + print("{} - {}".format(k,shortest_distance_table[k])) diff --git a/Chapter03/dyna_fib.py b/Chapter03/dyna_fib.py new file mode 100644 index 0000000..9c81b91 --- /dev/null +++ b/Chapter03/dyna_fib.py @@ -0,0 +1,17 @@ +def dyna_fib(n): + if n == 0: + return 0 + if n == 1: + return 1 + if lookup[n] is not None: + return lookup[n] + + lookup[n] = dyna_fib(n-1) + dyna_fib(n-2) + return lookup[n] + + +lookup = [None]*(1000) + + +for i in range(6): + print(dyna_fib(i)) diff --git a/Chapter03/factorial.py b/Chapter03/factorial.py new file mode 100644 index 0000000..861221a --- /dev/null +++ b/Chapter03/factorial.py @@ -0,0 +1,10 @@ +def factorial(n): + # test for a base case + if n == 0: + return 1 + else: + return n*factorial(n-1) # Do the calculation and a recursive call + + + +print(factorial(4)) diff --git a/Chapter03/merge_sort.py b/Chapter03/merge_sort.py new file mode 100644 index 0000000..d678a03 --- /dev/null +++ b/Chapter03/merge_sort.py @@ -0,0 +1,35 @@ +def merge_sort(unsorted_list): + if len(unsorted_list) == 1: + return unsorted_list + mid_point = int(len(unsorted_list)/2) + first_half = unsorted_list[:mid_point] + second_half = unsorted_list[mid_point:] + + half_a = merge_sort(first_half) + half_b = merge_sort(second_half) + + return merge(half_a, half_b) + + + +def merge(first_sublist, second_sublist): + i = j = 0 + merged_list = [] + while i < len(first_sublist) and j < len(second_sublist): + if first_sublist[i] < second_sublist[j]: + merged_list.append(first_sublist[i]) + i += 1 + else: + merged_list.append(second_sublist[j]) + j += 1 + while i < len(first_sublist): + merged_list.append(first_sublist[i]) + i += 1 + while j < len(second_sublist): + merged_list.append(second_sublist[j]) + j += 1 + return merged_list + + +a= [11, 12, 7, 41, 61, 13, 16, 14] +print(merge_sort(a)) From 8c8198563ccfc266b1c9242dffbba242ffb6c79e Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Fri, 3 Jun 2022 18:16:05 +0530 Subject: [PATCH 07/53] Update --- Chapter01/chapter1.py | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/Chapter01/chapter1.py b/Chapter01/chapter1.py index 2631bf5..497d320 100644 --- a/Chapter01/chapter1.py +++ b/Chapter01/chapter1.py @@ -9,14 +9,14 @@ ############### var = 13.2 -print(var) +print(type(var)) #13.2 type (var) # var = "Now the type is string" -print(var) +print(type(var)) type(var) # @@ -36,6 +36,7 @@ ''' bool(False) +print(bool(False)) #False va1 = 0 print(bool(va1)) @@ -50,9 +51,11 @@ #True #### Strings -Str1 = 'Hello how are you' +str1 = 'Hello how are you' str2 = "Hello how are you" str3 = 'multiline'+'string'; +print(str1) +print(str2) print(str3) f = 'data' @@ -69,6 +72,22 @@ print(3 * st) #'data.data.data.' +###### Range ###### + +print(list(range(10))) +print(range(10)) +print(list(range(10))) +print(range(1,10,2)) +print(list(range(1,10,2))) +print(list(range(20,10,-2))) + +#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] +#range(0, 10) +#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] +#range(1, 10, 2) +#[1, 3, 5, 7, 9] +#[20, 18, 16, 14, 12] + ###### Lists ###### @@ -209,7 +228,7 @@ if thirdList is Secondlist: print("Both are pointing to the same object") else: - print("Both are not pointing to the same object ") + print("Both are not pointing to the same object") ''' Output: Both are equal @@ -223,9 +242,9 @@ Firstlist = [] Secondlist = [] if Firstlist is not Secondlist: - print("Both are pointing to the different object") + print("Both Firstlist and Secondlist variables are the same object") else: - print("Both are not pointing to the different object ") + print("Both Firstlist and Secondlist variables are not the same object") #Output: # Both are pointing to the different object From ba8bcb712e03b1d454e9ef6f43eff5b75bb5ebe1 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Fri, 3 Jun 2022 19:39:12 +0530 Subject: [PATCH 08/53] Update --- Chapter01/chapter1.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Chapter01/chapter1.py b/Chapter01/chapter1.py index 497d320..9d9d1be 100644 --- a/Chapter01/chapter1.py +++ b/Chapter01/chapter1.py @@ -247,7 +247,7 @@ print("Both Firstlist and Secondlist variables are not the same object") #Output: -# Both are pointing to the different object +# Both Firstlist and Secondlist variables are the same object @@ -480,6 +480,7 @@ from collections import deque s = deque() # Creates an empty deque +print(s) my_queue = deque([1, 2, 'Name']) print(my_queue) #deque([1, 2, 'Name']) @@ -525,9 +526,9 @@ print(chain) #ChainMap({'data': 1, 'structure': 2}, {'python': 3, 'language': 4}) -print (list(chain.keys())) +print(list(chain.keys())) #['python', 'language', 'data', 'structure'] -print (list(chain.values())) +print(list(chain.values())) #[3, 4, 1, 2] print(chain["data"]) #1 From 20143eb004ffbfae8a64c521a5289033e0228836 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Mon, 6 Jun 2022 16:21:59 +0530 Subject: [PATCH 09/53] Update --- Chapter10/binary_search_iterative.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Chapter10/binary_search_iterative.py b/Chapter10/binary_search_iterative.py index 718d4d4..220b61a 100644 --- a/Chapter10/binary_search_iterative.py +++ b/Chapter10/binary_search_iterative.py @@ -4,7 +4,7 @@ def binary_search_iterative(ordered_list, term): index_of_first_element = 0 index_of_last_element = size_of_list while index_of_first_element <= index_of_last_element: - mid_point = (index_of_first_element + index_of_last_element)//2 + mid_point = (index_of_first_element + index_of_last_element)/2 if ordered_list[mid_point] == term: return mid_point if term > ordered_list[mid_point]: From eecca8d54b4dc33930a9104400cfb5c802d16c32 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Mon, 6 Jun 2022 16:24:06 +0530 Subject: [PATCH 10/53] Update --- Chapter10/binary_search_iterative.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Chapter10/binary_search_iterative.py b/Chapter10/binary_search_iterative.py index 220b61a..c20a523 100644 --- a/Chapter10/binary_search_iterative.py +++ b/Chapter10/binary_search_iterative.py @@ -27,7 +27,7 @@ def binary_search_iterative(ordered_list, term): list1 = [10, 30, 100, 120, 500] search_term = 10 -index_position1 = binary_search(list1, search_term) +index_position1 = binary_search_iterative(list1, search_term) if index_position1 is None: print("The data item {} is not found".format(search_term)) else: @@ -37,7 +37,7 @@ def binary_search_iterative(ordered_list, term): list2 = ['book','data','packt', 'structure'] search_term2 = 'structure' -index_position2 = search_ordered(list2, search_term2) +index_position2 = binary_search_iterative(list2, search_term2) if index_position2 is None: print("The data item {} is not found".format(search_term2)) else: From 92ad9d81eb00315e7584d2e5c656cccb17bbe4d5 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Mon, 6 Jun 2022 16:48:31 +0530 Subject: [PATCH 11/53] Update --- Chapter10/binary_search_recursive.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Chapter10/binary_search_recursive.py b/Chapter10/binary_search_recursive.py index 33c7e2a..dd63c5e 100644 --- a/Chapter10/binary_search_recursive.py +++ b/Chapter10/binary_search_recursive.py @@ -2,7 +2,7 @@ def binary_search_recursive(ordered_list, first_element_index, last_element_inde if (last_element_index < first_element_index): return None else: - mid_point = first_element_index + ((last_element_index - first_element_index) // 2) + mid_point = first_element_index + ((last_element_index - first_element_index) / 2) if ordered_list[mid_point] > term: return binary_search_recursive(ordered_list, first_element_index, mid_point-1,term) From 3d8ce8cb9fb330c31fe0637af184bf7155c43040 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Mon, 6 Jun 2022 17:00:09 +0530 Subject: [PATCH 12/53] Update --- Chapter10/exponential_search.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Chapter10/exponential_search.py b/Chapter10/exponential_search.py index 870728b..e9d7ded 100644 --- a/Chapter10/exponential_search.py +++ b/Chapter10/exponential_search.py @@ -2,7 +2,7 @@ def binary_search_recursive(ordered_list, first_element_index, last_element_inde if (last_element_index < first_element_index): return None else: - mid_point = first_element_index + ((last_element_index - first_element_index) // 2) + mid_point = first_element_index + ((last_element_index - first_element_index) / 2) if ordered_list[mid_point] > term: return binary_search_recursive (ordered_list, first_element_index, mid_point-1, term) elif ordered_list[mid_point] < term: @@ -14,7 +14,7 @@ def binary_search_recursive(ordered_list, first_element_index, last_element_inde -def exponentialSearch(A, search_value): +def exponential_search(A, search_value): if (A[0] == search_value): return 0 index = 1 @@ -25,4 +25,4 @@ def exponentialSearch(A, search_value): -print(exponentialSearch([1,2,3,4,5,6,7,8,9, 10, 11, 12, 34, 40], 34)) +print(exponential_search([1,2,3,4,5,6,7,8,9, 10, 11, 12, 34, 40], 34)) From 5f8f4f70289f68120dbb56dd25691a4f803fd0cc Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Mon, 6 Jun 2022 17:00:55 +0530 Subject: [PATCH 13/53] Update --- Chapter10/exponential_search.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Chapter10/exponential_search.py b/Chapter10/exponential_search.py index e9d7ded..e5ccd41 100644 --- a/Chapter10/exponential_search.py +++ b/Chapter10/exponential_search.py @@ -25,4 +25,4 @@ def exponential_search(A, search_value): -print(exponential_search([1,2,3,4,5,6,7,8,9, 10, 11, 12, 34, 40], 34)) +print(exponential_search([1,2,3,4,5,6,7,8,9,10,11,12,34,40],34)) From 105c2d3bebed62e5f2bce350632cbafb87dea543 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Mon, 6 Jun 2022 17:43:29 +0530 Subject: [PATCH 14/53] Update --- Chapter11/Insertion_sort.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Chapter11/Insertion_sort.py b/Chapter11/Insertion_sort.py index b1ad40d..b4b1305 100644 --- a/Chapter11/Insertion_sort.py +++ b/Chapter11/Insertion_sort.py @@ -13,7 +13,7 @@ def insertion_sort(unsorted_list): -my_list = [10, 11, 12, 1, 2, 3] -print("List before sorting", my_list) +my_list = [5, 1, 100, 2, 10] +print("Original ist", my_list) insertion_sort(my_list) -print("List before sorting", my_list) +print("Sorted list", my_list) From 376a60b7ee0ad7a2dc8cc79741ef510f9e36a05b Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Mon, 6 Jun 2022 17:58:08 +0530 Subject: [PATCH 15/53] Update --- Chapter11/Tim_sort.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/Chapter11/Tim_sort.py b/Chapter11/Tim_sort.py index 7646fa6..f42cfb8 100644 --- a/Chapter11/Tim_sort.py +++ b/Chapter11/Tim_sort.py @@ -29,9 +29,9 @@ def Merge(first_sublist, second_sublist): return merged_list -def Tim_Sort(arr,run): +def Tim_Sort(arr, run): for x in range(0, len(arr), run): - arr[x : x + run] = InsertionSort(arr[x : x + run]) + arr[x : x + run] = Insertion_Sort(arr[x : x + run]) runSize = run while runSize < len(arr): @@ -44,12 +44,5 @@ def Tim_Sort(arr,run): run = 2 -Tim_Sort(arr,run) +Tim_Sort(arr, run) print(arr) - - -import random -array = [random.randint(0, 1000) for i in range(1000)] - -Tim_Sort(array,run) -print(array) From 6a31512e29dd4ff90e55030fa1ec95cb6d3729bc Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Tue, 7 Jun 2022 13:49:35 +0530 Subject: [PATCH 16/53] Update --- Chapter12/deterministic_selection.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Chapter12/deterministic_selection.py b/Chapter12/deterministic_selection.py index 8258e3b..0d5336d 100644 --- a/Chapter12/deterministic_selection.py +++ b/Chapter12/deterministic_selection.py @@ -56,10 +56,10 @@ def get_index_of_nearest_median(array_list, first, second, median): -def swap(array_list, first, second): +def swap(array_list, first, index_of_nearest_median): temp = array_list[first] - array_list[first] = array_list[second] - array_list[second] = temp + array_list[first] = array_list[index_of_nearest_median] + array_list[index_of_nearest_median] = temp From 6df2bf1ae5931862840fa53d1ec13d9d310efd4a Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Tue, 7 Jun 2022 13:53:49 +0530 Subject: [PATCH 17/53] Update --- Chapter02/matrix_chain.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Chapter02/matrix_chain.py b/Chapter02/matrix_chain.py index 2d30a87..55b6eed 100644 --- a/Chapter02/matrix_chain.py +++ b/Chapter02/matrix_chain.py @@ -5,10 +5,10 @@ def matrix_chain(mat, i, j): return 0 minimum_computations = sys.maxsize for k in range(i, j): - count = (MatrixChain(mat, i, k) + MatrixChain(mat, k+1, j)+ mat[i-1] * mat[k] * mat[j]) + count = (matrix_chain(mat, i, k) + matrix_chain(mat, k+1, j)+ mat[i-1] * mat[k] * mat[j]) if count < minimum_computations: minimum_computations = count return minimum_computations matrix_sizes = [20, 30, 45, 50] -print("Minimum multiplications are", MatrixChain(matrix_sizes , 1, len(matrix_sizes)-1)) +print("Minimum multiplications are", matrix_chain(matrix_sizes , 1, len(matrix_sizes)-1)) From f63b196cfc60d0e48982ff3611870ebe8b776955 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Tue, 7 Jun 2022 16:11:15 +0530 Subject: [PATCH 18/53] Update --- Chapter05/Stack.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Chapter05/Stack.py b/Chapter05/Stack.py index 0c1db3d..3e01863 100644 --- a/Chapter05/Stack.py +++ b/Chapter05/Stack.py @@ -43,11 +43,10 @@ def peek(self): -words = stack() -words.push('4') -words.push('5') -words.push('6') -words.push('7') +words = Stack() +words.push('egg') +words.push('ham') +words.push('spam') #print the stack elements. current = words.top From a316b32e775cb36751f3fe0d8e5d850708ffdd91 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Tue, 7 Jun 2022 16:16:54 +0530 Subject: [PATCH 19/53] Update --- Chapter05/List_based_queue.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/Chapter05/List_based_queue.py b/Chapter05/List_based_queue.py index a9f72e2..bf1a9ce 100644 --- a/Chapter05/List_based_queue.py +++ b/Chapter05/List_based_queue.py @@ -23,12 +23,22 @@ def dequeue(self): -q= ListQueue() -q.enqueue(4) -q.enqueue('dog') -q.enqueue('cat') -q.enqueue('monday') +q = ListQueue() +q.enqueue(20) +q.enqueue(30) +q.enqueue(40) +q.enqueue(50) +print(q.items) +#Queue is full +#[20, 30, 40] -a= q.size1() +data = q.dequeue() +print(data) +print(q.items) +#20 +#[30, 40] + + +a = q.size1() print(a) From e1da4651c7d37ac7a1042732ec1092fb4d163653 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Tue, 7 Jun 2022 16:42:48 +0530 Subject: [PATCH 20/53] Update --- Chapter07/heap.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Chapter07/heap.py b/Chapter07/heap.py index 4d9b8f2..ee0aa33 100644 --- a/Chapter07/heap.py +++ b/Chapter07/heap.py @@ -51,7 +51,6 @@ def delete_at_location(self, location): h = MinHeap() for i in ( 4, 8, 7, 2, 9, 10, 5, 1, 3, 6): h.insert(i) - print(h.heap) n = h.delete_at_root() From b20db73a46528f981f6c0ebf4d4988d7de080a24 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Tue, 7 Jun 2022 16:45:38 +0530 Subject: [PATCH 21/53] Update --- Chapter07/heap_sort.py | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/Chapter07/heap_sort.py b/Chapter07/heap_sort.py index 085f18a..39f7a92 100644 --- a/Chapter07/heap_sort.py +++ b/Chapter07/heap_sort.py @@ -1,4 +1,4 @@ -class minHeap: +class MinHeap: def __init__(self): self.heap = [0] self.size = 0 @@ -55,36 +55,28 @@ def heap_sort(self): -h = minHeap() +h = MinHeap() for i in ( 4, 8, 7, 2, 9, 10, 5, 1, 3, 6): h.insert(i) - print(h.heap) -h = minHeap() +h = MinHeap() unsorted_list = [4, 8, 7, 2, 9, 10, 5, 1, 3, 6] - - for i in unsorted_list: h.insert(i) - print("Unsorted list: {}".format(unsorted_list)) -h = minHeap() +h = MinHeap() unsorted_list = [4, 8, 7, 2, 9, 10, 5, 1, 3, 6] - - for i in unsorted_list: h.insert(i) - print("Unsorted list: {}".format(unsorted_list)) - print("Sorted list: {}".format(h.heap_sort())) From 2aa132784c151d950edc0b08bc54ff11cd3d4e0a Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Tue, 7 Jun 2022 17:04:10 +0530 Subject: [PATCH 22/53] Update --- Chapter08/hashtable_chaining.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Chapter08/hashtable_chaining.py b/Chapter08/hashtable_chaining.py index 96dcc12..0f0d006 100644 --- a/Chapter08/hashtable_chaining.py +++ b/Chapter08/hashtable_chaining.py @@ -34,14 +34,14 @@ def search(self, key): current = self.head while current: if current.key == key: - print("list ",current.key, current.value) + print("\"Record found:", current.key, "-", current.value, "\"") return True current = current.next return False -class HashTable: +class HashTableChaining: def __init__(self): self.size = 6 self.slots = [None for i in range(self.size)] @@ -79,7 +79,7 @@ def printHashTable(self) : -ht = HashTable() +ht = HashTableChaining() ht.put("good", "eggs") ht.put("better", "ham") ht.put("best", "spam") @@ -99,4 +99,4 @@ def printHashTable(self) : print(v) -ht.printHashTable() +ht.printHashTable() From 221d740750e8c117b6739d5b07307341d4a13b7e Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Tue, 7 Jun 2022 17:24:42 +0530 Subject: [PATCH 23/53] Update --- Chapter08/hashtable.py | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/Chapter08/hashtable.py b/Chapter08/hashtable.py index 2429567..d6f986a 100644 --- a/Chapter08/hashtable.py +++ b/Chapter08/hashtable.py @@ -10,7 +10,7 @@ def __init__(self): self.slots = [None for i in range(self.size)] self.count = 0 self.MAXLOADFACTOR = 0.65 - + self.prime_num = 5 def check_growth(self): loadfactor = self.count / self.size @@ -97,7 +97,7 @@ def h2(self, key): return hv - def put_doubleHashing(self, key, value): + def put_double_hashing(self, key, value): item = HashItem(key, value) h = self._hash(key) j = 1 @@ -111,7 +111,7 @@ def put_doubleHashing(self, key, value): self.slots[h] = item self.check_growth() - def get_doubleHashing(self, key): + def get_double_hashing(self, key): h = self._hash(key) j = 1 while self.slots[h] != None: @@ -129,6 +129,15 @@ def __setitem__(self, key, value): def __getitem__(self, key): return self.get(key) + + + +ht = HashTable() +ht.put_quadratic(“good”, “eggs”) +ht.put_quadratic(“ad”, “packt”) +ht.put_quadratic(“ga”, “books”) +v = ht.get_quadratic(“ga”) +print(v) ht = HashTable() @@ -136,13 +145,28 @@ def __getitem__(self, key): ht.put("better", "ham") ht.put("best", "spam") ht.put("ad", "do not") -ht.put("ga", "collide") +ht.put("ga", "collide") +ht.put(“awd”, “do not”) +ht.put(“add”, “do not”) +ht.checkGrow() for key in ("good", "better", "best", "worst", "ad", "ga"): v = ht.get(key) print(v) - + +ht = HashTable() +ht.put_double_hashing(“good”, “eggs”) +ht.put_double_hashing(“better”, “spam”) +ht.put_double_hashing(“best”, “cool”) +ht.put_double_hashing(“ad”, “donot”) +ht.put_double_hashing(“ga”, “collide”) +ht.put_double_hashing(“awd”, “hello”) +ht.put_double_hashing(“addition”, “ok”) +for key in (“good”, “better”, “best”, “worst”, “ad”, “ga”): +v = ht.get_double_hashing(key) +print(v) +print(“The number of elements is: {}”.format(ht.count)) ht = HashTable() From 33b630c394334458261df6d0e354556744aba67d Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Wed, 8 Jun 2022 17:22:24 +0530 Subject: [PATCH 24/53] Update --- Chapter04/append_at_any_location_singly_linkedlist.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Chapter04/append_at_any_location_singly_linkedlist.py b/Chapter04/append_at_any_location_singly_linkedlist.py index b5e8f80..c2e1f2f 100644 --- a/Chapter04/append_at_any_location_singly_linkedlist.py +++ b/Chapter04/append_at_any_location_singly_linkedlist.py @@ -7,6 +7,7 @@ def __init__(self, data=None): class SinglyLinkedList: def __init__ (self): + self.tail = None self.head = None self.size = 0 From f925219717c56368a2fa58b3cb105f20713d3dd7 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Wed, 8 Jun 2022 17:30:14 +0530 Subject: [PATCH 25/53] Update --- Chapter04/delete_operation_singly_linkedlist.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Chapter04/delete_operation_singly_linkedlist.py b/Chapter04/delete_operation_singly_linkedlist.py index be5c04c..a12126d 100644 --- a/Chapter04/delete_operation_singly_linkedlist.py +++ b/Chapter04/delete_operation_singly_linkedlist.py @@ -61,7 +61,6 @@ def delete(self, data): words.delete_last_node() - current = words.tail while current: print(current.data) @@ -70,7 +69,7 @@ def delete(self, data): words.delete('ham') -current = words.tail +current = words.head while current: print(current.data) current = current.next From 5e450f95bc7be8bcee8966b574be1e80effc6252 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Wed, 8 Jun 2022 17:32:49 +0530 Subject: [PATCH 26/53] Update --- Chapter04/doubly_linked_list.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Chapter04/doubly_linked_list.py b/Chapter04/doubly_linked_list.py index 44a9511..e53ee67 100644 --- a/Chapter04/doubly_linked_list.py +++ b/Chapter04/doubly_linked_list.py @@ -1,4 +1,4 @@ -class Node(object): +class Node: def __init__ (self, data = None, next = None, prev = None): self.data = data self.next = next From 0674277494651a5aef9b2cc1cd1723cb3197c9b9 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Wed, 8 Jun 2022 17:52:00 +0530 Subject: [PATCH 27/53] Update --- Chapter04/doubly_linked_list.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Chapter04/doubly_linked_list.py b/Chapter04/doubly_linked_list.py index e53ee67..3538740 100644 --- a/Chapter04/doubly_linked_list.py +++ b/Chapter04/doubly_linked_list.py @@ -11,7 +11,7 @@ def __init__ (self): self.count = 0 def append(self, data): - #Append an item to the list. + #Append an item at the end of the list. new_node = Node(data, None, None) if self.head is None: self.head = new_node From d8ebfbb9ad211d81d44795d8e6d10978b4d2e583 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Wed, 8 Jun 2022 18:14:49 +0530 Subject: [PATCH 28/53] Update --- Chapter04/doubly_linked_list.py | 49 ++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/Chapter04/doubly_linked_list.py b/Chapter04/doubly_linked_list.py index 3538740..4eb2f94 100644 --- a/Chapter04/doubly_linked_list.py +++ b/Chapter04/doubly_linked_list.py @@ -4,7 +4,7 @@ def __init__ (self, data = None, next = None, prev = None): self.next = next self.prev = prev -class DoublyLinkedList(object): +class DoublyLinkedList: def __init__ (self): self.head = None self.tail = None @@ -49,6 +49,23 @@ def append_at_a_location(self, data): prev = current current = current.next + def iter(self): + current = self.head + while current: + val = current.data + current = current.next + yield val + + + def contains(self, data): + for node_data in self.iter(): + if data == node_data: + print(" Data item is present in the list. ") + return + print(" Data item is not present in the list. ") + return + + words = DoublyLinkedList() @@ -56,14 +73,44 @@ def append_at_a_location(self, data): words.append('ham') words.append('spam') +print("Items in doubly linked list before append") current = words.head while current: print(current.data) current = current.next +words.append_at_start('book') + +print("Items in doubly linked list after append") +current = words.head +while current: + print(current.data) + current = current.next + + +words.append('book') + +print("Items in doubly linked list after adding element at end.") +current = words.head +while current: + print(current.data) + current = current.next + + words.append_at_a_location('ham') +print("Doubly linked list after adding an element after word \"ham\" in the list.") current = words.head while current: print(current.data) current = current.next + + +words = DoublyLinkedList() +words.append('egg') +words.append('ham') +words.append('spam') + + +words.contains("ham") +words.contains("ham2") From 8a55bf7695abc35134a61c99e0605dc63d8e98e3 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Wed, 8 Jun 2022 18:17:28 +0530 Subject: [PATCH 29/53] Update --- .../delete_operation_singly_linkedlist.py | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/Chapter04/delete_operation_singly_linkedlist.py b/Chapter04/delete_operation_singly_linkedlist.py index a12126d..c181c0c 100644 --- a/Chapter04/delete_operation_singly_linkedlist.py +++ b/Chapter04/delete_operation_singly_linkedlist.py @@ -6,16 +6,16 @@ def __init__(self, data=None): class SinglyLinkedList: def __init__ (self): - self.tail = None + self.head = None self.size = 0 def append(self, data): # Encapsulate the data in a Node node = Node(data) - if self.tail is None: - self.tail = node + if self.head is None: + self.head = node else: - current = self.tail + current = self.head while current.next: current = current.next current.next = node @@ -29,8 +29,8 @@ def delete_first_node (self): def delete_last_node (self): - current = self.tail - prev = self.tail + current = self.head + prev = self.head while current: if current.next is None: prev.next = current.next @@ -40,12 +40,12 @@ def delete_last_node (self): def delete(self, data): - current = self.tail - prev = self.tail + current = self.head + prev = self.head while current: if current.data == data: - if current == self.tail: - self.tail = current.next + if current == self.head: + self.head = current.next else: prev.next = current.next self.size -= 1 @@ -59,9 +59,18 @@ def delete(self, data): words.append('ham') words.append('spam') +words.delete_first_node() + +current = words.head +while current: + print(current.data) + current = current.next + + words.delete_last_node() -current = words.tail + +current = words.head while current: print(current.data) current = current.next From 1e2d1c912456995a8fe67c78555e8d2c5e8ccd52 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Wed, 8 Jun 2022 18:19:09 +0530 Subject: [PATCH 30/53] Update --- Chapter04/CircularList.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Chapter04/CircularList.py b/Chapter04/CircularList.py index 16eed02..e179121 100644 --- a/Chapter04/CircularList.py +++ b/Chapter04/CircularList.py @@ -28,17 +28,26 @@ def append(self, data): def delete(self, data): current = self.head prev = self.head + flag = False while prev == current or prev != self.tail: if current.data == data: if current == self.head: + #item to be deleted is head node self.head = current.next self.tail.next = self.head + elif current == self.tail: + #item to be deleted is tail node + self.tail = prev + prev.next = self.head else: + #item to be deleted is an intermediate node prev.next = current.next self.size -= 1 return prev = current current = current.next + if flag is False: + print("Item not present in the list") def iter(self): @@ -93,11 +102,3 @@ def iter(self): counter += 1 if counter > 2: break - - - - - - - - From bf7b532eb6be783f67f66c37879e0fcd4b373044 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Wed, 15 Jun 2022 11:47:29 +0530 Subject: [PATCH 31/53] Update --- Chapter06/tree_traversal.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Chapter06/tree_traversal.py b/Chapter06/tree_traversal.py index cf3d41d..5b2a9b8 100644 --- a/Chapter06/tree_traversal.py +++ b/Chapter06/tree_traversal.py @@ -1,8 +1,8 @@ class Node: - def __init__(self, data): - self.data = data - self.right_child = None - self.left_child = None + def __init__(self, data): + self.data = data + self.right_child = None + self.left_child = None n1 = Node("root node") From 7e7b69726d316eafc96c3467784249b1487fbe60 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Wed, 15 Jun 2022 11:51:00 +0530 Subject: [PATCH 32/53] Update --- Chapter06/tree_traversal.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Chapter06/tree_traversal.py b/Chapter06/tree_traversal.py index 5b2a9b8..7314801 100644 --- a/Chapter06/tree_traversal.py +++ b/Chapter06/tree_traversal.py @@ -46,8 +46,8 @@ def postorder(root_node): print(current.data) -inorder( n1) +inorder(n1) print("\n" ) -preorder( n1) +preorder(n1) print("\n" ) postorder(n1) From 779240a24fa0df640c34937aa28ef7c0136fb1c5 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Wed, 15 Jun 2022 12:43:44 +0530 Subject: [PATCH 33/53] Update --- Chapter06/binary_search_tree.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Chapter06/binary_search_tree.py b/Chapter06/binary_search_tree.py index 1487152..e6107ce 100644 --- a/Chapter06/binary_search_tree.py +++ b/Chapter06/binary_search_tree.py @@ -112,8 +112,10 @@ def search(self, data): current = self.root_node while True: if current is None: + print("Item not found") return None elif current.data is data: + print("Item found", data) return data elif current.data > data: current = current.left_child From 1634534d6ea76c4b6d621962e68e7900e86f098f Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Mon, 27 Jun 2022 10:42:53 +0530 Subject: [PATCH 34/53] Update --- Chapter06/binary_search_tree.py | 46 +++++++++++++++++----------- Chapter10/binary_search_recursive.py | 3 +- Chapter10/jump_search.py | 35 +++++++++++---------- 3 files changed, 47 insertions(+), 37 deletions(-) diff --git a/Chapter06/binary_search_tree.py b/Chapter06/binary_search_tree.py index 1487152..c9ebdbd 100644 --- a/Chapter06/binary_search_tree.py +++ b/Chapter06/binary_search_tree.py @@ -12,7 +12,7 @@ def insert(self, data): node = Node(data) if self.root_node is None: self.root_node = node - return + return self.root_node else: current = self.root_node parent = None @@ -22,20 +22,20 @@ def insert(self, data): current = current.left_child if current is None: parent.left_child = node - return + return self.root_node else: current = current.right_child if current is None: parent.right_child = node - return + return self.root_node - def inorder(self): - current = self.root_node + def inorder(self, root_node): + current = root_node if current is None: return - inorder(current.left_child) + self.inorder(current.left_child) print(current.data) - inorder(current.right_child) + self.inorder(current.right_child) def get_node_with_parent(self, data): @@ -112,8 +112,10 @@ def search(self, data): current = self.root_node while True: if current is None: + print("Item not found") return None elif current.data is data: + print("Item found", data) return data elif current.data > data: current = current.left_child @@ -136,6 +138,23 @@ def find_max(self): +tree = Tree() +r = tree.insert(5) +r = tree.insert(2) +r = tree.insert(7) +r = tree.insert(9) +r = tree.insert(1) + +tree.inorder(r) + + + +tree.search(9) + + +tree.remove(9) +tree.search(9) + tree = Tree() tree.insert(5) tree.insert(2) @@ -143,14 +162,5 @@ def find_max(self): tree.insert(9) tree.insert(1) -tree.inorder() - -for i in range(1, 10): - found = tree.search(i) - print("{}: {}".format(i, found)) - - -print(tree.find_min()) - -print(tree.find_max()) - +print(tree.find_min()) +print(tree.find_max()) diff --git a/Chapter10/binary_search_recursive.py b/Chapter10/binary_search_recursive.py index 33c7e2a..8e6d7b2 100644 --- a/Chapter10/binary_search_recursive.py +++ b/Chapter10/binary_search_recursive.py @@ -12,8 +12,7 @@ def binary_search_recursive(ordered_list, first_element_index, last_element_inde return mid_point -store = [2, 4, 5, 12, 43, 54, 60, 77] -print(binary_search_recursive(store, 0, 7, 12)) + diff --git a/Chapter10/jump_search.py b/Chapter10/jump_search.py index 71a218f..1c52e93 100644 --- a/Chapter10/jump_search.py +++ b/Chapter10/jump_search.py @@ -10,33 +10,34 @@ def search_ordered(ordered_list, term): -def jump_search(A, item): +def jump_search(ordered_list, item): + import math print("Entering Jump Search") - n = len(A) - m = int(math.sqrt(n)) + list_size = len(ordered_list) + block_size = int(math.sqrt(list_size)) i = 0 - while i != len(A)-1 and A[i] <= item: - print("Block under consideration - {}".format(A[i: i+m])) - if i+m > len(A): - m = len(A) - i - B = A[i: i+m] - j = search_ordered(B, item) + while i != len(ordered_list)-1 and ordered_list[i] <= item: + print("Block under consideration - {}".format(ordered_list[i: i+block_size])) + if i+ block_size > len(ordered_list): + block_size = len(ordered_list) - i + block_list = ordered_list[i: i+block_size] + j = search_ordered(block_list, item) if j == -1: print("Element not found") return return i + j - if A[i+m-1] == item: - return i+m-1 - elif A[i+m-1] > item: - B = A[i: i+m-1] - j = search_ordered(B, item) + if ordered_list[i + block_size -1] == item: + return i+block_size-1 + elif ordered_list[i + block_size - 1] > item: + block_array = ordered_list[i: i + block_size - 1] + j = search_ordered(block_array, item) if j == -1: print("Element not found") - return + return return i + j - i += m + i += block_size -print(jump_search([1,2,3,4,5,6,7,8,9, 10, 11], 10)) +print(jump_search([1,2,3,4,5,6,7,8,9, 10, 11], 8)) From afa5fad4a78f6e1002c9cc723b2666c317d1c672 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Mon, 27 Jun 2022 10:44:36 +0530 Subject: [PATCH 35/53] Delete jump_search.py --- Chapter10/jump_search.py | 43 ---------------------------------------- 1 file changed, 43 deletions(-) delete mode 100644 Chapter10/jump_search.py diff --git a/Chapter10/jump_search.py b/Chapter10/jump_search.py deleted file mode 100644 index 1c52e93..0000000 --- a/Chapter10/jump_search.py +++ /dev/null @@ -1,43 +0,0 @@ -def search_ordered(ordered_list, term): - print("Entering Linear Search") - ordered_list_size = len(ordered_list) - for i in range(ordered_list_size): - if term == ordered_list[i]: - return i - elif ordered_list[i] > term: - return -1 - return -1 - - - -def jump_search(ordered_list, item): - import math - print("Entering Jump Search") - list_size = len(ordered_list) - block_size = int(math.sqrt(list_size)) - i = 0 - while i != len(ordered_list)-1 and ordered_list[i] <= item: - print("Block under consideration - {}".format(ordered_list[i: i+block_size])) - if i+ block_size > len(ordered_list): - block_size = len(ordered_list) - i - block_list = ordered_list[i: i+block_size] - j = search_ordered(block_list, item) - if j == -1: - print("Element not found") - return - return i + j - if ordered_list[i + block_size -1] == item: - return i+block_size-1 - elif ordered_list[i + block_size - 1] > item: - block_array = ordered_list[i: i + block_size - 1] - j = search_ordered(block_array, item) - if j == -1: - print("Element not found") - return - return i + j - i += block_size - - - -print(jump_search([1,2,3,4,5,6,7,8,9, 10, 11], 8)) - From 5302c446a64cc6d2b997489e25359d3ce7fbdf75 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Mon, 27 Jun 2022 10:45:06 +0530 Subject: [PATCH 36/53] Delete binary_search_tree.py --- Chapter06/binary_search_tree.py | 166 -------------------------------- 1 file changed, 166 deletions(-) delete mode 100644 Chapter06/binary_search_tree.py diff --git a/Chapter06/binary_search_tree.py b/Chapter06/binary_search_tree.py deleted file mode 100644 index c9ebdbd..0000000 --- a/Chapter06/binary_search_tree.py +++ /dev/null @@ -1,166 +0,0 @@ -class Node: - def __init__(self, data): - self.data = data - self.right_child = None - self.left_child = None - -class Tree: - def __init__(self): - self.root_node = None - - def insert(self, data): - node = Node(data) - if self.root_node is None: - self.root_node = node - return self.root_node - else: - current = self.root_node - parent = None - while True: - parent = current - if node.data < parent.data: - current = current.left_child - if current is None: - parent.left_child = node - return self.root_node - else: - current = current.right_child - if current is None: - parent.right_child = node - return self.root_node - - def inorder(self, root_node): - current = root_node - if current is None: - return - self.inorder(current.left_child) - print(current.data) - self.inorder(current.right_child) - - - def get_node_with_parent(self, data): - parent = None - current = self.root_node - if current is None: - return (parent, None) - while True: - if current.data == data: - return (parent, current) - elif current.data > data: - parent = current - current = current.left_child - else: - parent = current - current = current.right_child - return (parent, current) - - - def remove(self, data): - parent, node = self.get_node_with_parent(data) - - if parent is None and node is None: - return False - - # Get children count - children_count = 0 - - if node.left_child and node.right_child: - children_count = 2 - elif (node.left_child is None) and (node.right_child is None): - children_count = 0 - else: - children_count = 1 - - if children_count == 0: - if parent: - if parent.right_child is node: - parent.right_child = None - else: - parent.left_child = None - else: - self.root_node = None - elif children_count == 1: - next_node = None - if node.left_child: - next_node = node.left_child - else: - next_node = node.right_child - - if parent: - if parent.left_child is node: - parent.left_child = next_node - else: - parent.right_child = next_node - else: - self.root_node = next_node - else: - parent_of_leftmost_node = node - leftmost_node = node.right_child - while leftmost_node.left_child: - parent_of_leftmost_node = leftmost_node - leftmost_node = leftmost_node.left_child - node.data = leftmost_node.data - - if parent_of_leftmost_node.left_child == leftmost_node: - parent_of_leftmost_node.left_child = leftmost_node.right_child - else: - parent_of_leftmost_node.right_child = leftmost_node.right_child - - - - def search(self, data): - current = self.root_node - while True: - if current is None: - print("Item not found") - return None - elif current.data is data: - print("Item found", data) - return data - elif current.data > data: - current = current.left_child - else: - current = current.right_child - - - def find_min(self): - current = self.root_node - while current.left_child: - current = current.left_child - return current.data - - - def find_max(self): - current = self.root_node - while current.right_child: - current = current.right_child - return current.data - - - -tree = Tree() -r = tree.insert(5) -r = tree.insert(2) -r = tree.insert(7) -r = tree.insert(9) -r = tree.insert(1) - -tree.inorder(r) - - - -tree.search(9) - - -tree.remove(9) -tree.search(9) - -tree = Tree() -tree.insert(5) -tree.insert(2) -tree.insert(7) -tree.insert(9) -tree.insert(1) - -print(tree.find_min()) -print(tree.find_max()) From 5f56e6a92634593b76cdbebfbcf0c10bfed16480 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Mon, 27 Jun 2022 10:45:29 +0530 Subject: [PATCH 37/53] Update --- Chapter06/binary_search_tree.py | 166 ++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 Chapter06/binary_search_tree.py diff --git a/Chapter06/binary_search_tree.py b/Chapter06/binary_search_tree.py new file mode 100644 index 0000000..c9ebdbd --- /dev/null +++ b/Chapter06/binary_search_tree.py @@ -0,0 +1,166 @@ +class Node: + def __init__(self, data): + self.data = data + self.right_child = None + self.left_child = None + +class Tree: + def __init__(self): + self.root_node = None + + def insert(self, data): + node = Node(data) + if self.root_node is None: + self.root_node = node + return self.root_node + else: + current = self.root_node + parent = None + while True: + parent = current + if node.data < parent.data: + current = current.left_child + if current is None: + parent.left_child = node + return self.root_node + else: + current = current.right_child + if current is None: + parent.right_child = node + return self.root_node + + def inorder(self, root_node): + current = root_node + if current is None: + return + self.inorder(current.left_child) + print(current.data) + self.inorder(current.right_child) + + + def get_node_with_parent(self, data): + parent = None + current = self.root_node + if current is None: + return (parent, None) + while True: + if current.data == data: + return (parent, current) + elif current.data > data: + parent = current + current = current.left_child + else: + parent = current + current = current.right_child + return (parent, current) + + + def remove(self, data): + parent, node = self.get_node_with_parent(data) + + if parent is None and node is None: + return False + + # Get children count + children_count = 0 + + if node.left_child and node.right_child: + children_count = 2 + elif (node.left_child is None) and (node.right_child is None): + children_count = 0 + else: + children_count = 1 + + if children_count == 0: + if parent: + if parent.right_child is node: + parent.right_child = None + else: + parent.left_child = None + else: + self.root_node = None + elif children_count == 1: + next_node = None + if node.left_child: + next_node = node.left_child + else: + next_node = node.right_child + + if parent: + if parent.left_child is node: + parent.left_child = next_node + else: + parent.right_child = next_node + else: + self.root_node = next_node + else: + parent_of_leftmost_node = node + leftmost_node = node.right_child + while leftmost_node.left_child: + parent_of_leftmost_node = leftmost_node + leftmost_node = leftmost_node.left_child + node.data = leftmost_node.data + + if parent_of_leftmost_node.left_child == leftmost_node: + parent_of_leftmost_node.left_child = leftmost_node.right_child + else: + parent_of_leftmost_node.right_child = leftmost_node.right_child + + + + def search(self, data): + current = self.root_node + while True: + if current is None: + print("Item not found") + return None + elif current.data is data: + print("Item found", data) + return data + elif current.data > data: + current = current.left_child + else: + current = current.right_child + + + def find_min(self): + current = self.root_node + while current.left_child: + current = current.left_child + return current.data + + + def find_max(self): + current = self.root_node + while current.right_child: + current = current.right_child + return current.data + + + +tree = Tree() +r = tree.insert(5) +r = tree.insert(2) +r = tree.insert(7) +r = tree.insert(9) +r = tree.insert(1) + +tree.inorder(r) + + + +tree.search(9) + + +tree.remove(9) +tree.search(9) + +tree = Tree() +tree.insert(5) +tree.insert(2) +tree.insert(7) +tree.insert(9) +tree.insert(1) + +print(tree.find_min()) +print(tree.find_max()) From 0e7c85c8e66ce487081b0966bb6c3efb9b00bf71 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Mon, 27 Jun 2022 10:45:57 +0530 Subject: [PATCH 38/53] Update --- Chapter10/jump_search.py | 43 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 Chapter10/jump_search.py diff --git a/Chapter10/jump_search.py b/Chapter10/jump_search.py new file mode 100644 index 0000000..1c52e93 --- /dev/null +++ b/Chapter10/jump_search.py @@ -0,0 +1,43 @@ +def search_ordered(ordered_list, term): + print("Entering Linear Search") + ordered_list_size = len(ordered_list) + for i in range(ordered_list_size): + if term == ordered_list[i]: + return i + elif ordered_list[i] > term: + return -1 + return -1 + + + +def jump_search(ordered_list, item): + import math + print("Entering Jump Search") + list_size = len(ordered_list) + block_size = int(math.sqrt(list_size)) + i = 0 + while i != len(ordered_list)-1 and ordered_list[i] <= item: + print("Block under consideration - {}".format(ordered_list[i: i+block_size])) + if i+ block_size > len(ordered_list): + block_size = len(ordered_list) - i + block_list = ordered_list[i: i+block_size] + j = search_ordered(block_list, item) + if j == -1: + print("Element not found") + return + return i + j + if ordered_list[i + block_size -1] == item: + return i+block_size-1 + elif ordered_list[i + block_size - 1] > item: + block_array = ordered_list[i: i + block_size - 1] + j = search_ordered(block_array, item) + if j == -1: + print("Element not found") + return + return i + j + i += block_size + + + +print(jump_search([1,2,3,4,5,6,7,8,9, 10, 11], 8)) + From db85b75f2878c545771f30d1964c44a9eb7573be Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Tue, 28 Jun 2022 17:30:43 +0530 Subject: [PATCH 39/53] Update --- Chapter10/jump_search.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Chapter10/jump_search.py b/Chapter10/jump_search.py index 1c52e93..3393126 100644 --- a/Chapter10/jump_search.py +++ b/Chapter10/jump_search.py @@ -19,7 +19,7 @@ def jump_search(ordered_list, item): while i != len(ordered_list)-1 and ordered_list[i] <= item: print("Block under consideration - {}".format(ordered_list[i: i+block_size])) if i+ block_size > len(ordered_list): - block_size = len(ordered_list) - i + block_size = len(ordered_list) - i block_list = ordered_list[i: i+block_size] j = search_ordered(block_list, item) if j == -1: From 344e59937f6487bd1a097bc40d2151f28ffa8e41 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Tue, 28 Jun 2022 17:37:46 +0530 Subject: [PATCH 40/53] Update --- Chapter10/binary_search_recursive.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Chapter10/binary_search_recursive.py b/Chapter10/binary_search_recursive.py index 16c9b45..8e6d7b2 100644 --- a/Chapter10/binary_search_recursive.py +++ b/Chapter10/binary_search_recursive.py @@ -2,7 +2,7 @@ def binary_search_recursive(ordered_list, first_element_index, last_element_inde if (last_element_index < first_element_index): return None else: - mid_point = first_element_index + ((last_element_index - first_element_index) / 2) + mid_point = first_element_index + ((last_element_index - first_element_index) // 2) if ordered_list[mid_point] > term: return binary_search_recursive(ordered_list, first_element_index, mid_point-1,term) From a95df12c0eabab1794aa07ceffa47974963ecc1a Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Tue, 28 Jun 2022 17:40:45 +0530 Subject: [PATCH 41/53] Update --- Chapter10/interpolation_search.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Chapter10/interpolation_search.py b/Chapter10/interpolation_search.py index 8bec8be..16b80f8 100644 --- a/Chapter10/interpolation_search.py +++ b/Chapter10/interpolation_search.py @@ -22,8 +22,8 @@ def interpolation_search(ordered_list, search_value): -store = [44, 60, 75, 100, 120, 230, 250] -a = interpolation_search(store, 120) +list1 = [44, 60, 75, 100, 120, 230, 250] +a = interpolation_search(list1, 120) print("Index position of value 2 is ", a) -print(nearest_mid(store, 0, 6, 120)) +print(nearest_mid(list1, 0, 6, 120)) From ce04091d4e621283a349fef67ae9ccb8053ff66f Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Tue, 28 Jun 2022 17:46:18 +0530 Subject: [PATCH 42/53] Update --- Chapter10/exponential_search.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Chapter10/exponential_search.py b/Chapter10/exponential_search.py index e5ccd41..da87ab8 100644 --- a/Chapter10/exponential_search.py +++ b/Chapter10/exponential_search.py @@ -2,7 +2,7 @@ def binary_search_recursive(ordered_list, first_element_index, last_element_inde if (last_element_index < first_element_index): return None else: - mid_point = first_element_index + ((last_element_index - first_element_index) / 2) + mid_point = first_element_index + ((last_element_index - first_element_index) // 2) if ordered_list[mid_point] > term: return binary_search_recursive (ordered_list, first_element_index, mid_point-1, term) elif ordered_list[mid_point] < term: From 174c216c1f42e1e15692db5de8fdf8b7d23749f8 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Mon, 3 Oct 2022 12:01:35 +0530 Subject: [PATCH 43/53] Update --- errata.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 errata.md diff --git a/errata.md b/errata.md new file mode 100644 index 0000000..146bda0 --- /dev/null +++ b/errata.md @@ -0,0 +1,18 @@ +# Errata, Corrections and Improvements +---------------------------------------------------- +If you find any mistakes in the third edition of Hands On Data Structures and Algorithms with Python book, or if you have suggestions for improvements, then please [raise an issue in this repository]([https://github.com/PacktPublishing/JavaScript-from-Beginner-to-Professional/issues](https://github.com/PacktPublishing/Hands-On-Data-Structures-and-Algorithms-with-Python-Third-Edition/issues)), or email to us. + +## Chapter 13, Page 403 - Fixing the reference to `ord` array + +There should be a reference calling to the `ord` array as `ord_text` in the `generate_hash` function. + +Incorrect code is: +``` +else: + hash_text[i] = ((hash_text[i-1] - ord_text[i-1]) + ord[i+len_pattern-1]) # calculating next hash value using previous value +``` +Correct code is: +``` +else: + hash_text[i] = ((hash_text[i-1] - ord_text[i-1]) + ord_text[i+len_pattern-1]) # calculating next hash value using previous value +``` From 27d279dee4772be41aea9194c277175205a0050c Mon Sep 17 00:00:00 2001 From: Packt-ITService <62882280+Packt-ITService@users.noreply.github.com> Date: Tue, 25 Oct 2022 08:24:19 +0100 Subject: [PATCH 44/53] add free ebook notification --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 12ec142..d0e681a 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,6 @@ # Hands-On Data-Structures-and-Algorithms-with-Python-Third-Edition-published-by-Packt Hands-On Data Structures and Algorithms with Python – Third Edition +### Download a free PDF + + If you have already purchased a print or Kindle version of this book, you can get a DRM-free PDF version at no cost.
Simply click on the link to claim your free PDF.
+

https://packt.link/free-ebook/9781801073448

\ No newline at end of file From ddecd4dfbf687cbd76548f30024d19027a4fb2f8 Mon Sep 17 00:00:00 2001 From: Packt-ITService <62882280+Packt-ITService@users.noreply.github.com> Date: Wed, 14 Dec 2022 13:10:40 +0530 Subject: [PATCH 45/53] add free ebook notification --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index d0e681a..156598c 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,15 @@ + +### Get this product for $5 + +Packt is having its biggest sale of the year. Get this eBook or any other book, video, or course that you like just for $5 each + + +

[Buy now](https://packt.link/9781801073448)

+ + +

[Buy similar titles for just $5](https://subscription.packtpub.com/search)

+ + # Hands-On Data-Structures-and-Algorithms-with-Python-Third-Edition-published-by-Packt Hands-On Data Structures and Algorithms with Python – Third Edition ### Download a free PDF From b0bf14743414e266e0e4e73e75d179859397b4c3 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Mon, 9 Jan 2023 18:26:29 +0530 Subject: [PATCH 46/53] Update binary_search.py --- Chapter03/binary_search.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Chapter03/binary_search.py b/Chapter03/binary_search.py index d07b955..8042a39 100644 --- a/Chapter03/binary_search.py +++ b/Chapter03/binary_search.py @@ -1,6 +1,6 @@ def binary_search(arr, start, end, key): while start <= end: - mid = start + (end - start)/2) + mid = start + (end - start)/2 if arr[mid] == key: return mid elif arr[mid] < key: From 515b4e6f42c08eba8bbe288878dedc33924460f6 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Tue, 10 Jan 2023 11:03:39 +0530 Subject: [PATCH 47/53] Update binary_search.py --- Chapter03/binary_search.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Chapter03/binary_search.py b/Chapter03/binary_search.py index 8042a39..09a6444 100644 --- a/Chapter03/binary_search.py +++ b/Chapter03/binary_search.py @@ -1,6 +1,6 @@ def binary_search(arr, start, end, key): while start <= end: - mid = start + (end - start)/2 + mid = start + (end - start)//2 if arr[mid] == key: return mid elif arr[mid] < key: From c8e9a280b290bd8c98c88b4d2c07e3f6e5b203c7 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Tue, 10 Jan 2023 11:12:43 +0530 Subject: [PATCH 48/53] Update errata.md --- errata.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/errata.md b/errata.md index 146bda0..ed12f49 100644 --- a/errata.md +++ b/errata.md @@ -16,3 +16,20 @@ Correct code is: else: hash_text[i] = ((hash_text[i-1] - ord_text[i-1]) + ord_text[i+len_pattern-1]) # calculating next hash value using previous value ``` + +## Chapter 3, Page 61 - Fixed the missing '/' + +There should be `//` in place of `/` + +Incorrect code is: +``` +mid = start + (end - start)/2 +if arr[mid] == key: + return mid +``` +Correct code is: +``` +mid = start + (end - start)//2 +if arr[mid] == key: + return mid +``` From da959a8ae7b88e214901e0cfdd2ad2f2478e1f83 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Tue, 10 Jan 2023 11:14:13 +0530 Subject: [PATCH 49/53] Update errata.md --- errata.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/errata.md b/errata.md index ed12f49..b529c3f 100644 --- a/errata.md +++ b/errata.md @@ -22,13 +22,13 @@ else: There should be `//` in place of `/` Incorrect code is: -``` +```python mid = start + (end - start)/2 if arr[mid] == key: return mid ``` Correct code is: -``` +```python mid = start + (end - start)//2 if arr[mid] == key: return mid From 16ae778fde5dd7f6266cdbb9aa8f6436087cbd58 Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Tue, 10 Jan 2023 11:15:12 +0530 Subject: [PATCH 50/53] Update errata.md --- errata.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/errata.md b/errata.md index b529c3f..1ea38f0 100644 --- a/errata.md +++ b/errata.md @@ -17,7 +17,7 @@ else: hash_text[i] = ((hash_text[i-1] - ord_text[i-1]) + ord_text[i+len_pattern-1]) # calculating next hash value using previous value ``` -## Chapter 3, Page 61 - Fixed the missing '/' +## Chapter 3, Page 61 - Fixed the missing '/' in **binary search** code There should be `//` in place of `/` From b76dabd10b4a047102d31ec7db4f8f1013ac46df Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Tue, 10 Jan 2023 11:15:37 +0530 Subject: [PATCH 51/53] Update errata.md --- errata.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/errata.md b/errata.md index 1ea38f0..a68ce37 100644 --- a/errata.md +++ b/errata.md @@ -17,7 +17,7 @@ else: hash_text[i] = ((hash_text[i-1] - ord_text[i-1]) + ord_text[i+len_pattern-1]) # calculating next hash value using previous value ``` -## Chapter 3, Page 61 - Fixed the missing '/' in **binary search** code +## Chapter 3, Page 61 - Fixed the missing '/' in `binary search` code There should be `//` in place of `/` From ac7828fe06d7e6591ce342de2e30aaf6578868e8 Mon Sep 17 00:00:00 2001 From: Packt-ITService <62882280+Packt-ITService@users.noreply.github.com> Date: Wed, 18 Jan 2023 15:20:57 +0530 Subject: [PATCH 52/53] remove 5$ campaign - 2022 --- README.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/README.md b/README.md index 156598c..94bd315 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,4 @@ -### Get this product for $5 - -Packt is having its biggest sale of the year. Get this eBook or any other book, video, or course that you like just for $5 each - - -

[Buy now](https://packt.link/9781801073448)

- - -

[Buy similar titles for just $5](https://subscription.packtpub.com/search)

# Hands-On Data-Structures-and-Algorithms-with-Python-Third-Edition-published-by-Packt From f234dae2579165320218f49dbd0d9675507113bb Mon Sep 17 00:00:00 2001 From: Karan <50290386+Sonawane-Karan26@users.noreply.github.com> Date: Mon, 6 Mar 2023 13:16:21 +0530 Subject: [PATCH 53/53] Update errata.md --- errata.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/errata.md b/errata.md index a68ce37..9cc9cd7 100644 --- a/errata.md +++ b/errata.md @@ -33,3 +33,20 @@ mid = start + (end - start)//2 if arr[mid] == key: return mid ``` + + +## Chapter 1, Page 23 - Fixed the missing outputs + +This is the actual dictionary +`mydict = {'a': 1, 'b': 2, 'c': 3}` + +|Function |Description |Example| +| :-------:| :-------: | :-------: | +| `mydict.pop()`| If a given key is present in the dictionary, then this function will remove the key and return the associated value. | `print(mydict.pop('b'))` should give you output `2` | +| `| | `print(mydict)` should give you output `{'a': 1, 'c': 3}` | +| `mydict.popitem()`| This method removes the last key-value pair added in the dictionary and returns it as a tuple. | `print(mydict.popitem())` should give you output `('c', 3)` | +| `| | `print(mydict)` should give you output `{'a': 1, 'b': 2}` | +| `mydict.update()`| Merges one dictionary with another. Firstly, it checks whether a key of the second dictionary is present in the fi rst dictionary; the corresponding value is then updated. If the key is not present in the fi rst dictionary, then the key-value pair is added. | It has two dictionaries as `d1 = {'a': 10, 'b': 20, 'c': 30}` and `d2 = {'b': 200, 'd': 400}`| +| | | `d1.update(d2)` should update values of `d2` on `d1` | +| | | `print(d1)` should give you `{'a': 10, 'b': 200, 'c': 30, 'd': 400}` | +