Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Цителадзе лаб 2 вар 6 5030102/20001 #147

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
ЛАБА 2 ВАРИАНТ 6
Написать рекурсивные процедуры добавления, сцепления и расцепления для treaps
без ссылок на предков.






Пусть x и y - две бинарных последовательности (т.е. элементы последовательностей -
нули и единицы); x и y можно рассматривать как запись в двоичной форме некоторых двух
натуральных чисел. Найти максимальное число z, двоичную запись которого можно
получить вычеркиванием цифр как из x, так и из y. Ответ выдать в виде бинарной
последовательности.
79 changes: 79 additions & 0 deletions lab1/Source.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#include <stdio.h>
#include <string.h>
#include <locale.h>

#define max(a, b) ((a) > (b) ? (a) : (b))

void mLCS(const char* x, const char* y, char* lcs) {
int m = strlen(x);
int n = strlen(y);
int dmtx[100][100] = { 0 };
for (int i = 0; i <= m; ++i) {
for (int j = 0; j <= n; ++j) {
dmtx[i][j] = 0;
}
}

for (int i = 1; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
if (x[i - 1] == y[j - 1]) {
dmtx[i][j] = dmtx[i - 1][j - 1] + 1;
}
else {
dmtx[i][j] = max(dmtx[i - 1][j], dmtx[i][j - 1]);
}
}
}

int len = dmtx[m][n];
lcs[len] = '\0';

int i = m, j = n;
while (i > 0 && j > 0) {
if (x[i - 1] == y[j - 1]) {
lcs[--len] = x[i - 1];
--i;
--j;
}
else if (dmtx[i - 1][j] > dmtx[i][j - 1]) {
--i;
}
else {
--j;
}
}
}

void testing() {
struct TestCase {
const char* x;
const char* y;
const char* z;
};

struct TestCase tests[] = {
{"11011011", "11101111", "1101111"},
{"10101", "11111", "111"},
{"0", "1", ""},
{"1011111", "10111111", "1011111"},
{"", "", ""},
};

for (int i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) {
char result[100];
mLCS(tests[i].x, tests[i].y, result);
if (strcmp(result, tests[i].z) == 0) {
printf("���� %d �������\n", i + 1);
}
else {
printf("������ � ����� %d: ��������� %s, �������� %s\n", i + 1, tests[i].z, result);
}
}
}

int main() {
setlocale(LC_CTYPE, "Russian");
printf("��������� 5030102/20001\n������� 1, ������� 9\n\n");
testing();
return 0;
}
243 changes: 243 additions & 0 deletions lab2/Source.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
#include <stdio.h>
#include <locale.h>
#include <stdlib.h>
#include <time.h>

struct treaps {
int key;
int val;
struct treaps* left;
struct treaps* right;
};

struct treaps* rhtgRotation(struct treaps* y) {
struct treaps* x = y->left;
struct treaps* T2 = x->right;
x->right = y;
y->left = T2;
return x;
}

struct treaps* lftRotation(struct treaps* x) {
struct treaps* y = x->right;
struct treaps* T2 = y->left;
y->left = x;
x->right = T2;
return y;
}

struct treaps* newNode(int key) {
struct treaps* temp = (struct treaps*)malloc(sizeof(struct treaps));
temp->key = key;
temp->val = rand() % 100;
temp->left = temp->right = NULL;
return temp;
}

struct treaps* insert(struct treaps* root, int key) {
if (!root)
return newNode(key);

if (key <= root->key) {
root->left = insert(root->left, key);

if (root->left && root->left->val > root->val)
root = rhtgRotation(root);
}
else {
root->right = insert(root->right, key);

if (root->right && root->right->val > root->val)
root = lftRotation(root);
}
return root;
}

struct treaps* join(struct treaps* left, struct treaps* right) {
if (!left) return right;
if (!right) return left;

if (left->val > right->val) {
left->right = join(left->right, right);
return left;
}
else {
right->left = join(left, right->left);
return right;
}
}

void split(struct treaps* root, int key, struct treaps** left, struct treaps** right) {
if (!root) {
*left = *right = NULL;
}
else if (key <= root->key) {
split(root->left, key, left, &root->left);
*right = root;
}
else {
split(root->right, key, &root->right, right);
*left = root;
}
}

struct treaps* delNode(struct treaps* root, int key) {
if (!root)
return root;

if (key < root->key)
root->left = delNode(root->left, key);
else if (key > root->key)
root->right = delNode(root->right, key);
else {
struct treaps* temp = join(root->left, root->right);
free(root);
return temp;
}
return root;
}

