diff --git a/avlTreeNew/AVLTree/AVLTree.sln b/avlTreeNew/AVLTree/AVLTree.sln
new file mode 100644
index 0000000..1d6c315
--- /dev/null
+++ b/avlTreeNew/AVLTree/AVLTree.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31903.59
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AVLTree", "AVLTree\AVLTree.vcxproj", "{4324245A-4186-4376-87B3-D0293B15F24B}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {4324245A-4186-4376-87B3-D0293B15F24B}.Debug|x64.ActiveCfg = Debug|x64
+ {4324245A-4186-4376-87B3-D0293B15F24B}.Debug|x64.Build.0 = Debug|x64
+ {4324245A-4186-4376-87B3-D0293B15F24B}.Debug|x86.ActiveCfg = Debug|Win32
+ {4324245A-4186-4376-87B3-D0293B15F24B}.Debug|x86.Build.0 = Debug|Win32
+ {4324245A-4186-4376-87B3-D0293B15F24B}.Release|x64.ActiveCfg = Release|x64
+ {4324245A-4186-4376-87B3-D0293B15F24B}.Release|x64.Build.0 = Release|x64
+ {4324245A-4186-4376-87B3-D0293B15F24B}.Release|x86.ActiveCfg = Release|Win32
+ {4324245A-4186-4376-87B3-D0293B15F24B}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {4226DC63-DC3D-43E1-9341-646B92A145E2}
+ EndGlobalSection
+EndGlobal
diff --git a/avlTreeNew/AVLTree/AVLTree/AVLTree.vcxproj b/avlTreeNew/AVLTree/AVLTree/AVLTree.vcxproj
new file mode 100644
index 0000000..fca2ebb
--- /dev/null
+++ b/avlTreeNew/AVLTree/AVLTree/AVLTree.vcxproj
@@ -0,0 +1,153 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ Win32Proj
+ {4324245a-4186-4376-87b3-d0293b15f24b}
+ AVLTree
+ 10.0
+
+
+
+ Application
+ true
+ v143
+ Unicode
+
+
+ Application
+ false
+ v143
+ true
+ Unicode
+
+
+ Application
+ true
+ v143
+ Unicode
+
+
+ Application
+ false
+ v143
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ false
+
+
+ true
+
+
+ false
+
+
+
+ Level3
+ true
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+ Level3
+ false
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/avlTreeNew/AVLTree/AVLTree/AVLTree.vcxproj.filters b/avlTreeNew/AVLTree/AVLTree/AVLTree.vcxproj.filters
new file mode 100644
index 0000000..3ef73b8
--- /dev/null
+++ b/avlTreeNew/AVLTree/AVLTree/AVLTree.vcxproj.filters
@@ -0,0 +1,36 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Исходные файлы
+
+
+ Исходные файлы
+
+
+ Исходные файлы
+
+
+
+
+ Исходные файлы
+
+
+ Исходные файлы
+
+
+
\ No newline at end of file
diff --git a/avlTreeNew/AVLTree/AVLTree/avlTree.c b/avlTreeNew/AVLTree/AVLTree/avlTree.c
new file mode 100644
index 0000000..a00a30c
--- /dev/null
+++ b/avlTreeNew/AVLTree/AVLTree/avlTree.c
@@ -0,0 +1,306 @@
+#include "avlTree.h"
+#include
+#include
+#include
+#include
+
+typedef struct Value {
+ char key[100];
+ char* value;
+ int balance;
+} Value;
+
+typedef struct Node {
+ Value data;
+ struct Node* left;
+ struct Node* right;
+} Node;
+
+typedef struct Tree {
+ struct Node* root;
+} Tree;
+
+int orderForBalance(Node* root, bool* isBalanced, int height) {
+ if (root != NULL) {
+ int leftHeight = orderForBalance(root->left, isBalanced, height);
+ int rightHeight = orderForBalance(root->right, isBalanced, height);
+ if (rightHeight - leftHeight != root->data.balance) {
+ *isBalanced = false;
+ }
+ return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
+ }
+ return 0;
+}
+
+bool checkBalance(Tree* tree) {
+ bool isBalanced = true;
+ orderForBalance(tree->root, &isBalanced, 0);
+ return isBalanced;
+}
+
+Tree* createTree(void) {
+ Tree* tree = calloc(1, sizeof(Tree));
+ return tree;
+}
+
+Node* createElementTree(void) {
+ Node* temp = calloc(1, sizeof(Node));
+ return temp;
+}
+
+void helpedClearTree(Node* root) {
+ if (root != NULL) {
+ helpedClearTree(root->left);
+ helpedClearTree(root->right);
+ free(root->data.value);
+ free(root);
+ }
+}
+
+void clearTree(Tree* tree) {
+ if (tree == NULL) {
+ return;
+ }
+ helpedClearTree(tree->root);
+ free(tree);
+}
+
+Node* rotateLeft(Node* a) {
+ Node* b = a->right;
+ Node* c = b->left;
+ if (b->data.balance == 0) {
+ b->data.balance += 1;
+ a->data.balance += -1;
+ } else {
+ b->data.balance = 0;
+ a->data.balance = 0;
+ }
+ b->left = a;
+ a->right = c;
+ return b;
+}
+
+Node* rotateRight(Node* a) {
+ Node* b = a->left;
+ Node* c = b->right;
+ if (b->data.balance == 0) {
+ b->data.balance += -1;
+ a->data.balance += 1;
+ } else {
+ a->data.balance = 0;
+ b->data.balance = 0;
+ }
+ b->right = a;
+ a->left = c;
+ return b;
+}
+
+Node* balance(Node* node) {
+ if (node->data.balance == 2) {
+ if (node->right->data.balance >= 0) {
+ return rotateLeft(node);
+ }
+
+ node->right = rotateRight(node->right);
+ return rotateLeft(node);
+ }
+ if (node->data.balance == -2) {
+ if (node->left->data.balance <= 0) {
+ return rotateRight(node);
+ }
+
+ node->left = rotateLeft(node->left);
+ return rotateRight(node);
+ }
+ return node;
+}
+
+Node* helpedToInsert(Node* root, const char* key, char* string, const bool isKeyInTree, bool* needToChangeBalance) {
+ if (root == NULL) {
+ Node* newNode = createElementTree();
+ newNode->data.value = string;
+ strcpy(newNode->data.key, key);
+ return newNode;
+ }
+ if (strcmp(root->data.key, key) == 0) {
+ free(root->data.value);
+ root->data.value = string;
+ return root;
+ }
+ if (strcmp(key, root->data.key) == -1) {
+ root->left = helpedToInsert(root->left, key, string, isKeyInTree, needToChangeBalance);
+ if (!isKeyInTree && !*needToChangeBalance) {
+ --root->data.balance;
+ }
+ }
+ else {
+ root->right = helpedToInsert(root->right, key, string, isKeyInTree, needToChangeBalance);
+ if (!isKeyInTree && !*needToChangeBalance) {
+ ++root->data.balance;
+ }
+ }
+ if (root->data.balance == 0) {
+ *needToChangeBalance = true;
+ }
+ Node* temp = balance(root);
+ if (temp->data.balance == 0) {
+ *needToChangeBalance = true;
+ }
+ return temp;
+}
+
+void addToTree(Tree* tree, const char* key, char* string) {
+ bool needToChangeBalance = false;
+ tree->root = helpedToInsert(tree->root, key, string, isKeyInTree(tree, key), &needToChangeBalance);
+}
+
+char* returnValueByKey(Tree* tree, const char* key) {
+ if (tree == NULL) {
+ return NULL;
+ }
+ Node* walker = tree->root;
+
+ while (walker != NULL) {
+ if (strcmp(walker->data.key, key) == 0) {
+ return walker->data.value;
+ }
+ if (strcmp(walker->data.key, key) == -1) {
+ walker = walker->right;
+ }
+ else {
+ walker = walker->left;
+ }
+ }
+ return NULL;
+}
+
+bool isKeyInTree(Tree* tree, const char* key) {
+ if (tree == NULL) {
+ return false;
+ }
+ Node* walker = tree->root;
+
+ while (walker != NULL) {
+ if (strcmp(walker->data.key, key) == 0) {
+ return true;
+ }
+ if (strcmp(walker->data.key, key) == -1) {
+ walker = walker->right;
+ }
+ else {
+ walker = walker->left;
+ }
+ }
+ return false;
+}
+
+Node* deleteNode(Node* root, const char* key, Tree* tree, Node* previousRoot, Node* theMostBigLeft, bool firstLeft, bool* needToChangeBalance, Node* previousMostBigLeft) {
+ if (!firstLeft && theMostBigLeft->right == NULL) {
+ Node* tempLeft = root->left;
+ free(root->data.value);
+ root->data.value = theMostBigLeft->data.value;
+ strcpy(root->data.key, theMostBigLeft->data.key);
+ if (theMostBigLeft->left != NULL && previousMostBigLeft != root) {
+ previousMostBigLeft->right = theMostBigLeft->left;
+ }
+ free(theMostBigLeft);
+ return NULL;
+ } else {
+ if (firstLeft) {
+ root->left = deleteNode(root, key, tree, previousRoot, root->left, false, needToChangeBalance, root);
+ if (!*needToChangeBalance) {
+ ++root->data.balance;
+ }
+ if (root->data.balance == -1 || root->data.balance == 1) {
+ *needToChangeBalance = true;
+ }
+ Node* temp = balance(root);
+ if (temp->data.balance == -1 || temp->data.balance == 1) {
+ *needToChangeBalance = true;
+ }
+ return temp;
+ }
+ else {
+ theMostBigLeft->right = deleteNode(root, key, tree, previousRoot, theMostBigLeft->right, false, needToChangeBalance, theMostBigLeft);
+ if (!*needToChangeBalance) {
+ --theMostBigLeft->data.balance;
+ }
+ if (theMostBigLeft->right == NULL) {
+ return theMostBigLeft;
+ }
+ }
+ }
+ if (root->data.balance == -1 || root->data.balance == 1) {
+ *needToChangeBalance = true;
+ }
+ Node* temp = balance(theMostBigLeft);
+ if (temp->data.balance == -1 || temp->data.balance == 1) {
+ *needToChangeBalance = true;
+ }
+ return temp;
+}
+
+Node* helpDeleteNodeInTreeByKey(Node* root, const char* key, Tree* tree, Node* previousRoot, bool* needToChangeBalance) {
+ if (root == NULL) {
+ return NULL;
+ }
+ if (strcmp(root->data.key, key) == 0) {
+ if (root->left == NULL) {
+ Node* temp = root->right;
+ free(root->data.value);
+ free(root);
+ if (previousRoot == NULL) {
+ tree->root = temp;
+ }
+ else {
+ if (strcmp(previousRoot->data.key, key) == -1) {
+ previousRoot->right = temp;
+ }
+ else {
+ previousRoot->left = temp;
+ }
+ }
+ return temp;
+ }
+ root = deleteNode(root, key, tree, previousRoot, NULL, true, needToChangeBalance, root);
+ if (previousRoot == NULL) {
+ tree->root = root;
+ }
+ else {
+ if (strcmp(previousRoot->data.key, key) == -1) {
+ previousRoot->right = root;
+ }
+ else {
+ previousRoot->left = root;
+ }
+ }
+ return root;
+ }
+ if (strcmp(key, root->data.key) == -1) {
+ root->left = helpDeleteNodeInTreeByKey(root->left, key, tree, root, needToChangeBalance);
+ if (!*needToChangeBalance) {
+ ++root->data.balance;
+ }
+ }
+ else {
+ root->right = helpDeleteNodeInTreeByKey(root->right, key, tree, root, needToChangeBalance);
+ if (!*needToChangeBalance) {
+ --root->data.balance;
+ }
+ }
+ if (root->data.balance == -1 || root->data.balance == 1) {
+ *needToChangeBalance = true;
+ }
+ Node* temp = balance(root);
+ if (temp->data.balance == -1 || temp->data.balance == 1) {
+ *needToChangeBalance = true;
+ }
+ return temp;
+}
+
+void deleteNodeInTreeByKey(Tree* tree, const char* key) {
+ if (isKeyInTree(tree, key)) {
+ bool needToChangeBalance = false;
+ tree->root = helpDeleteNodeInTreeByKey(tree->root, key, tree, NULL, &needToChangeBalance);
+ }
+}
\ No newline at end of file
diff --git a/avlTreeNew/AVLTree/AVLTree/avlTree.h b/avlTreeNew/AVLTree/AVLTree/avlTree.h
new file mode 100644
index 0000000..e1148d6
--- /dev/null
+++ b/avlTreeNew/AVLTree/AVLTree/avlTree.h
@@ -0,0 +1,27 @@
+#ifndef AVL_TREE_H
+#define AVL_TREE_H
+#include
+
+typedef struct Tree Tree;
+
+//
+Tree* createTree(void);
+
+//
+void clearTree(Tree* tree);
+
+//
+void addToTree(Tree* tree, const char* key, char* string);
+
+//
+char* returnValueByKey(Tree* tree, const char* key);
+
+//
+bool isKeyInTree(Tree* tree, const char* key);
+
+//
+void deleteNodeInTreeByKey(Tree* tree, const char* key);
+
+// ,
+bool checkBalance(Tree* tree);
+#endif
\ No newline at end of file
diff --git a/avlTreeNew/AVLTree/AVLTree/main.c b/avlTreeNew/AVLTree/AVLTree/main.c
new file mode 100644
index 0000000..afd72ab
--- /dev/null
+++ b/avlTreeNew/AVLTree/AVLTree/main.c
@@ -0,0 +1,122 @@
+#include "avlTree.h"
+#include "test.h"
+#include
+#include
+#include
+#include
+#include
+
+int scanOne();
+
+bool talkWithUser(void) {
+ printf(" :\n0 - \n1 - . , .\n2 - . , NULL.\n3 - .\n4- . , .\n");
+ int command = scanOne();
+
+ while (command > 4 || command < 0) {
+ printf(" . !\n");
+ command = scanOne();
+ }
+
+ Tree* tree = createTree();
+ char* stringCopy = NULL;
+
+ while (command != 0) {
+ printf(" . , 100 \n");
+ char key[100] = { '\0' };
+ int checkScanfKey = scanf("%s", key);
+ while (checkScanfKey != 1) {
+ while (getchar() != '\n') {
+ }
+ printf("...\n");
+ checkScanfKey = scanf("%s", key);
+ }
+
+ switch (command) {
+ case 1:
+ printf(" . 100 , \n");
+ int size = scanOne();
+ while (size < 0 || size > 100) {
+ while (getchar() != '\n') {
+ }
+ printf("...\n");
+ size = scanOne();
+ }
+ char buffer[101] = { '\0' };
+ int checkScanf = scanf("%s", buffer);
+
+ while (checkScanf != 1) {
+ while (getchar() != '\n') {
+ }
+ printf("...\n");
+ checkScanf = scanf("%s", buffer);
+ }
+ size_t sizeBuffer = strlen(buffer);
+ char* string = calloc(sizeBuffer + 1, sizeof(char));
+ if (string == NULL) {
+ return false;
+ }
+ for (size_t i = 0; i < sizeBuffer; ++i) {
+ string[i] = buffer[i];
+ }
+ addToTree(tree, key, string);
+ break;
+ case 2:
+ stringCopy = returnValueByKey(tree, key);
+ if (string != NULL) {
+ printf("%s\n", string);
+ }
+ break;
+ case 3:
+ if (isKeyInTree(tree, key)) {
+ printf(", !\n");
+ }
+ else {
+ printf(", !\n");
+ }
+ break;
+ case 4:
+ deleteNodeInTreeByKey(tree, key);
+ break;
+ }
+ printf(" !\n");
+ command = scanOne();
+
+ while (command > 4 || command < 0) {
+ printf(" . !\n");
+ command = scanOne();
+ }
+ }
+
+ clearTree(tree);
+}
+
+int main() {
+ setlocale(LC_ALL, "RUS");
+ if (testForAvlTree()) {
+ printf(" !\n");
+ }
+ else {
+ printf("...\n");
+ return -1;
+ }
+
+ if (!talkWithUser()) {
+ printf("...\n");
+ return -1;
+ }
+}
+
+int scanOne() {
+ int number = 0;
+ int checkScanf = scanf("%d", &number);
+
+ while (checkScanf != 1) {
+ while (getchar() != '\n') {
+ }
+
+ printf("...\n");
+ checkScanf = scanf("%d", &number);
+ }
+
+ return number;
+}
\ No newline at end of file
diff --git a/avlTreeNew/AVLTree/AVLTree/test.c b/avlTreeNew/AVLTree/AVLTree/test.c
new file mode 100644
index 0000000..2d50511
--- /dev/null
+++ b/avlTreeNew/AVLTree/AVLTree/test.c
@@ -0,0 +1,61 @@
+#include "avlTree.h"
+#include "test.h"
+#include
+#include
+#include
+#include
+
+bool testForAvlTree() {
+ Tree* tree = createTree();
+ char* string1 = calloc(2, sizeof(char));
+ if (string1 == NULL) {
+ return false;
+ }
+ string1[0] = 'a';
+ char key1[] = "320";
+ addToTree(tree, key1, string1);
+ char* string2 = calloc(2, sizeof(char));
+ if (string2 == NULL) {
+ free(string1);
+ return false;
+ }
+ string2[0] = 'b';
+ char key2[] = "200";
+ addToTree(tree, key2, string2);
+ char* string3 = calloc(2, sizeof(char));
+ if (string3 == NULL) {
+ clearTree(tree);
+ return false;
+ }
+ string3[0] = 'c';
+ char key3[] = "100";
+ addToTree(tree, key3, string3);
+ if (!isKeyInTree(tree, "100")) {
+ clearTree(tree);
+ return false;
+ }
+ for (int i = 0; i < 1000; ++i) {
+ char buffer[5] = { '\0' };
+ _itoa(i, buffer, 10);
+ addToTree(tree, buffer, calloc(1, sizeof(char)));
+ }
+ if (!checkBalance(tree)) {
+ clearTree(tree);
+ return false;
+ }
+ deleteNodeInTreeByKey(tree, "100", true);
+ if (isKeyInTree(tree, "100")) {
+ clearTree(tree);
+ return false;
+ }
+ deleteNodeInTreeByKey(tree, "200", true);
+ char stringForCheck[2] = { '\0' };
+ stringForCheck[0] = 'a';
+ if (strcmp(returnValueByKey(tree, "320"), stringForCheck) != 0) {
+ clearTree(tree);
+ return false;
+ }
+ deleteNodeInTreeByKey(tree, "320", true);
+ clearTree(tree);
+ return true;
+}
\ No newline at end of file
diff --git a/avlTreeNew/AVLTree/AVLTree/test.h b/avlTreeNew/AVLTree/AVLTree/test.h
new file mode 100644
index 0000000..6a9d474
--- /dev/null
+++ b/avlTreeNew/AVLTree/AVLTree/test.h
@@ -0,0 +1,8 @@
+#ifndef TEST_H
+#define TEST_H
+#include
+
+//Tests for tree
+bool testForAvlTree();
+
+#endif
\ No newline at end of file