实现非递归版本的搜索二叉树的插入、查找和删除
插入:这里的思想是定义两个指针一个指向当前结点,一个指向当前结点的父节点,当前结点就是找要插入的位置,插入整体分为两步,第一步是找到要插入的位置,第二步判断要插入的值与此时父节点的大小,来决定是插入到左子树还是右子树即可;
代码实现:
void SeachTreeInsert(SearchNode** pRoot ,SearchNodeType to_insert){
if(pRoot == NULL){
return;
}
if(*pRoot == NULL){
SearchNode* new_node = CreateSearchNode(to_insert);
*pRoot = new_node;
return;
}
SearchNode* cur = *pRoot;
SearchNode* pre = NULL;
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;
}
}
SearchNode* new_node = CreateSearchNode(to_insert);
if(new_node->data < pre->data){
pre->lchild = new_node;
}else{
pre->rchild = new_node;
}
return;
}
查找:直接循环去找,当要查找的值比根结点的值小时,往左子树找,大时往右子树找,相等时跳出循环找到了,跳出循环即可;
代码如下:
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;
}
删除:这里的删除与递归版本的一样,先找到要删除的结点,然后分情况讨论:如果要删除的结点有孩子,就需要将孩子交付给父节点保管,不然删除结点之后他的孩子会被丢失;
代码实现:
void SearchTreeRemove(SearchNode** pRoot,SearchNodeType to_remove){
if(pRoot == NULL){
return;
}
if(*pRoot == NULL){
return;
}
SearchNode* to_remove_node = *pRoot;
SearchNode* parent = NULL;
while(1){
if(to_remove_node == NULL){
//没找到,要删除的元素,直接函数终止
return;
}
if(to_remove < to_remove_node->data){
parent = to_remove_node;
to_remove_node = to_remove_node->lchild;
}else if(to_remove > to_remove_node->data){
parent = to_remove_node;
to_remove_node = to_remove_node->rchild;
}else {
//找到了要删除的节点
break;
}
}
//2.如果找到了要删除的节点,分情况讨论
if(to_remove_node->lchild == NULL && to_remove_node->rchild == NULL){
//没有子树
//此处我们要判断删除的节点是否是根结点
if(to_remove_node == *pRoot){
//要删除的元素是根结点
*pRoot = NULL;
}else{
//要删除的元素不是根结点
//需要知道当前节点是parent的左子树还是右子树
if(to_remove_node->data < parent->data){
parent->lchild = NULL;
}else{
parent->rchild = NULL;
}
}
//统一释放节点
DestroySearchNode(to_remove_node);
return;
}else if(to_remove_node->lchild != NULL && to_remove_node->rchild ==NULL){
//只有左子树
if(to_remove_node == *pRoot){
*pRoot = to_remove_node->lchild;
}else{
if(to_remove_node->data < parent->data){
parent->lchild = to_remove_node->lchild;
}else{
parent->rchild = to_remove_node->lchild;
}
}
DestroySearchNode(to_remove_node);
return;
}else if(to_remove_node->lchild == NULL && to_remove_node->rchild != NULL){
//只有右子树
if(to_remove_node == *pRoot){
*pRoot = to_remove_node->rchild;
}else{
if(to_remove_node->data < parent->data){
parent->lchild = to_remove_node->rchild;
}else if(to_remove_node->data > parent->data){
parent->rchild = to_remove_node->rchild;
}
}
DestroySearchNode(to_remove_node);
return;
}else{
//同时有左右子树
SearchNode* min = to_remove_node->rchild;
SearchNode* min_parent = to_remove_node;
while(min->lchild != NULL){
min_parent = min;
min = min->lchild;
}
//循环结束之后,min就指向了to_remove_node右子树的最小值
to_remove_node->data = min->data;
if(min->data < min_parent->data){
//min是min_parent的左子树
//min一定没有左子树
min_parent->lchild = min->rchild;
}else{
//通常情况下,min是min_parent左子树,
//但是初始化情况下例外
min_parent->rchild = min->rchild;
}
}
}