码迷,mamicode.com
首页 > 其他好文 > 详细

搜索二叉树

时间:2018-11-30 15:48:12      阅读:185      评论:0      收藏:0      [点我收藏+]

标签:打印二叉树   最小   两种   判断   思路   有一个   avl树   node   scanf   

思路:

(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;
}
View Code

 

搜索二叉树

标签:打印二叉树   最小   两种   判断   思路   有一个   avl树   node   scanf   

原文地址:https://www.cnblogs.com/2018zxy/p/10043950.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!