MIPI_AdvancedC_FRTK/Lect7/55_delete_test.c

219 lines
5.5 KiB
C
Raw Permalink Normal View History

2024-11-14 08:45:50 +03:00
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct tree {
int key;//datatype
struct tree *left, *right;
struct tree *parent; // необязательное поле
} tree;
void preorder(tree *root)
{
if(root == NULL)
return;
printf("%d ",root->key);
if(root->left)//! NULL
preorder(root->left);
if(root->right)//! NULL
preorder(root->right);
}
void inorder(tree *root) {
if(root == NULL)
return;
if(root->left)
inorder(root->left);
printf("%d ",root->key);
if(root->right)
inorder(root->right);
}
void postorder(tree *root)
{
if(root == NULL)
return;
if(root->left)
postorder(root->left);
if(root->right)
postorder(root->right);
printf("%d ",root->key);
}
//Вычисляем высоту дерева
int heightTree(tree* p)
{
if (p == NULL)
return 0;
else
{
/* вычисляем высоту каждого поддерева */
int lheight = heightTree(p->left);
int rheight = heightTree(p->right);
if (lheight > rheight)
return (lheight + 1);
else
return (rheight + 1);
}
}
//Печатаем все узлы на уровне level
void printCurrentLevel(tree* root, int level)
{
if (root == NULL)
return;
if (level == 1)
printf("%d ", root->key);
else if (level > 1)
{
//если поменять местами то будет обход справа на лево
printCurrentLevel(root->left, level - 1);
printCurrentLevel(root->right, level - 1);
}
}
//функция печати
void printBFS(tree* root)
{
int h = heightTree(root);
for (int i = 1; i <= h; i++)
printCurrentLevel(root, i);
}
void insert(tree **root,int key, tree *pt) {
if(!(*root))
{
// дерево пустое или дошли до нужного места
*root=(tree *)calloc(1,sizeof(tree));
(*root)->key=key;
(*root)->parent=pt;
// c calloc строчка ниже не нужа
(*root)->left=(*root)->right= NULL;
}
else if( key < (*root)->key)
insert( &((*root)->left) ,key,*root);
else
insert( &((*root)->right),key,*root);
}
/* Рекурсивная реализация */
tree* search_tree(tree *root, int key)
{
if(root==NULL || root->key == key)
return root;
else if(root->key > key)
return search_tree(root->left, key);
else
return search_tree(root->right, key);
}
/* Итеративная версия */
tree* search_tree_i(tree *root, int key){
tree *find=root;
while(find && find->key!=key) {
if( key < find->key )
find = find->left;
else
find = find->right;
}
return find;
}
tree * searchKey(tree *root, int key)
{
if(!root)
return NULL;
if(root->key == key)
return root;
if(key < root->key )
return searchKey(root->left, key);
return searchKey(root->right, key);
}
tree* min_tree(tree *root)
{
tree *find=root;
while(find && find->left) {
find = find->left;
}
return find;
}
tree* left_follower_key(tree *root) {
if(root==NULL)
return root;
if(root->right)
return min_tree(root->right);
else {
tree *y = root->parent;
tree *x = root;
while(y && x==y->right) {
x = y;
y = y->parent;
}
return y;
}
}
/* Удаление узла из дерева */
tree* delete(tree *root, tree* pt) {
tree *remove = NULL, *remove_son;
/* Нет потомков или один потомок. Удаляем сам узел */
if(pt->left == NULL || pt->right == NULL)
remove = pt;
else
/* Два потомка. Удаляем его последователя.У последователя только один правый потомок, потому что это самый левый элемент правого поддерева.*/
remove = left_follower_key(pt);// Всегда только один потомок
/* Прикрепляем потомка удаляемого элемента к
родителю, либо делаем этого потомка корнем дерева*/
if(remove -> left != NULL) // не сработает если это последователь pt
remove_son = remove->left;
else
remove_son = remove->right;
if( remove_son ) // обновляем родителя у удаляемого потомка
remove_son->parent = remove->parent;
if(remove->parent==NULL) // если удаляем корень
root = remove_son;
else if (remove == remove->parent->left)
remove->parent->left = remove_son;
else
remove->parent->right = remove_son;
if(pt != remove)
pt->key = remove->key;
return remove;
}
int main()
{
tree *tr = NULL;
insert(&tr,10,NULL);
insert(&tr,5, NULL);
insert(&tr,15,NULL);
insert(&tr,3, NULL);
insert(&tr,7 ,NULL);
insert(&tr,13,NULL);
insert(&tr,18,NULL);
insert(&tr,1, NULL);
insert(&tr,6 ,NULL);
printBFS(tr);
printf("\n");
preorder(tr);
printf("\n");
postorder(tr);
printf("\n");
inorder(tr);
printf("\n");
printBFS(searchKey(tr,15));
printf("\n");
tree *del = NULL;
del = delete(tr,searchKey(tr,15));
free(del);
inorder(tr);
printf("\n");
return 0;
}