树(中)

树(中)

1.二叉搜索树:

二叉搜索树也称二叉排序树或二叉查找树,它是一种对排序和查找都很有用的特殊二叉树。

它可以为空,若不为空则会满足以下性质:

(1)非空左子树的所有键值小于其根结点的键值。

(2)非空右子树的所有键值大于其根结点的键值。

(3)左、右子树都是二叉搜索树。

二叉搜索树的查找

void find(struct tree *root,int x)
{
    while(root!=NULL)
    {
        if(x>root->data)
            root=root->r;//向右子树中移动,继续查找
        else if(x<root->data)
            root=root->l;//向左子树中移动,继续查找
        else 
            break;
    }
    return root;
}

查找最大和最小元素:

根据性质可以知道:最大元素一定是在树的最右分枝的端结点上 ; 最小元素一定是在树的最左分枝的端结点上。

2.二叉搜索树的插入:

思路:将元素X插入二叉搜索树中关键是要找到元素应该插入的位置。位置的确定可以利用与上面的查找函数Find类似的方法,如果在树中找到X,说明要插入的元素已存在,可放弃插入操作。如果没找到X,查找终止的位置就是X应插入的位置。

struck tree Insert(struck tree root, int X )
{
     if( root==NULL ) //若原树为空,生成并返回一个结点的二叉搜索树
    {
        root= (struck tree )malloc(sizeof(struck tree));
        root->data = X;
        root->l = root->r = NULL;
  }
  else//开始找要插入元素的位置 
{
        if( X <root->data )
            root->l = Insert( root->l, X );//递归插入左子树
        else  if( X > root->data )
            root->r = Insert( root->r, X ); //递归插入右子树
  }
  return root;
}

3.二叉搜索树的删除:

通常分为三种情况:

(1)要删除的是叶结点——可以直接删除,然后再修改其父结点的指针。

(2)要删除的结点只有一个孩子结点——删除之前需要改变其父结点的指针,指向要删除结点的孩子结点。

(3)要删除的结点有左、右两棵子树——为了保持二叉搜索树的有序性,替代被删除的元素的位置可以有两种选择:一种是取其右子树中的最小元素;另一个是取其左子树中的最大元素。

struct tree Delete(struct tree root,int X ) 
{ Position T; 
  if(root==NULL) 
    printf("要删除的元素未找到"); 
  else 
  {
    if(X<root->data) 
      root->l=Delete(root->l,X); // 从左子树递归删除 
    else if(X>root->data) 
      root->r=Delete(root->r,X); //从右子树递归删除 
    else // BST就是要删除的结点 
    { 
      //如果被删除结点有左右两个子结点
      if(root->l&&root->r)
      {
        T=FindMin(root->r); //从右子树中找最小的元素填充删除结点
        root->data=T->data;//从右子树中删除最小元素 
        root->r=Delete(root->r,root->data);
      }
      else //被删除结点有一个或无子结点
      { 
        T=root; 
        if(!root->l)
        root=root->r; //只有右孩子或无子结点 
        else    
        root=root->l;  //只有左孩子 
        free(T);
      }
    }
  }
  return root;

4.平衡二叉树:

对于二叉树中任一结点T,其“平衡因子”定义为BF(T) = hL-hR,其中hL和hR分别为T的左、右子树的高度。任一结点左、右子树高度差的绝对值不超过1。即|BF(T) |≤ 1。

(1)RR: 首个不平衡的“发现者”(未必是根结点),它是调整起点位置。而“麻烦结点”在发现者右子树的右边,因而叫 RR 插入,需要RR 旋转(右单旋);

(2)LL: 首个“发现者”; “麻烦结点” 在发现者左子树的左边,因而叫 LL 插入;

(3)LR: 首个“发现者”; “麻烦结点”在左子树的右边,因而叫 LR 插入;

发布了20 篇原创文章 · 获赞 1 · 访问量 532

猜你喜欢

转载自blog.csdn.net/huyidai/article/details/104382730