#include #include #include typedef struct Node { int data; struct Node* left; struct Node* right; int isThreaded; } Node; Node* createNode(int data); Node* insert(Node* root, int data); void printTree(Node* root, int level, int showThreads); void inorder(Node* root); void preorder(Node* root); void postorder(Node* root); void createThreadedBST(Node* root, Node** lastNode); void threadedInorderTraversal(Node* root); Node* leftMost(Node* node); void deleteSubtree(Node** root, int key); void freeTree(Node* root); void clearInputBuffer(); int search(Node* root, int key); void deleteSubtreeRecursive(Node** root, int key); Node* copyTree(Node* root); int main() { Node* root = NULL; Node* threadedRoot = NULL; int choice, data, key; Node* lastNode = NULL; while (1) { printf("1. Построить дерево двоичного поиска и вывести\n"); printf("2. Выполнить 3 полных обхода (с выделением)\n"); printf("3. Сделать симметричную правую прошивку и вывести\n"); printf("4. Удаление из прошитого дерева и вывод\n"); printf("5. Выход\n"); printf("Выберите пункт: "); if (scanf("%d", &choice) != 1) { printf("Ошибка ввода!\n"); clearInputBuffer(); continue; } clearInputBuffer(); switch (choice) { case 1: freeTree(root); freeTree(threadedRoot); root = NULL; threadedRoot = NULL; printf("Введите элементы (для завершения введите -1):\n"); while (1) { printf("Элемент: "); if (scanf("%d", &data) != 1) { printf("Некорректный ввод. Попробуйте снова.\n"); clearInputBuffer(); continue; } if (data == -1) break; root = insert(root, data); } printf("\nДерево:\n"); printTree(root, 0, 0); break; case 2: if (root == NULL) { printf("Дерево пусто!\n"); break; } printf("\nПрямой обход (трассировка): "); preorder(root); printf("\nСимметричный обход (трассировка): "); inorder(root); printf("\nОбратный обход (трассировка): "); postorder(root); printf("\n"); break; case 3: if (root == NULL) { printf("Дерево пусто!\n"); break; } freeTree(threadedRoot); threadedRoot = copyTree(root); lastNode = NULL; createThreadedBST(threadedRoot, &lastNode); if (lastNode != NULL && lastNode->right == NULL) { lastNode->right = threadedRoot; lastNode->isThreaded = 1; } printf("\nПрошитый симметричный обход: "); threadedInorderTraversal(threadedRoot); printf("\n\nПрошитое дерево:\n"); printTree(threadedRoot, 0, 1); break; case 4: if (root == NULL) { printf("Дерево пусто!\n"); break; } printf("Введите ключ для удаления: "); if (scanf("%d", &key) != 1) { printf("Ошибка ввода!\n"); clearInputBuffer(); break; } if (!search(root, key)) { printf("Элемент %d не найден.\n", key); } else { deleteSubtree(&root, key); deleteSubtree(&threadedRoot, key); if (threadedRoot != NULL) { lastNode = NULL; createThreadedBST(threadedRoot, &lastNode); if (lastNode != NULL && lastNode->right == NULL) { lastNode->right = threadedRoot; lastNode->isThreaded = 1; } } printf("\nПосле удаления:\n"); printf("Исходное дерево:\n"); printTree(root, 0, 0); printf("\nПрошитое дерево:\n"); printTree(threadedRoot, 0, 1); printf("\nОбновлённый прошитый обход: "); threadedInorderTraversal(threadedRoot); printf("\n"); } break; case 5: freeTree(root); freeTree(threadedRoot); printf("Программа завершена.\n"); return 0; default: printf("Неверный выбор! Попробуйте снова.\n"); } } return 0; } Node* createNode(int data) { Node* newNode = (Node*)malloc(sizeof(Node)); if (newNode == NULL) { printf("Ошибка выделения памяти!\n"); exit(1); } newNode->data = data; newNode->left = NULL; newNode->right = NULL; newNode->isThreaded = 0; return newNode; } Node* insert(Node* root, int data) { if (root == NULL) return createNode(data); if (data < root->data) root->left = insert(root->left, data); else if (data > root->data) root->right = insert(root->right, data); return root; } int search(Node* root, int key) { if (root == NULL) return 0; if (key == root->data) return 1; if (key < root->data) return search(root->left, key); if (!root->isThreaded) return search(root->right, key); return 0; } void printTree(Node* root, int level, int showThreads) { if (root == NULL) return; for (int i = 0; i < level; i++) { printf(" "); } printf("%d", root->data); if (showThreads && root->isThreaded && root->right != NULL) { printf(" (%d)", root->right->data); } printf("\n"); int hasLeft = (root->left != NULL); int hasRight = (!root->isThreaded && root->right != NULL); if (hasLeft && hasRight) { printTree(root->left, level + 1, showThreads); printTree(root->right, level + 1, showThreads); } else if (hasLeft && !hasRight) { printTree(root->left, level + 1, showThreads); for (int i = 0; i < level + 1; i++) { printf(" "); } printf("-\n"); } else if (!hasLeft && hasRight) { for (int i = 0; i < level + 1; i++) { printf(" "); } printf("-\n"); printTree(root->right, level + 1, showThreads); } } void inorder(Node* root) { if (root == NULL) { printf("0 "); return; } printf("%d ", root->data); inorder(root->left); printf("(%d) ", root->data); inorder(root->right); printf("%d ", root->data); } void preorder(Node* root) { if (root == NULL) { printf("0 "); return; } printf("(%d) ", root->data); preorder(root->left); printf("%d ", root->data); preorder(root->right); printf("%d ", root->data); } void postorder(Node* root) { if (root == NULL) { printf("0 "); return; } printf("%d ", root->data); postorder(root->left); printf("%d ", root->data); postorder(root->right); printf("(%d) ", root->data); } Node* leftMost(Node* node) { if (node == NULL) return NULL; while (node->left != NULL) node = node->left; return node; } void createThreadedBST(Node* root, Node** lastNode) { if (root == NULL) return; createThreadedBST(root->left, lastNode); if (*lastNode != NULL && (*lastNode)->right == NULL) { (*lastNode)->right = root; (*lastNode)->isThreaded = 1; } *lastNode = root; if (!root->isThreaded) { createThreadedBST(root->right, lastNode); } } void threadedInorderTraversal(Node* root) { if (root == NULL) { printf("(пусто)"); return; } Node* current = leftMost(root); int first = 1; int rootVisited = 0; while (current != NULL) { if (!first) { printf(" "); } printf("%d", current->data); first = 0; if (current == root) { if (rootVisited) { break; } rootVisited = 1; } if (current->isThreaded) { current = current->right; } else { current = leftMost(current->right); } } } Node* copyTree(Node* root) { if (root == NULL) return NULL; Node* newNode = createNode(root->data); newNode->left = copyTree(root->left); newNode->right = copyTree(root->right); newNode->isThreaded = 0; return newNode; } void deleteSubtree(Node** root, int key) { if (*root == NULL) return; if ((*root)->data == key) { freeTree(*root); *root = NULL; return; } deleteSubtreeRecursive(root, key); } void deleteSubtreeRecursive(Node** root, int key) { if (*root == NULL) return; if ((*root)->data == key) { Node* leftSubtree = (*root)->left; Node* rightSubtree = (*root)->right; free(*root); if (leftSubtree != NULL && rightSubtree != NULL) { Node* maxNode = leftSubtree; while (maxNode->right != NULL && !maxNode->isThreaded) { maxNode = maxNode->right; } *root = maxNode; maxNode->left = (maxNode != leftSubtree) ? leftSubtree : maxNode->left; maxNode->right = rightSubtree; } else if (leftSubtree != NULL) { *root = leftSubtree; } else { *root = rightSubtree; } return; } if (key < (*root)->data) { deleteSubtreeRecursive(&(*root)->left, key); } else { deleteSubtreeRecursive(&(*root)->right, key); } } void freeTree(Node* root) { if (root == NULL) return; freeTree(root->left); if (!root->isThreaded) { freeTree(root->right); } free(root); } void clearInputBuffer() { int c; while ((c = getchar()) != '\n' && c != EOF); }