二叉搜索树的非递归实现
之前写过递归版本的,这里的实现思想是相同的,具体见
二叉搜索树相关操作的递归实现,这里只写几个非递归实现的函数
1. 给定一个值,将该元素插入二叉搜索树
SearchNode* CreateSearchNode(SearchNodeType value)//创建一个结点
{
SearchNode* new_node = (SearchNode*)malloc(sizeof(SearchNode));
new_node->data = value;
new_node->lchild = NULL;
new_node->rchild = NULL;
return new_node;
}
void SearchTreeInsert(SearchNode** proot, SearchNodeType to_insert)//插入一个元素
{
if(proot == NULL)//非法输入
return;
//1.空树->直接插入指针所指位置
if(*proot == NULL)//空树,也是插入位置
{
SearchNode* new_node = CreateSearchNode(to_insert);
*proot = new_node;
return;
}
//2.非空树->寻找插入位置
SearchNode* pre = NULL;//记录父结点
SearchNode* cur = *proot;//记录当前结点
while(1)
{
//当前结点为空,可插入
if(cur == NULL)
break;
//向左子树寻找
if(to_insert < cur->data)
{
pre = cur;
cur = cur->lchild;
}
//向右子树寻找
else if(to_insert > cur->data)
{
pre = cur;
cur = cur->rchild;
}
//有相同元素,按照约定,直接返回,插入失败
else
{
return;
}
}
//3.当前cur所指即为可插入位置,下面插入元素
//这里要注意当前可插入位置为父结点的左子树还是右子树
SearchNode* new_node = CreateSearchNode(to_insert);
//插入左子树
if(to_insert < pre->data)
{
pre->lchild = new_node;
}
if(to_insert > pre->data)
{
pre->rchild = new_node;
}
return;
}
2
. 给定一个值,在二叉搜索树中查找对应结点
SearchNode* SearchTreeFind(SearchNode* root, SearchNodeType to_find)//查找指定值结点
{
if(root == NULL)//空树
return NULL;
SearchNode* cur = root;
while(1)
{
//没找到
if(cur == NULL)
break;
if(to_find < cur->data)
{
cur = cur->lchild;
}
else if(to_find > cur->data)
{
cur = cur->rchild;
}
else
{
break;
}
}
return cur;
}
3
. 给定一个值,在二叉搜索树中删除对应结点
void SearchTreeRemove(SearchNode** proot, SearchNodeType to_remove)//删除指定值结点
{
if(proot == NULL)//非法输入
return;
if(*proot == NULL)//空树
return;
//1.查找要删除的结点
SearchNode* root = *proot;
SearchNode* pre = NULL;
while(1)
{
//没找到
if(root == NULL)
return;
if(to_remove < root->data)
{
pre = root;
root = root->lchild;
}
else if(to_remove > root->data)
{
pre = root;
root = root->rchild;
}
else
break;
}
//2.当前root所指元素即为要删除的元素
//(1)要删除的结点无左右子树
if(root->lchild == NULL && root->rchild == NULL)
{
//要删除的元素为整个二叉搜索树的根节点
if(root == *proot)
{
*proot = NULL;
}
else
{
//删除结点为父结点的左子树
if(to_remove < pre->data)
pre->lchild = NULL;
else
pre->rchild = NULL;
}
SearchNodeDestroy(root);
}
//(2)要删除的结点仅有左子树
if(root->lchild != NULL && root->rchild == NULL)
{
//要删除的元素为整个二叉搜索树的根节点
if(root == *proot)
{
*proot = root->lchild;
}
else
{
//删除结点为父结点的左子树
if(to_remove < pre->data)
pre->lchild = root->lchild;
//要删除结点为父结点的右子树
else
pre->rchild = root->lchild;
}
//统一释放
SearchNodeDestroy(root);
}
//(3)要删除的结点仅有右子树
if(root->lchild == NULL && root->rchild != NULL)
{
//要删除的元素为整个二叉搜索树的根节点
if(root == *proot)
{
*proot = root->rchild;
}
else
{
//删除结点为父结点的左子树
if(to_remove < pre->data)
pre->lchild = root->rchild;
//要删除结点为父结点的右子树
else
pre->rchild = root->rchild;
}
//统一释放
SearchNodeDestroy(root);
}
//(4)要删除的结点左右子树均在
if(root->lchild != NULL && root->rchild != NULL)
{
//查找要删除结点的右子树的最小值
SearchNode* min = root->rchild;
SearchNode* min_pre = root;
while(min->lchild != NULL)
{
min_pre = min;
min = min->lchild;
}
//用最小值覆盖要删除结点的值
root->data = min->data;
//删除释放
//这里不管min所指结点的右子树是否为空,都将其指向它的右子树,因为走到这里,min不可能有左子树
if(min->data < min_pre->data)
min_pre->lchild = min->rchild;
else
min_pre->rchild = min->rchild;
SearchNodeDestroy(min);
}
}
测试代码也与递归版本的测试代码相同。