【数据结构与算法分析】第四章 树(二)

【数据结构与算法分析】第四章 树(二)

3.二叉树

二叉树是一棵树,其中每个节点都不能有多于两个的儿子。

4.表达式树

表达式树的树叶是操作数,如常量或变量,其他节点为操作符。其计算过程为中序遍历(左子树,节点,右子树)。

如图为一个表达式树:

左子树的值为a+(b*c),右子树的值是((d * e)+f)*g,整个树为(a+(b * c))+(((d * e)+f)*g),也称为中缀表达式

后序遍历(左子树,右子树,节点)输出结果为:abc*++de * f+g*+,表达式也称为后缀表达式

前序遍历(节点,左子树,右子树)输出结果为:++a*bc * +*defg,表达式也称为前缀表达式

5.二叉查找树

二叉树的一个重要的应用是它们在查找中的使用。

二叉查找树的性质:

  • 若左子树不空,则左子树上所有结点的值均小于它的根结点的值;

  • 若右子树不空,则右子树上所有结点的值均大于它的根结点的值;

如图,左边的树为二叉查找树

分析:

左图,(1)对于节点6,左子树上的每个值均小于6,右子树上的每个值都大于6,(2)对于节点2,左子树上的每个值均小于2,右子树上的每个值都大于2,(3)对于节点4,左子树上的每个值均小于4,无右子树

右图,对于节点6,左子树中含有子节点7大于节点6,所有不是二叉查找树

5.1程序实现

二叉查找树的声明:

#ifndif _Tree_H
struct TreeNode;
typedef struct TreeNode *Position;
typedef struct TreeNode *SearchTree;
SearchTree MakeEmpty(SearchTree T);
Position Find(ElementType X,SeachTree T);
Position FindMin(SeachTree T);
Position FindMax(SeachTree T);
SearchTree Insert(ElementType X,SeachTree T);
SearchTree Delete(ElementType X,SeachTree T);
ElementType Retrieve(Position P);
#endif
struct TreeNode
{
    ElementType Element;
    SearchTree Left;
    SearchTree Right;
};

建立一个空树:

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

二叉查找树的Find操作:

Position Find(ElementType X,SearchTree T)//利用二叉查找树中每个节点的左子节点小于父节点,有子节点大于父节点的性质
{
    if(T==NULL)
        return NULL;//未查找到关键字X
    if(X<T->Element)//如果查找的关键字小于节点的关键字
        return Find(X,T->Left);//用递归方式,查找节点的左子节点
    else if(X>T->Element)//如果查找的关键字大于节点的关键字
        return Find(X,T->Right);//用递归方式,查找节点的右子节点
    else
        return T;//查找到关键字X,返回指向树T中具有关键字X的节点的指针
}

对二叉查找树的FindMin的递归实现:

Position FindMin(SearchTree T)//查找树中最小元素的位置,每个父节点的左子节点均小于父节点
{
    if(T==NULL)
        return NULL;
    else if(T->Left==NULL)
        return T;
    else
        return FindMin(T->Left);
}

对二叉查找树的FindMax的非递归实现:

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

对二叉查找树的FindMax的递归实现:

Position FindMax(SearchTree T)//查找树中最大元素的位置,每个父节点的右子节点均大于父节点
{
    if(T==NULL)
        return NULL;
    else if(T->Right==NULL)
        return T;
    else
        return FindMax(T->Right);
}

插入元素到二叉查找树:

SearchTree Insert(ElementType X,SearchTree T)//将X插入树T,如果找到X,则什么也不做,否则,将插入X到遍历的路径上的最后一点
{
    if(T==NULL)
    {
        T=malloc(sizeof(struct TreeNode));
        if(T==NULL)
            FatalError("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 = Inser(X,T->Right);
    return T;
}

 如图插入元素5:

5.2Delete

删除节点的几种情况:

(1)节点是树叶,它可以立即被删除

(2)节点有一个儿子,删除情况如图:

(3)节点有两个儿子,用删除节点2的右子树的最小数据3代替该节点的数据,并递归的删除那个节点3,因为右子树的最小数据无左儿子,第二次删除较容易,删除情况如图:

代码实现:

SearchTree Delete(ElementType X,SearchTree T)
{
    Position Temp;
    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
        T->Right=Delete(X,T->Right);
    else if(T->Left&&T->Right)//如果有两儿子
    {
        Temp=FindMin(T->Right);//找到右子树中最小元素的位置
        T->Element=Temp->Element;
        T->Right=Delete(T->Element,T->Right);
    }
    else//如果有一个或没有儿子
    {
        Temp=T;
        if(T->Left!=NULL)//有一个左儿子
            T=T->Left;
        else if(T->Right!=NULL)//有一个右儿子
            T=T->Right;
        free(temp);
    }
    return T;
}
​

猜你喜欢

转载自blog.csdn.net/zhangxiafll/article/details/81710735