Commit 8a0aa1ff authored by Ing. Petr Pauš, Ph.D.'s avatar Ing. Petr Pauš, Ph.D.
Browse files

Added solutions

parent 7874c392
Loading
Loading
Loading
Loading
+157 −0
Original line number Diff line number Diff line
# Prvek seznamu, musí mít data a taky odkaz na další prvek
class Node:
    def __init__(self, data):
        '''Nastaví data na danou hodnotu a odkaz na další nastaví na None'''
        self.data = data
        self.next = None

# Samotná třída pro seznam (LinkedList)
class LinkedList:
    def __init__(self):
        '''# Inicializace udělá jen prázdný seznam'''
        self.head = None # odkaz na první prvek je None

    def findIndex(self, index):
        current_node = self.head
        pos = 0

        if index == 0:
            return self.head

        while(current_node != None and pos+1 != index):
            pos += 1
            current_node = current_node.next

        return current_node
 
    def insertAtBegin(self, data):
        '''Vložení prvku na začátek seznamu. Vytvoří nový prvek a nastaví správně odkazy'''
        new_node = Node(data) # nový prvek
        if self.head is None: # pokud je seznam prázdný, je třeba nastavit počátek na nový prvek
            self.head = new_node
        else:
            new_node.next = self.head   # další prvek je hlava
            self.head = new_node  # a hlava bude nový prvek
        return True
 
    def insertAtIndex(self, data, index):
        '''Vložení prvku na daný index počítáno od 0.'''
        new_node = Node(data) 
        if index==0:
            self.insertAtBegin(data)
        else:
            current_node = self.findIndex(index)
            
            if current_node != None:
                new_node.next = current_node.next
                current_node.next = new_node
            else:
                return False
        return True
 
    def insertAtEnd(self, data):
        '''Vložení prvku na konec seznamu.'''
        new_node = Node(data)
        if self.head is None:
            self.head = new_node
            return True
 
        current_node = self.head
        while(current_node.next):
            current_node = current_node.next
 
        current_node.next = new_node
        return True
 
    def removeFirst(self):
        '''Odstraní první prvek.'''
        if(self.head == None):
            return False
 
        self.head = self.head.next
        return True
 
    def removeLast(self):
        '''Odstraní poslední prvek.'''
        if self.head is None:
            return False
 
        current_node = self.head
        while(current_node.next.next):
            current_node = current_node.next
 
        current_node.next = None
        return True
 
    def removeAtIndex(self, index):
        '''Odstraní prvek na indexu.'''
        if self.head == None:
            return False

        if index==0:
            self.removeFirst()
        else:
            current_node = self.findIndex(index)
 
            if current_node != None:
                current_node.next = current_node.next.next
            else:
                return False
        return True
 
    def removeNode(self, data):
        '''Odstraní podle dat.'''
        current_node = self.head
 
        if current_node.data == data:
            self.removeFirst()
            return True
 
        while(current_node != None and current_node.next.data != data):
            current_node = current_node.next
 
        if current_node == None:
            return False
        else:
            current_node.next = current_node.next.next
            return True
 
    def size(self):
        '''Vrátí velikost seznamu.'''
        size = 0
        if (self.head):
            current_node = self.head
            while(current_node):
                size += 1
                current_node = current_node.next
            return size
        else:
            return 0
 
    def __str__(self) -> str:
        '''Vrátí seznam ve stringu.'''
        result = ""
        current_node = self.head
        while(current_node):
            result += str(current_node.data) + ' '
            current_node = current_node.next
        return result

    def print(self):
        '''Vytiskne seznam.'''
        print(self)



ll = LinkedList()
ll.insertAtBegin(5)
ll.insertAtBegin(3)
ll.insertAtBegin(1)
ll.insertAtIndex(2,1)
ll.insertAtIndex(6,0)
ll.insertAtIndex(7,4)

ll.print()

ll.removeAtIndex(1)
ll.print()
 No newline at end of file
