二叉树实现

二叉树节点声明

typedef struct TreeNode *PtrToNode;
typedef PtrToNode Tree;

struct TreeNode
{
    ElementTpe Element;
    Tree Left;
    Tree Right;
};


 

建立一棵空树的例程

 

MakeEmpty( searchTree T )
{
    if( T != NULL )
    {
        MakeEmpty( T->Left );
        MakeEmpty( T->Right );
        free(T);
    }
    return NULL;
}


 

 

二叉查找树的Find 操作

 

Find( ElementType X,SearchTree T )
{
    if( T == NULL )
        return NULL;
    if( X < T->Element )
        return Find( X, T->Left );
    else 
    if( X > T->Element )
        return Find( X, T->Right );
    else 
        return T;
}

 

二叉查找树的FindMin和FindMax的递归实现和非递归实现

 

    为执行FindMin,从根开始并且只要有左儿子就向左进行。终止点是最小的元素。FindMax例程除分支朝向右儿子外其余过程相同。
 

 

FindMin( SearchTree T )
{
    if( T == NULL )
        return NULL;
    else 
    if( T->Left == NULL )
        return T;
    else 
        return FindMin( T->Left );
}


 

 

FindMax( SearchTree T )
{
    if( T != NULL )
        while( T->Right != NULL )
            T = T->Right;
            
    return T;
}


 

 

 

插入元素到二叉查找树的例程

 

       进行插入操作的例程在概念上是简单的。为了将X插入到树T中,你可以象用Find那样沿着树查找。如果找到X,则什么也不用做(或做一些“更新”)。否则,将X插入到遍历的路径上的最后一点。

 

Insert( ElementType X,SearchTree T )
{
    if( T == NULL )
    {
        /* Creat and return a one-node tree */
        T = malloc( sizeof( struct TreeNode ) );
        if( T == NULL )
            FataError( "out of space!!!" );
        else
        {
            T->Element = X;
            T->Left = T->Right = NULL;
        }
    }
    else 
    if( X < T->Element )
        T->Left = Insert( X, T->Left );
    else 
    if( X > T->Element )
        T->Right = Insert( X, T->Right );
    /* Else X is it the tree already; we'll do nothing */
    return T; /* Do not forget this line!! */
}


 

 

二叉查找树的删除例程

 

  如果节点是一片树叶,那么它可以被立即删除。如果节点是一个儿子,则该节点可以在其父节点调整指针绕过该节点后背删除(为了清楚起见,我们将明确的画出指针的指向)。注意,所删除的节点现在已不再引用,该节点只有在指向他的指针已被省去的情况下才能够被去掉。

  复杂的情况是处理具有两个儿子的节点。一般的删除策略是用其右儿子树的最小的数据(很容易找到)代替该节点的数据并递归的删除那个节点(现在他是空的)。因为右子树中的最小的节点不可能有左儿子,所以第二次Delete要容易。

 

   如果删除的次数不多,则通常使用的策略是Lazy deletion:当一个元素要被删除时,他仍留在树中,而是只做了个被删除的记号。这种做法特别是在有重复关键字时很流行,因为此时记录出现频率书的域可以减一。如果树中德实际节点数和“被删除”的节点数相同,那么树的深度预计只上升一个小的常数,因此,存在一个与懒惰删除相关的非常小的时间损耗。

 

 

Delete( ElementType X, SearchTree T )
{
    Position TmpCell;
    
    if( T == NULL )
        Error( "Element not found" );
    else 
    if( X < T->Element ) //Go Left
        T->Left = Delete( X,T->Left );
    else 
    if( X > T->Element ) //Go Right
    else
    if( T->Left < X && X < T->Right ) //two children
    {
        /* Replace with smallest in right subtree */
        TmpCell = FindMin( T->Right );
        T->Element = TmpCell->Element;
        T->Right = Delete( T->Element, T-Right);
    }
    else  // one or zero children 
    {
        TmpCell  = T;
        if( T->Left == NULL ) /* Also handles 0 children */
            T = T->Right;
        else if( T->Right == NULL )
            T = T->Left;
        free( TmpCell );
    }
    return T;
}


 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值