void printTreap(struct treaps* root, int k) {
if (root == NULL) {
return;
}

printTreap(root->right, k + 1);

for (int i = 0; i < k; i++) {
printf("\t");
}
printf("%d(%d)\n", root->key, root->val);

printTreap(root->left, k + 1);
}


int compTreaps(struct treaps* first, struct treaps* second) {
if (first == NULL && second == NULL) {
return 1;
}
if (first == NULL || second == NULL) {
return 0;
}
if (first->key != second->key) {
return 0;
}
if (compTreaps(first->left, second->left) && compTreaps(first->right, second->right)) {
return 1;
}
return 0;
}



void testing() {
struct TestCase {
struct treaps* tree;
int key;
char* description;
struct treaps* afterdel;
struct treaps* afteradd;
};

struct TestCase tests[] = {
{NULL, 10, "Дерево без элементов",NULL, newNode(10)},
{newNode(5), 5, "Дерево с одним элементом",NULL, newNode(5)},
{insert(newNode(5),10),10,"Дерево с двумя элементами",newNode(5),insert(newNode(5),10)},
{insert(insert(newNode(5), 3), 7), 5, "Дерево с тремя элементами",insert(newNode(3),7),insert(insert(newNode(5), 3), 7)},
};

int numTests = sizeof(tests) / sizeof(tests[0]);

printf("Начало тестирования:\n");

for (int i = 0; i < numTests; ++i) {
printf("\nТест %d: %s\n", i + 1, tests[i].description);

// Удаление
if (tests[i].tree) {
printf("Удаление элемента: ", tests[i].key);
tests[i].tree = delNode(tests[i].tree, tests[i].key);
if (compTreaps(tests[i].tree,tests[i].afterdel)) {
printf("успешно\n");
}
else {printf("неуспешно\n"); }
}

// Вставка
printf("Добавление элемента: ", tests[i].key);
tests[i].tree = insert(tests[i].tree, tests[i].key);
if (compTreaps(tests[i].tree,tests[i].afteradd)) {
printf("успешно\n");
}
else {
printf("неуспешно\n");
}

struct treaps* left = NULL;
struct treaps* right = NULL;
split(tests[i].tree, tests[i].key, &left, &right);
if (i == 0) {
printf("Сцепление и расцепление невозможно\n");
continue;
}
if (/*left && right*/ compTreaps(join(left,right),tests[i].afteradd)) {
printf("Расцепление успешно\n");
printf("Сцепление успешно\n");
}
else {
printf("Расцепление неуспешно\n");
printf("Сцепление неуспешно\n");
}
}

printf("\nДЛЯ ДЕРЕВА С ТРЕМЯ ЭЛЕМЕНТАМИ РАБОТАЕТ НЕ ВСЕГДА ТАК КАК ПРИОРИТЕТ ЗАДАЁТСЯ СЛУЧАЙНО\n И ДАЖЕ ЕСЛИ ЕГО ПРЕДСКАЗЫВАТЬ, ТО ВСЁ РАВНО В ВИДУ ТОГО ЧТО ТЕСТЫ ДЛЯ СРАВНЕНИЯ СОЗДАЮТСЯ ПОСЛЕ СОЗДАНИЯ ДЕРЕВА\n ПРИОРИТЕТ МОЖЕТ ОТЛИЧАТЬСЯ\n");
printf("\nТестирование завершено.\n");
}




int main() {
tsitic marked this conversation as resolved.
Show resolved Hide resolved
setlocale(LC_CTYPE, "Russian");
srand(time(NULL));

struct treaps* root = NULL;
root = insert(root, 50);
root = insert(root, 30);
root = insert(root, 20);
root = insert(root, 40);
root = insert(root, 70);
root = insert(root, 60);
root = insert(root, 80);

printf("Дерево после вставок:\n\n");
printTreap(root, 0);

printf("\n\nУдаляем элемент с ключом 20\n\n");
root = delNode(root, 20);

printf("\nДерево после удаления:\n\n");
printTreap(root, 0);

struct treaps* left = NULL;
struct treaps* right = NULL;

printf("\n\nРасцепляем дерево по ключу 40\n\n");
split(root, 40, &left, &right);

printf("\n\n\nЛевое дерево:\n");
printTreap(left, 0);

printf("\n\n\nПравое дерево:\n");
printTreap(right, 0);

printf("\n\nСцепляем левое и правое деревья\n\n");
root = join(left, right);

printf("\n\nДерево после сцепления:\\n");
printTreap(root, 0);

testing();
return 0;
}