+197 −0
Original line number Diff line number Diff line
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

    def __str__(self):
        return str(self.data)

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

    def insert_at_begin(self, data) -> bool:
        new_node = Node(data)
        if self.head == None:
            self.head = new_node
        else:
            new_node.next = self.head
            self.head = new_node
        return True
    
    def __str__(self):
        current_node = self.head
        result = '[ '
        while current_node:
            result += str(current_node.data) + ' -> '
            current_node = current_node.next
        return result + ']'
    
    def find_index(self, index : int) -> Node:
        '''Najde predchazejici uzel danemu indexu'''
        if index==0:
            return None

        pos = 0
        current_node = self.head
        while current_node and pos+1<index:
            current_node = current_node.next
            pos += 1

        if not current_node:
            return None
        return current_node
    
    def insert_at_index(self, data, index : int) -> bool:
        if index == 0:
            self.insert_at_begin(data)
            return True
        
        prev_node = self.find_prev_index(index)
        if not prev_node:
            return False
        
        new_node = Node(data)
        new_node.next = prev_node.next
        prev_node.next = new_node
        return True
    
    def __len__(self) -> int:
        current_node = self.head
        l = 0
        while current_node:
            l += 1
            current_node = current_node.next

        return l
    
    def insert_at_end(self, data) -> bool:
        if self.head == None:
            return self.insert_at_begin(data)

        current_node = self.head
        while current_node.next:
            current_node = current_node.next
        
        new_node = Node(data)
        current_node.next = new_node

        return True
    
    def get_by_index(self, index : int):
        node = self.find_index(index+1)
        if node:
            return node.data
        else:
            return None
    
    def remove_at_begin(self):
        if not self.head:
            return None
        data = self.head.data
        self.head = self.head.next
        return data
    
    def remove_at_index(self, index : int):
        if index == 0:
            return self.remove_at_begin()
        node = self.find_index(index)
        if not node or not node.next:
            return None
        data = node.next.data
        node.next = node.next.next
        return data
    
    def remove_at_end(self):
        current_node = self.head
        if not current_node.next:
            return self.remove_at_begin()
        
        while current_node.next.next:
            current_node = current_node.next
        data = current_node.next.data
        current_node.next = None
        return data

    def clear(self):
        self.head = None

    def remove_data(self, data):
        if not self.head:
            return False
        current_node = self.head
        prev_node = None

        while current_node and current_node.data != data:
            prev_node = current_node
            current_node = current_node.next 

        if not prev_node:
            self.remove_at_begin()  
            return True 

        if current_node:
            prev_node.next = current_node.next
            return True
        return False    
    
    def __iter__(self):
        current_node = self.head
        while current_node:
            yield current_node
            current_node = current_node.next

    
l = LinkedList()
print(len(l))
print(l.remove_at_begin())
l.insert_at_begin(1)
l.insert_at_begin(2)
l.insert_at_begin(3)
l.insert_at_index(5,0)
l.insert_at_end(10)
print(len(l))
print(l)
print(l.get_by_index(0))
print(l.get_by_index(1))
print(l.get_by_index(2))
print(l.get_by_index(3))
print(l.get_by_index(4))
print(l.get_by_index(5))
print(l)

print(l.remove_at_index(0))
print(l)

print(l.remove_at_index(2))
print(l)

print(l.remove_at_index(2))
print(l)

print(l.remove_at_index(2))
print(l)

print(l.remove_at_index(3))
print(l)

print(l.remove_at_end())
print(l.remove_at_end())
print(l)

l.insert_at_begin(1)
l.insert_at_begin(2)
l.insert_at_begin(3)
l.insert_at_begin(1)
l.insert_at_begin(2)
l.insert_at_begin(3)

print(l)

l.remove_data(1)
l.remove_data(1)
l.remove_data(3)
print(l)

for node in l:
    print (node, ' -> ', end = '')

2024/04/bintree.py

0 → 100644
+118 −0
Original line number Diff line number Diff line
import random

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

    def __str__(self):
        return str(self.data)
    
class BinTree:
    def __init__(self) -> None:
        self.root = None

    def find(self, data) -> tuple[Node, Node]:
        current_node = self.root
        prev_node = None

        while current_node:
            if current_node.data < data:
                prev_node = current_node
                current_node = current_node.right
            elif current_node.data > data:
                prev_node = current_node
                current_node = current_node.left
            else:
                break
        
        return current_node, prev_node
    
            
    def insert(self, data) -> bool:
        current_node, prev_node = self.find(data)
        if current_node:
            return False
        
        new_node = Node(data)
        if not prev_node:
            self.root = new_node
            return True
        if prev_node.data < data:
            prev_node.right = new_node
        else:
            prev_node.left = new_node
        return True

    def print_recursive(self, node):
        if not node:
            return
        self.print_recursive(node.left)
        print(node.data, end=' ')
        self.print_recursive(node.right)

    def print(self):
        self.print_recursive(self.root)
        print()


    def remove_leaf(self, current:Node, prev:Node):
        if current==self.root:
            self.root = None
            return
        if prev.left == current:
            prev.left = None
        else:
            prev.right = None
    
    def remove_in_branch(self, current:Node, prev:Node):
        if not prev:
            self.root = current.left if current.left else current.right
            return
        if prev.left == current:
            prev.left = current.left if current.left else current.right
        else:
            prev.right = current.left if current.left else current.right

    def remove_in_tree(self, current:Node):
        tmp = current.left
        tmp_prev = current
        while tmp.right:
            tmp_prev = tmp
            tmp = tmp.right
        current.data = tmp.data
        if tmp.left:
            self.remove_in_branch(tmp, tmp_prev)
        else:
            self.remove_leaf(tmp, tmp_prev)
        
    def remove(self, data):
        current, prev = self.find(data)
        if not current:
            return False
        if current.left and current.right:
            self.remove_in_tree(current)
        elif current.left or current.right:
            self.remove_in_branch(current, prev)
        else:
            self.remove_leaf(current, prev)
        return True

        

