Sort

# bubble sort takes the biggest one to the behind at every cycle.
def bubblesort(arr):
    while True:
        flag = 0

        for i in range(len(arr) - 1):
            if arr[i] > arr[i+1]:
                arr[i], arr[i+1] = arr[i+1], arr[i]

                flag += 1

        print_array(arr)

        if flag == 0:
            break

    return arr
def selectionsort(arr):  # find the smallest and put it to the front
    for i in range(len(arr) - 1):
        min_i = i
        
        for j in range(i + 1, len(arr)):
            if arr[j] < arr[min_i]:
                min_i = j

        arr[i], arr[min_i] = arr[min_i], arr[i]

        print_array(arr)

    return arr
def insertionsort(arr):
    for i in range(1, len(arr)):
        new_index = i
        new_one = arr[i]
        
        for j in range(i-1, -1, -1):
            if new_one < arr[j]:
                arr[new_index] = arr[j]
                arr[j] = new_one
                new_index = j

    return arr

def teacher_insertionsort(arr):
    for i in range(1, len(arr)):
        for j in range(i):
            if arr[i-j-1] > arr[i-j]:
                arr[i-j-1], arr[i-j] = arr[i-j], arr[i-j-1]
def merge(arr1, arr2):
    print("merge:", arr1, arr2)
    arr = []

    p1 = 0
    p2 = 0

    while len(arr) <= len(arr1) + len(arr2):
        if arr1[p1] < arr2[p2]:
            arr.append(arr1[p1])

            p1 += 1
        elif arr1[p1] > arr2[p2]:
            arr.append(arr2[p2])

            p2 += 1
        elif arr1[p1] == arr2[p2]:
            arr.append(arr1[p1])
            arr.append(arr2[p2])

            p1 += 1
            p2 += 1

        if p1 == len(arr1):
            for i in range(len(arr2) - p2):
                arr.append(arr2[p2])

                p2 += 1

            break

        if p2 == len(arr2):
            for i in range(len(arr1) - p1):
                arr.append(arr1[p1])

                p1 += 1

            break

    return arr

def mergesort(arr):
    if len(arr) <= 1:
        return arr

    mid = len(arr) // 2

    left = mergesort(arr[:mid])
    right = mergesort(arr[mid:])

    return merge(left, right)

stack

class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

class Stack:
    def __init__(self):
        self.head = None

    def push(self, value):
        if self.head == None:
            self.head = Node(value)

            return

        new_node = self.head
        self.head = Node(value)
        self.head.next = new_node
        

    def pop(self):
        value = self.head.data
        self.head = self.head.next
        
        return value

    def peek(self):
        return self.head.data

    def is_empty(self):
        if self.head == None:
            return False
        else:
            return True

    def show(self):
        cur = self.head
        
        while cur.next != None:
            print(cur.data, "=>", end=" ")
            cur = cur.next
        print(cur.data)

s = Stack()

print(s.is_empty())

s.push(10)
s.push(20)
s.push(30)

s.show()

print(s.pop())

s.show()

print(s.peek())

print(s.is_empty())

Queue

class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

class Queue:
    def __init__(self):
        self.head = None
        self.tail = None

    def enqueue(self, value):
        new_node = Node(value)
        
        if self.is_empty():
            self.head = new_node
            self.tail = new_node
        else:
            self.tail.next = new_node
            self.tail = new_node
            

    def dequeue(self):
        d_node = self.head
        self.head = self.head.next

    def peek(self):
        return self.head

    def is_empty(self):
        if self.head == None:
            return True
        else:
            return False

    def showQueue(self):
        cur = self.head

        while cur.next != None:
            print(cur.data, "=>", end=" ")
            cur=cur.next
            
        print(cur.data)

q = Queue()

print(q.is_empty())

q.enqueue(10)
q.showQueue()
q.enqueue(20)
q.showQueue()
q.enqueue(30)
q.showQueue()
q.enqueue(40)
q.showQueue()

print(q.peek().data)

q.dequeue()

q.showQueue()

print(q.is_empty())

Hash

class LinkedTuple:
    def __init__(self):
        self.items = list()

    def add(self, key, value):
        self.items.append((key, value))

    def get(self, key):
        for k, v in self.items:
            if key == k:
                return v

class LinkedDict:
    def __init__(self):
        self.items = []

        for i in range(8):
            self.items.append(LinkedTuple())

    def put(self, key, value):
        self.items[hash(key) % len(self.items)].add(key, value)

    def get(self, key):
        return self.items[hash(key) % len(self.items)].get(key)

ld = LinkedDict()
ld.put("name", "garden")
print(ld.get("name"))