思路:
(1)搜索二叉树的结构就是二叉树的左右两个节点,所有左子节点的值小于右子节点的值,然后还要有一个lazy标志,用于lazy删除。
(2)搜索二叉树主要有一下几个操作:建立搜索二叉树;建立空树;查找x的位置;查找最大,最小值的位置;
插入节点,删除节点;打印二叉树;
(3)建立搜索二叉树,不同于链表的建立,不用带头结点,所以直接插入就行了。
(4)建立空树:递归删除每个节点,通过后序遍历,先找到然后再删除。
(5)查找x的位置:递归查找,如果x小于当前节点的值就在左子树中查找,否则在右子树中查找。
(6)查找最大,最小值:二叉查找时的最左节点就是最小值,最右子节点就是最大值;
查找过程可以用递归或者非递归两种方式实现
eg:查找最小值,不断向左递归查找;或者将根节点的所有左子树视为一个链表,不断指向左结点来实现。
(7)插入:如果即将插入的节点是空,就分配内存,并且插入节点,
如果不是空节点,比较当前节点的值与将要插入的值的大小,再向左向右递归插入。(每次都要返回T的值,返回插入结束后的树,后面的删除操作同理)。
(8)删除:
如果删除的节点数量较小,直接用lazy标记一下就行了。
如果删除数量较大,就要判断删除的是哪一个节点。
叶子节点:直接删除;
只有一个子节点的节点:删除让当前节点变为它的子节点
有两个子节点的节点:先寻找次节点的右子树的最小值,然后将此节点的值替换为右子树的最小值,再递归删除右子树的最小值。
(9)打印二叉树:
前序遍历,中序遍历,后序遍历。
注意:
(1)查找,删除时判断一下是否为空,如果为空就返回
(2)搜索二叉树的中序遍历是x从小到大的排序
(3)搜索二叉树的大部分操作是O(logN)级别的,但是,如果输入5,4,3,2,1就可能退化为一个链表,就并不高效了,
所以应该使二叉树保持平衡状态,降低它的深度,就可以用到AVL树。
(4)删除和查找时注意二叉树的返回。
#include<stdio.h>
#include<stdlib.h>
struct Node{
int x,lazy;
struct Node *Left,*Right;
};
typedef struct Node *SearchTree;
typedef SearchTree Position;
SearchTree MakeEmpty(SearchTree T)
{
if(T!=NULL)
{
MakeEmpty(T->Left);
MakeEmpty(T->Right);
free(T);
}
return NULL;
}
SearchTree Find(int x,SearchTree T)
{
if(T==NULL) return NULL;
else if(x<T->x) return Find(x,T->Left);
else if(x>T->x) return Find(x,T->Right);
else return T;
}
SearchTree FindMin1(SearchTree T)
{
if(T==NULL) return NULL;
else if(T->Left==NULL) return T;
else return FindMin1(T->Left);
}
SearchTree FindMin2(SearchTree T)
{
if(T!=NULL)
{
while(T->Left!=NULL) T=T->Left;
}
return T;
}
SearchTree FindMax1(SearchTree T)
{
if(T==NULL) return NULL;
else if(T->Right==NULL) return T;
else return FindMax1(T->Right);
}
SearchTree FindMax2(SearchTree T)
{
if(T!=NULL)
{
while(T->Right!=NULL) T=T->Right;
}
return T;
}
SearchTree Insert(int x,SearchTree T)
{
if(T==NULL)
{
T=(SearchTree)malloc(sizeof(struct Node));
if(T==NULL) printf("Out of Space!!!\n");
else
{
T->x=x;
T->Left=NULL;
T->Right=NULL;
}
}
else if(x<T->x) T->Left=Insert(x,T->Left);
else T->Right=Insert(x,T->Right);
return T;
}
SearchTree Delete(int x,SearchTree T)
{
SearchTree tp;
if(T==NULL) printf("Empty SearchTree\n");
else if(x<T->x) T->Left=Delete(x,T->Left);
else if(x>T->x) T->Right=Delete(x,T->Right);
else
{
if(T->Left&&T->Right)
{
tp=FindMin1(T->Right);
T->x=tp->x;
T->Right=Delete(tp->x,T->Right);
}
else
{
tp=T;
if(T->Left==NULL) T=T->Right;
else if(T->Right==NULL) T=T->Left;
free(tp);
}
}
return T;
}
SearchTree Delete_Lazy(int x,SearchTree T)
{
if(T==NULL) printf("Empty SearchTree!!!\n");
else if(x<T->x) T->Left=Delete(x,T->Left);
else if(x>T->x) T->Right=Delete(x,T->Right);
else
{
T->lazy=-1;
}
return T;
}
void Print(SearchTree T)
{
if(T!=NULL)
{
Print(T->Left);
printf("%d ",T->x);
Print(T->Right);
}
}
int main(void)
{
int n,i,x;
SearchTree root,p;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&x);
root=Insert(x,root);
}
Print(root);
printf("\n");
root=Delete(3,root);
Print(root);
return 0;
}