搜索二叉树:
在搜索二叉树中,根节点大于所有左子树节点的值,小于所有右子树节点的值。
本博客中涉及到的基本操作有:
1.递归与非递归的插入
2.递归与非递归的删除
3.递归与非递归的查找
#include<stdio.h>
#include<stdlib.h>
typedef char SearchTreeType;
typedef struct SearchTreeNode {
SearchTreeType data;
struct SearchTreeNode* lchild;
struct SearchTreeNode* rchild;
} SearchTreeNode;
初始化:
void SearchTreeInit(SearchTreeNode** root){
if(root == NULL){
return;//非法输入
}
*root = NULL;
return;
}
这里传二级指针是可能会对根节点进行删除等操作。
创建节点:
SearchTreeNode* CreateSearchNode(SearchTreeType value){
SearchTreeNode* new_node = (SearchTreeNode*)malloc(sizeof(SearchTreeNode));
new_node->data = value;
new_node->rchild = NULL;
new_node->lchild = NULL;
return new_node;
}
递归插入:
//递归插入
void SearchTreeInsert(SearchTreeNode** root,SearchTreeType value){
if(root == NULL){
return;
}
if(*root == NULL){
//空树,把要插的元素直接放到root指向的位置即可
SearchTreeNode* new_node = CreateSearchNode(value);
*root = new_node;
return;
}
//非空树采用递归的思想
SearchTreeNode* cur = *root;
if (value<cur->data){
//左
SearchTreeInsert(&cur->lchild,value);
}else if (value>cur->data){
SearchTreeInsert(&cur->rchild,value);
}else{
//条件有多种,这里采用一种约定
//1.在二叉搜索树中所有元素不能重复
//2.直接返回(插入失败)
//3.放在相同元素左子树的右子树,或者右子树的左子树
//这里采用第一种
return;
}
return;
}
非递归插入:
//非递归插入
void SearchTreeInsertByLoop(SearchTreeNode** root,SearchTreeType value)
{
if(root == NULL)
{
return;
}
SearchTreeNode* new_node = CreateSearchNode(value);
if(*root == NULL)
{
*root = new_node;
return;
}
SearchTreeNode* cur = *root;
while(1)
{
if(cur->rchild == NULL && value > cur->data)
{
cur->rchild = new_node;
break;
}
if(value < cur->data)
{
cur = cur->lchild;
}
else if(value > cur->data)
{
cur = cur->rchild;
}
else
{
DestroySrearNode(new_node);
break;
}
}
}
递归删除:
//递归删除
void SearchTreeRemove(SearchTreeNode** root,SearchTreeType key)
{
//1.要删除的元素没有找到,直接返回
//2.要删除的元素没有子树,直接将父节点对应的指针指向空,释放内存
//3.如果要删除的元素只有右子树,
//让父节点指向当前节点的右子树,释放内存
//4.************只有左子树,**********
//5,有左右子树
if(root == NULL)
{
return;
}
if(*root == NULL)
{
return;
}
SearchTreeNode* proot = *root;
if(key < proot->data)
{
SearchTreeRemove(&proot->lchild,key);
return;
}
else if(key > proot->data)
{
SearchTreeRemove(&proot->rchild,key);
return;
}
else//要删除的元素相等
{
SearchTreeNode* to_remove = proot;
//分情况讨论
if(proot->lchild == NULL && proot->rchild == NULL)
{
//没有子树
*root = NULL;
DestroySrearNode(to_remove);
return;
}
else if(proot->lchild != NULL && proot->rchild == NULL)
{
//只有左子树
*root = to_remove->lchild;
DestroySrearNode(to_remove);
return;
}
else if(proot->lchild == NULL && proot->rchild != NULL)
{
//只有右子树
*root = to_remove->rchild;
DestroySrearNode(to_remove);
return;
}
else
{
SearchTreeNode* min = to_remove->rchild;
while(min->lchild != NULL)
{
min = min->lchild;
}
//min指向了右子树中最小的节点
to_remove->data = min->data;
SearchTreeRemove(&to_remove->lchild,min->data);
return;
}
}
}
非递归删除:
//非递归删除
void SearchTreeRemoveByLoop(SearchTreeNode** root,SearchTreeType key)
{
if(root == NULL)
{
return;
}
if(*root == NULL)
{
return;
}
SearchTreeNode* cur = *root;
SearchTreeNode* pre = NULL;
while(1)
{
if(cur->data == key)
{
break;
}
else if(cur->data > key)
{
pre = cur;
cur = cur->lchild;
}
else if(cur->data < key)
{
pre = cur;
cur = cur->rchild;
}
}
//此时说明已经找到了要删除的节点
//a.要删除的节点没有左右子树
if(cur->lchild == NULL && cur->rchild == NULL)
{
if(cur == *root)
{
*root = NULL;
}
else
{
if(cur == pre->rchild)
{
pre->rchild = NULL;
}
else if(cur == pre->lchild)
{
pre->lchild = NULL;
}
}
DestroySrearNode(cur);
}
//b.要删除的点有左子树
else if(cur->lchild != NULL && cur->rchild == NULL)
{
if(cur == *root)
{
*root = cur->lchild;
}
else
{
if(cur = pre->lchild)
{
pre->lchild = cur->lchild;
}
else if(cur = pre->rchild)
{
pre->rchild = cur->lchild;
}
}
DestroySrearNode(cur);
}
//只有右子树
else if(cur->lchild == NULL && cur->rchild != NULL)
{
if(cur == (*root))
{
*root = NULL;
}
else
{
if(cur = pre->lchild)
{
pre->lchild = cur->rchild;
}
else if(cur = pre->rchild)
{
pre->rchild = cur->rchild;
}
}
DestroySrearNode(cur);
}
//同时具有左右子树
else
{
if(cur->lchild != NULL && cur->rchild != NULL)
{
if(cur == (*root))
{
*root = NULL;
}
SearchTreeNode* min = cur->lchild;
SearchTreeNode* min_pre = cur;
while(min->lchild != NULL)
{
min_pre = min;
min = min->lchild;
}
cur->data = min->data;
if(min == cur->lchild)
{
cur->rchild = min->rchild;
}
else
{
cur->lchild = min->rchild;
}
DestroySrearNode(min);
}
}
}
递归查找:
//递归查找
SearchTreeNode* SearchTreeFind(SearchTreeNode* root,SearchTreeType to_find)
{
if(root == NULL)
{
return NULL;
}
if(root->data == to_find)
{
return root;
}
else if(to_find < root->data)
{
return SearchTreeFind(root->lchild,to_find);
}
else
{
return SearchTreeFind(root->rchild,to_find);
}
}
非递归查找:
//非递归查找
SearchTreeNode* SearchTreeFindByLoop(SearchTreeNode* root,SearchTreeType to_find)
{
if(root == NULL)
{
return NULL;
}
SearchTreeNode* 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
{
return cur;
}
}
return NULL;
}