在TST的SET 1帖子中,我们描述了如何在TST中插入和搜索节点。在本文中,我们将讨论有关如何从TST删除节点的算法。
在删除操作过程中,我们使用递归从下往上的方式删除密钥。从特里删除键时,以下是可能的情况。
- TST中可能没有密钥。
解决方案:删除操作不应修改TST。 - 密钥作为唯一密钥存在(密钥的任何部分都不包含另一个密钥(前缀),密钥本身也不是TST中另一个密钥的前缀)。
解决方案:删除所有节点。 - 键是TST中另一个长键的前缀键。
解决方案:取消标记叶子节点。 - TST中存在的密钥,具有至少另一个密钥作为前缀密钥。
解决方案:从密钥末尾删除节点,直到删除最长前缀密钥的第一个叶节点。
delete_node函数的说明
- 假设我们要删除字符串“ BIG”,因为它在TST中不存在,因此在与第一个字符“ B”匹配之后,delete_node函数将返回零。因此,什么也不会被删除。
- 现在我们要删除字符串“ BUG”,它在TST中唯一存在,即它既没有一部分是其他字符串的前缀,又没有任何其他字符串的前缀,因此将被完全删除。
- 现在我们要删除字符串“ CAT”,因为它是字符串“ CATS”的前缀,所以我们无法删除字符串“ CAT”中的内容,而只能取消标记叶节点,这将确保“ CAT”不再是成员TST的字符串。
- 现在我们要删除字符串“ CATS”,因为它具有前缀字符串“ CAT”,它也是TST的成员字符串,因此我们只能删除字符串“ CATS”的最后一个字符,这将确保字符串“ CAT”仍然保留TST的一部分。
C
// C program to demonstrate deletion in
// Ternary Search Tree (TST). For insert
// and other functions, refer
// https://www.geeksforgeeks.org/ternary-search-tree/
#include
#include
// structure of a node in TST
struct Node
{
char key;
int isleaf;
struct Node *left;
struct Node *eq;
struct Node *right;
};
// function to create a Node in TST
struct Node *createNode(char key)
{
struct Node *temp =
(struct Node*)malloc(sizeof(struct Node));
temp->key = key;
temp->isleaf = 0;
temp->left = NULL;
temp->eq = NULL;
temp->right = NULL;
return temp;
};
// function to insert a Node in TST
void insert_node(struct Node **root ,char *s)
{
if (!(*root))
(*root) = createNode(*s);
if ((*s)<(*root)->key)
insert_node( &(*root)->left ,s);
else if ((*s)>(*root)->key)
insert_node( &(*root)->right ,s);
else if ((*s) == (*root)->key)
{
if (*(s+1) == '\0')
{
(*root)->isleaf = 1;
return;
}
insert_node( &(*root)->eq ,s+1);
}
}
// function to display the TST
void display(struct Node *root, char str[], int level)
{
if (!root)
return;
display(root->left ,str ,level);
str[level] = root->key;
if (root->isleaf == 1)
{
str[level+1] = '\0';
printf("%s\n",str);
}
display(root->eq ,str ,level+1);
display(root->right ,str ,level);
}
// to check if current Node is leaf node or not
int isLeaf(struct Node *root)
{
return root->isleaf == 1;
}
// to check if current node has any child node or not
int isFreeNode(struct Node *root)
{
if (root->left ||root->eq ||root->right)
return 0;
return 1;
}
// function to delete a string in TST
int delete_node(struct Node *root, char str[],
int level ,int n)
{
if (root == NULL)
return 0;
// CASE 4 Key present in TST, having
// atleast one other key as prefix key.
if (str[level+1] == '\0')
{
// Unmark leaf node if present
if (isLeaf(root))
{
root->isleaf=0;
return isFreeNode(root);
}
// else string is not present in TST and
// return 0
else
return 0;
}
else
{
// CASE 3 Key is prefix key of another
// long key in TST.
if (str[level] < root->key)
delete_node(root->left ,str ,level ,n);
else if (str[level] > root->key)
delete_node(root->right ,str ,level ,n);
// CASE 1 Key may not be there in TST.
else if (str[level] == root->key)
{
// CASE 2 Key present as unique key
if( delete_node(root->eq ,str ,level+1 ,n) )
{
// delete the last node, neither it
// has any child
// nor it is part of any other string
free(root->eq);
return !isLeaf(root) && isFreeNode(root);
}
}
}
return 0;
}
// Driver function
int main()
{
struct Node *temp = NULL;
insert_node(&temp ,"CAT");
insert_node(&temp ,"BUGS");
insert_node(&temp ,"CATS");
insert_node(&temp ,"UP");
int level = 0;
char str[20];
int p = 0;
printf( "1.Content of the TST before "
"deletion:\n" );
display(temp ,str ,level);
level = 0;
delete_node(temp ,"CAT" ,level ,5);
level = 0;
printf("\n2.Content of the TST after "
"deletion:\n");
display(temp, str, level);
return 0;
}
C++
// C++ program to demonstrate deletion in
// Ternary Search Tree (TST)
// For insert and other functions, refer
// https://www.geeksforgeeks.org/ternary-search-tree
#include
using namespace std;
// structure of a node in TST
struct Node
{
char key;
int isleaf;
struct Node *left;
struct Node *eq;
struct Node *right;
};
// function to create a node in TST
struct Node *createNode(char key)
{
struct Node *temp = new Node;
temp->key = key;
temp->isleaf = 0;
temp->left = NULL;
temp->eq = NULL;
temp->right = NULL;
return temp;
};
// function to insert a Node in TST
void insert_node(struct Node **root, char *s)
{
if (!(*root))
{
(*root) = createNode(*s);
}
if ((*s)<(*root)->key)
insert_node( &(*root)->left, s);
else if ((*s)>(*root)->key)
insert_node( &(*root)->right, s);
else if ((*s) == (*root)->key)
{
if (*(s+1) == '\0')
{
(*root)->isleaf = 1;
return;
}
insert_node( &(*root)->eq, s+1);
}
}
// function to display the TST
void display(struct Node *root, char str[], int level)
{
if (!root)
return;
display(root->left, str, level);
str[level] = root->key;
if (root->isleaf == 1)
{
str[level+1] = '\0';
cout<< str <eq, str, level+1);
display(root->right, str, level);
}
//to check if current node is leaf node or not
int isLeaf(struct Node *root)
{
return root->isleaf == 1;
}
// to check if current node has any child
// node or not
int isFreeNode(struct Node *root)
{
if (root->left ||root->eq ||root->right)
return 0;
return 1;
}
// function to delete a string in TST
int delete_node(struct Node *root, char str[],
int level, int n)
{
if (root == NULL)
return 0;
// CASE 4 Key present in TST, having atleast
// one other key as prefix key.
if (str[level+1] == '\0')
{
// Unmark leaf node if present
if (isLeaf(root))
{
root->isleaf = 0;
return isFreeNode(root);
}
// else string is not present in TST and
// return 0
else
return 0;
}
// CASE 3 Key is prefix key of another long
// key in TST.
if (str[level] < root->key)
return delete_node(root->left, str, level, n);
if (str[level] > root->key)
return delete_node(root->right, str, level, n);
// CASE 1 Key may not be there in TST.
if (str[level] == root->key)
{
// CASE 2 Key present as unique key
if (delete_node(root->eq, str, level+1, n))
{
// delete the last node, neither it has
// any child nor it is part of any other
// string
delete(root->eq);
return !isLeaf(root) && isFreeNode(root);
}
}
return 0;
}
// Driver function
int main()
{
struct Node *temp = NULL;
insert_node(&temp, "CAT");
insert_node(&temp, "BUGS");
insert_node(&temp, "CATS");
insert_node(&temp, "UP");
int level = 0;
char str[20];
int p = 0;
cout << "1.Content of the TST before deletion:\n";
display(temp, str, level);
level = 0;
delete_node(temp,"CAT", level, 5);
level = 0;
cout << "\n2.Content of the TST after deletion:\n";
display(temp, str, level);
return 0;
}
输出:
1.Content of the TST before deletion:
BUGS
CAT
CATS
UP
2.Content of the TST after deletion:
BUGS
CATS
UP