# n=50
# numbers = []

# for x in range(n):
#     numbers.append(random.randint(-20,50))

# tree = BinTree()
# for x in numbers:
#     tree.insert(x)
# tree.print()


# tree.remove(1)
# tree.print()
        
 No newline at end of file

2024/04/bintree_rek.py

0 → 100644
+122 −0
Original line number Diff line number Diff line
import random

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

    def __str__(self):
        return str(self.data)
    
class BinTree:
    def __init__(self) -> None:
        self.root = None

    def find_recursive(self, data, node:Node, prev:Node) -> tuple[Node, Node]:
        if not node:
            return node, prev
        if node.data == data:
            return node, prev
        prev = node
        if data < node.data:
            return self.find_recursive(data, node.left, prev)
        else:
            return self.find_recursive(data, node.right, prev)

    def find(self, data) -> tuple[Node, Node]:
        prev = None
        return self.find_recursive(data, self.root, prev)
    
            
    def insert_recursive(self, node:Node, data) ->bool:
        if node.data==data:
            return False
        if (data>node.data):
            if not node.right:
                node.right = Node(data)
            else:
                self.insert_recursive(node.right, data)
        else:
            if not node.left:
                node.left = Node(data)
            else:
                self.insert_recursive(node.left, data)

    def insert(self, data) -> bool:
        if not self.root:
            self.root = Node(data)
            return True
        else:
            return self.insert_recursive(self.root, data)

    def print_recursive(self, node):
        if not node:
            return
        self.print_recursive(node.left)
        print(node.data, end=' ')
        self.print_recursive(node.right)

    def print(self):
        self.print_recursive(self.root)
        print()

    def remove_leaf(self, current:Node, prev:Node):
        if current==self.root:
            self.root = None
            return
        if prev.left == current:
            prev.left = None
        else:
            prev.right = None
    
    def remove_in_branch(self, current:Node, prev:Node):
        if not prev:
            self.root = current.left if current.left else current.right
            return
        if prev.left == current:
            prev.left = current.left if current.left else current.right
        else:
            prev.right = current.left if current.left else current.right

    def remove_in_tree(self, current:Node):
        tmp = current.left
        tmp_prev = current
        while tmp.right:
            tmp_prev = tmp
            tmp = tmp.right
        current.data = tmp.data
        if tmp.left:
            self.remove_in_branch(tmp, tmp_prev)
        else:
            self.remove_leaf(tmp, tmp_prev)
        
    def remove(self, data):
        current, prev = self.find(data)
        if not current:
            return False
        if current.left and current.right:
            self.remove_in_tree(current)
        elif current.left or current.right:
            self.remove_in_branch(current, prev)
        else:
            self.remove_leaf(current, prev)
        return True
        

n=50
numbers = [5,2,8,6,9,10,11]

#for x in range(n):
#    numbers.append(random.randint(-20,50))

tree = BinTree()
for x in numbers:
    tree.insert(x)
tree.print()

print (tree.find(5)[0], tree.find(5)[1])

#tree.remove(1)
tree.print()
        
 No newline at end of file
+45 −0
Original line number Diff line number Diff line
def binary_search_rek(arr:list, data:any, min:int, max:int) -> int:
    if min<=max:
        mid = (min+max)//2
        if data<arr[mid]:
            return binary_search_rek(arr, data, min, mid-1)
        elif data>arr[mid]:
            return binary_search_rek(arr,data,mid+1, max)
        else:
            return mid
    
    return None
    
def binary_search(arr:list, data:any) -> int:
    return binary_search_rek(arr, data, 0, len(arr)-1)


def binary_search_nonrek(arr:list, data:any) -> int:
    min = 0
    max = len(arr)-1
    while min<=max:
        mid = (min+max)//2
        if data<arr[mid]:
            max = mid-1
        elif data>arr[mid]:
            min = mid+1
        else:
            return mid
    
    return None



l = [1,2,5,9,11,15,17,18,20,30,50]

print(binary_search(l, 2))
print(binary_search(l, 11))
print(binary_search(l, 20))
print(binary_search(l, 50))

print(binary_search_nonrek(l, 2))
print(binary_search_nonrek(l, 11))
print(binary_search_nonrek(l, 20))
print(binary_search_nonrek(l, 50))

Loading