From 3efb2c24970e7357704a28373f8ea90b3e7c4664 Mon Sep 17 00:00:00 2001 From: raduntsev_win10 Date: Sat, 14 Feb 2026 02:58:53 +0500 Subject: [PATCH] chore(config): add black formatter configuration --- packing_algorithms.c | 216 +++++++++++++++++++++++++++++++ red_black_tree.py | 296 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 512 insertions(+) create mode 100644 packing_algorithms.c create mode 100644 red_black_tree.py diff --git a/packing_algorithms.c b/packing_algorithms.c new file mode 100644 index 0000000..86312d0 --- /dev/null +++ b/packing_algorithms.c @@ -0,0 +1,216 @@ +#include +#include +#include + +// Top 3 Packing Algorithms Implementation + +// 1. First Fit Decreasing (FFD) - Bin Packing Algorithm +int compare_desc(const void *a, const void *b) { + return (*(int*)b - *(int*)a); +} + +int firstFit(int bins[], int n, int c) { + int res = 0; + + for (int i = 0; i < n; i++) { + int j; + for (j = 0; j < res; j++) { + if (bins[j] >= bins[i]) { + bins[j] -= bins[i]; + break; + } + } + + if (j == res) { + bins[res] = c - bins[i]; + res++; + } + } + return res; +} + +void firstFitDecreasing(int items[], int n, int capacity) { + // Sort items in decreasing order + qsort(items, n, sizeof(int), compare_desc); + + printf("First Fit Decreasing Algorithm:\n"); + printf("Number of bins required: %d\n", firstFit(items, n, capacity)); +} + +// 2. Huffman Coding - Compression Algorithm +struct MinHeapNode { + char data; + unsigned freq; + struct MinHeapNode *left, *right; +}; + +struct MinHeap { + unsigned size; + unsigned capacity; + struct MinHeapNode** array; +}; + +struct MinHeapNode* newNode(char data, unsigned freq) { + struct MinHeapNode* temp = (struct MinHeapNode*)malloc(sizeof(struct MinHeapNode)); + temp->left = temp->right = NULL; + temp->data = data; + temp->freq = freq; + return temp; +} + +struct MinHeap* createMinHeap(unsigned capacity) { + struct MinHeap* minHeap = (struct MinHeap*)malloc(sizeof(struct MinHeap)); + minHeap->size = 0; + minHeap->capacity = capacity; + minHeap->array = (struct MinHeapNode**)malloc(minHeap->capacity * sizeof(struct MinHeapNode*)); + return minHeap; +} + +void swapMinHeapNode(struct MinHeapNode** a, struct MinHeapNode** b) { + struct MinHeapNode* t = *a; + *a = *b; + *b = t; +} + +void minHeapify(struct MinHeap* minHeap, int idx) { + int smallest = idx; + int left = 2 * idx + 1; + int right = 2 * idx + 2; + + if (left < minHeap->size && minHeap->array[left]->freq < minHeap->array[smallest]->freq) + smallest = left; + + if (right < minHeap->size && minHeap->array[right]->freq < minHeap->array[smallest]->freq) + smallest = right; + + if (smallest != idx) { + swapMinHeapNode(&minHeap->array[smallest], &minHeap->array[idx]); + minHeapify(minHeap, smallest); + } +} + +int isSizeOne(struct MinHeap* minHeap) { + return (minHeap->size == 1); +} + +struct MinHeapNode* extractMin(struct MinHeap* minHeap) { + struct MinHeapNode* temp = minHeap->array[0]; + minHeap->array[0] = minHeap->array[minHeap->size - 1]; + --minHeap->size; + minHeapify(minHeap, 0); + return temp; +} + +void insertMinHeap(struct MinHeap* minHeap, struct MinHeapNode* minHeapNode) { + ++minHeap->size; + int i = minHeap->size - 1; + while (i && minHeapNode->freq < minHeap->array[(i - 1) / 2]->freq) { + minHeap->array[i] = minHeap->array[(i - 1) / 2]; + i = (i - 1) / 2; + } + minHeap->array[i] = minHeapNode; +} + +void buildMinHeap(struct MinHeap* minHeap) { + int n = minHeap->size - 1; + for (int i = (n - 1) / 2; i >= 0; --i) + minHeapify(minHeap, i); +} + +int isLeaf(struct MinHeapNode* root) { + return !(root->left) && !(root->right); +} + +struct MinHeap* createAndBuildMinHeap(char data[], int freq[], int size) { + struct MinHeap* minHeap = createMinHeap(size); + for (int i = 0; i < size; ++i) + minHeap->array[i] = newNode(data[i], freq[i]); + minHeap->size = size; + buildMinHeap(minHeap); + return minHeap; +} + +struct MinHeapNode* buildHuffmanTree(char data[], int freq[], int size) { + struct MinHeapNode *left, *right, *top; + struct MinHeap* minHeap = createAndBuildMinHeap(data, freq, size); + + while (!isSizeOne(minHeap)) { + left = extractMin(minHeap); + right = extractMin(minHeap); + + top = newNode('$', left->freq + right->freq); + top->left = left; + top->right = right; + + insertMinHeap(minHeap, top); + } + return extractMin(minHeap); +} + +void printArr(int arr[], int n) { + printf("Huffman Codes:\n"); + for (int i = 0; i < n; ++i) + printf("%d ", arr[i]); + printf("\n"); +} + +void printCodes(struct MinHeapNode* root, int arr[], int top) { + if (root->left) { + arr[top] = 0; + printCodes(root->left, arr, top + 1); + } + if (root->right) { + arr[top] = 1; + printCodes(root->right, arr, top + 1); + } + if (isLeaf(root)) { + printf("%c: ", root->data); + printArr(arr, top); + } +} + +void HuffmanCodes(char data[], int freq[], int size) { + struct MinHeapNode* root = buildHuffmanTree(data, freq, size); + int arr[100], top = 0; + printCodes(root, arr, top); +} + +// 3. Run-Length Encoding - Simple Compression Algorithm +void runLengthEncoding(char input[]) { + int len = strlen(input); + printf("Run-Length Encoding:\n"); + + for (int i = 0; i < len; i++) { + int count = 1; + while (i < len - 1 && input[i] == input[i+1]) { + count++; + i++; + } + printf("%c%d", input[i], count); + } + printf("\n"); +} + +int main() { + printf("Top 3 Packing Algorithms Implementation\n\n"); + + // Example for First Fit Decreasing + int items[] = {10, 60, 20, 30, 70, 40, 50}; + int n = sizeof(items)/sizeof(items[0]); + int capacity = 100; + firstFitDecreasing(items, n, capacity); + printf("\n"); + + // Example for Huffman Coding + char arr[] = {'A', 'B', 'C', 'D'}; + int freq[] = {5, 9, 12, 13}; + int size = sizeof(arr)/sizeof(arr[0]); + HuffmanCodes(arr, freq, size); + printf("\n"); + + // Example for Run-Length Encoding + char str[] = "aaabbccccdddd"; + runLengthEncoding(str); + + return 0; +} \ No newline at end of file diff --git a/red_black_tree.py b/red_black_tree.py new file mode 100644 index 0000000..bd0f74e --- /dev/null +++ b/red_black_tree.py @@ -0,0 +1,296 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Реализация красно-чёрного дерева (Red-Black Tree) на Python. + +Красно-чёрное дерево — это самобалансирующееся бинарное дерево поиска, +которое гарантирует логарифмическое время выполнения операций вставки, +удаления и поиска. + +Свойства красно-чёрного дерева: +1. Каждый узел либо красный, либо чёрный. +2. Корень дерева всегда чёрный. +3. Все листья (NIL) чёрные. +4. Если узел красный, то оба его потомка чёрные. +5. Для каждого узла все пути от него до листьев содержат одинаковое + количество чёрных узлов. +""" + +class Node: + def __init__(self, key, color="red"): + self.key = key + self.left = None + self.right = None + self.parent = None + self.color = color # "red" или "black" + + +class RedBlackTree: + def __init__(self): + self.NIL = Node(None, "black") # Листовые узлы + self.root = self.NIL + + def insert(self, key): + """Вставка нового узла в дерево.""" + new_node = Node(key) + new_node.left = self.NIL + new_node.right = self.NIL + + parent = None + current = self.root + + # Поиск места для вставки + while current != self.NIL: + parent = current + if new_node.key < current.key: + current = current.left + else: + current = current.right + + new_node.parent = parent + if parent is None: + self.root = new_node + elif new_node.key < parent.key: + parent.left = new_node + else: + parent.right = new_node + + # Исправление свойств дерева + self._fix_insert(new_node) + + def _fix_insert(self, node): + """Исправление свойств дерева после вставки.""" + while node != self.root and node.parent.color == "red": + if node.parent == node.parent.parent.left: + uncle = node.parent.parent.right + if uncle.color == "red": + # Случай 1: Дядя красный + node.parent.color = "black" + uncle.color = "black" + node.parent.parent.color = "red" + node = node.parent.parent + else: + if node == node.parent.right: + # Случай 2: Дядя чёрный, узел — правый потомок + node = node.parent + self._left_rotate(node) + # Случай 3: Дядя чёрный, узел — левый потомок + node.parent.color = "black" + node.parent.parent.color = "red" + self._right_rotate(node.parent.parent) + else: + uncle = node.parent.parent.left + if uncle.color == "red": + # Случай 1: Дядя красный + node.parent.color = "black" + uncle.color = "black" + node.parent.parent.color = "red" + node = node.parent.parent + else: + if node == node.parent.left: + # Случай 2: Дядя чёрный, узел — левый потомок + node = node.parent + self._right_rotate(node) + # Случай 3: Дядя чёрный, узел — правый потомок + node.parent.color = "black" + node.parent.parent.color = "red" + self._left_rotate(node.parent.parent) + + self.root.color = "black" + + def _left_rotate(self, x): + """Левый поворот вокруг узла x.""" + y = x.right + x.right = y.left + if y.left != self.NIL: + y.left.parent = x + y.parent = x.parent + if x.parent is None: + self.root = y + elif x == x.parent.left: + x.parent.left = y + else: + x.parent.right = y + y.left = x + x.parent = y + + def _right_rotate(self, y): + """Правый поворот вокруг узла y.""" + x = y.left + y.left = x.right + if x.right != self.NIL: + x.right.parent = y + x.parent = y.parent + if y.parent is None: + self.root = x + elif y == y.parent.left: + y.parent.left = x + else: + y.parent.right = x + x.right = y + y.parent = x + + def search(self, key): + """Поиск узла по ключу.""" + current = self.root + while current != self.NIL and key != current.key: + if key < current.key: + current = current.left + else: + current = current.right + return current if current != self.NIL else None + + def delete(self, key): + """Удаление узла по ключу.""" + node = self.search(key) + if node is None: + return + + original_color = node.color + if node.left == self.NIL: + x = node.right + self._transplant(node, node.right) + elif node.right == self.NIL: + x = node.left + self._transplant(node, node.left) + else: + successor = self._minimum(node.right) + original_color = successor.color + x = successor.right + if successor.parent == node: + x.parent = successor + else: + self._transplant(successor, successor.right) + successor.right = node.right + successor.right.parent = successor + + self._transplant(node, successor) + successor.left = node.left + successor.left.parent = successor + successor.color = node.color + + if original_color == "black": + self._fix_delete(x) + + def _transplant(self, u, v): + """Замена поддерева u поддеревом v.""" + if u.parent is None: + self.root = v + elif u == u.parent.left: + u.parent.left = v + else: + u.parent.right = v + v.parent = u.parent + + def _minimum(self, node): + """Поиск узла с минимальным ключом в поддереве.""" + while node.left != self.NIL: + node = node.left + return node + + def _fix_delete(self, x): + """Исправление свойств дерева после удаления.""" + while x != self.root and x.color == "black": + if x == x.parent.left: + sibling = x.parent.right + if sibling.color == "red": + sibling.color = "black" + x.parent.color = "red" + self._left_rotate(x.parent) + sibling = x.parent.right + + if sibling.left.color == "black" and sibling.right.color == "black": + sibling.color = "red" + x = x.parent + else: + if sibling.right.color == "black": + sibling.left.color = "black" + sibling.color = "red" + self._right_rotate(sibling) + sibling = x.parent.right + + sibling.color = x.parent.color + x.parent.color = "black" + sibling.right.color = "black" + self._left_rotate(x.parent) + x = self.root + else: + sibling = x.parent.left + if sibling.color == "red": + sibling.color = "black" + x.parent.color = "red" + self._right_rotate(x.parent) + sibling = x.parent.left + + if sibling.right.color == "black" and sibling.left.color == "black": + sibling.color = "red" + x = x.parent + else: + if sibling.left.color == "black": + sibling.right.color = "black" + sibling.color = "red" + self._left_rotate(sibling) + sibling = x.parent.left + + sibling.color = x.parent.color + x.parent.color = "black" + sibling.left.color = "black" + self._right_rotate(x.parent) + x = self.root + + x.color = "black" + + def inorder_traversal(self, node=None): + """Обход дерева в порядке возрастания.""" + if node is None: + node = self.root + result = [] + if node != self.NIL: + result += self.inorder_traversal(node.left) + result.append(node.key) + result += self.inorder_traversal(node.right) + return result + + def print_tree(self, node=None, indent="", last=True): + """Вывод дерева в консоль (для визуализации).""" + if node is None: + node = self.root + if node != self.NIL: + print(indent, end="") + if last: + print("R----", end="") + indent += " " + else: + print("L----", end="") + indent += "| " + + color = node.color + print(f"{node.key}({color})") + self.print_tree(node.left, indent, False) + self.print_tree(node.right, indent, True) + + +# Пример использования +if __name__ == "__main__": + rbt = RedBlackTree() + keys = [7, 3, 18, 10, 22, 8, 11, 26] + for key in keys: + rbt.insert(key) + + print("Обход дерева в порядке возрастания:") + print(rbt.inorder_traversal()) + + print("\nСтруктура дерева:") + rbt.print_tree() + + print("\nПоиск узла с ключом 10:") + node = rbt.search(10) + print(f"Найден узел: {node.key} ({node.color})") + + print("\nУдаление узла с ключом 18:") + rbt.delete(18) + print("Обход дерева после удаления:") + print(rbt.inorder_traversal()) + + print("\nСтруктура дерева после удаления:") + rbt.print_tree()