搜索二叉树

Posted 2018zxy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了搜索二叉树相关的知识,希望对你有一定的参考价值。

思路:

(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!!!
");
        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
");
    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!!!
");
    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("
");
    root=Delete(3,root);
    Print(root);
    return 0;
}
View Code

 

以上是关于搜索二叉树的主要内容,如果未能解决你的问题,请参考以下文章

二叉树之二叉搜索树(BSTree)

二叉树进阶题------二叉树的构建及遍历;二叉搜索树转换成排序双向链表;二叉树创建字符串

二叉树进阶题------二叉树的构建及遍历;二叉搜索树转换成排序双向链表;二叉树创建字符串

二叉树进阶题------二叉树的构建及遍历;二叉搜索树转换成排序双向链表;二叉树创建字符串

数据结构树相关代码(数据结构笔试复测Leecode牛客)

找到搜索二叉树中两个错误的节点