[C言語実装]二叉ルックアップツリーの基本操作を実現(反復版)
5556 ワード
このブログでは、ツリーの定義が再帰的に実現されているため、再帰的に上記の操作を反復的に完了することは、再帰的に容易に実現できるという考え方を記録しています.
インプリメンテーションの挿入
親ノードの親ノードを手動で記録する必要があります.親ノードの子ツリーを新しいノードに挿入するノードが親ノードの左サブツリーか右サブツリーかを指すため、サイズを比較することで決定できます.
検索
検索は何もなくて、再帰と同じで、大きさを比較して、ループを終了する時node=NULLは検索が命中していないことを表します
削除
再帰バージョンの削除は複雑で反復にはもっと難しいですが、考え方は2つのノードを記録します.pre_Node(親ノード)node(現在のノード)、nodeがpreであることをサイズに基づいて比較する必要があるNodeの左サブツリーか右サブツリーかを4つに分けて議論し,再帰と同様にここでは4つのケースを削除する図である.
インプリメンテーションの挿入
親ノードの親ノードを手動で記録する必要があります.親ノードの子ツリーを新しいノードに挿入するノードが親ノードの左サブツリーか右サブツリーかを指すため、サイズを比較することで決定できます.
void SearchTreeInsert_ByLooP(SearchTreeNode* root, SearchTreeType key)
{
SearchTreeNode* pre_node = root;
SearchTreeNode* node = root;
for(node = root; node != NULL; )
{
if(node->key > key)
{
pre_node = node;
node = node->rchild;
}
else if(node->key < key)
{
pre_node = node;
node = node->lchild;
}
else if(node->key == key)
{
break;
}
}
//
if(node == NULL)
{
node = (SearchTreeNode*)malloc(sizeof(SearchTreeNode));
node->key = key;
node->lchild = NULL;
node->rchild = NULL;
//
if(pre_node->key < node->key)
{
pre_node->rchild = node;
}
else
{
pre_node->lchild = node;
}
}
}
検索
検索は何もなくて、再帰と同じで、大きさを比較して、ループを終了する時node=NULLは検索が命中していないことを表します
削除
再帰バージョンの削除は複雑で反復にはもっと難しいですが、考え方は2つのノードを記録します.pre_Node(親ノード)node(現在のノード)、nodeがpreであることをサイズに基づいて比較する必要があるNodeの左サブツリーか右サブツリーかを4つに分けて議論し,再帰と同様にここでは4つのケースを削除する図である.
void _SearchTreeRemove_ByLoop(SearchTreeNode** proot,SearchTreeType key)
{
if( proot == NULL )
return;
if( *proot == NULL )
return;
SearchTreeNode* root = *proot;
SearchTreeNode* pre_root = NULL;
//
while(root)
{
if(root->key > key)
{
pre_root = root;
root = root->lchild;
}
else if(root->key < key)
{
pre_root = root;
root = root->rchild;
}
else if(root->key == key)
{
break;
}
}
//
if(root == NULL)
{
return;
}
//
if(root == *proot)
{
free(*proot);
*proot = NULL;
return;
}
//
if(root->lchild == NULL && root->rchild == NULL)
{
//
if(pre_root->key > root->key)
{
pre_root->lchild = NULL;
}
else
{
pre_root->rchild = NULL;
}
free(root);
root = NULL;
}
//
else if(root->lchild != NULL && root->rchild == NULL)
{
//
if(pre_root->key > root->key)
{
pre_root->lchild = root->lchild;
}
else
{
pre_root->rchild = root->lchild;
}
free(root);
root = NULL;
}
//
else if(root->rchild != NULL && root->lchild == NULL)
{
if(pre_root->key > root->key)
{
pre_root->lchild = root->rchild;
}
else
{
pre_root->rchild = root->rchild;
}
free(root);
root = NULL;
}
else if(root->rchild != NULL && root->lchild != NULL)
{
// ,
SearchTreeNode* max = root->lchild;
SearchTreeNode* pre_max = NULL;
while(max->rchild)
{
pre_max = max;
max = max->rchild;
}
root->key = max->key;
//
if(pre_max == NULL)
{
free(root->lchild);
root->lchild = NULL;
}
else
{
// ,
free(pre_max->rchild);
pre_max->rchild = NULL;
}
}
}