数据结构与算法分析课后习题第四章(2)

本文介绍了一种实现带有懒删除功能的二叉搜索树的方法,并探讨了AVL树单旋转和双旋转的具体实现细节。此外,还提供了一个线性时间复杂度的算法来验证AVL树的高度信息是否正确维护并保持平衡。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

4.16 Redo the binary search tree class to implement lazy deletion. Note carefully that this affects all of the routines. Especially challenging are findMin and findMax, which must now be done recursively.

4.21 Write the remaining procedures to implement AVL single and double rotations.

4.22 Design a linear-time algorithm that verifies that the height information in an AVL tree is correctly maintained and that the balance property is in order.

//4.16 bstree.hpp

#ifndef BSTREE_HPP__
#define BSTREE_HPP__

#include <iosfwd>

template< typename Object >
class Set;

template< typename Object >
class BSTree {
private:
 class Node {
 public:
  Node(const Object& val = Object(), Node* l = NULL, Node* r = NULL,
   bool e = false) : lChild(l),
   rChild(r), data(val), erased(e)
  {}

  Node& operator=(const Node& rhs)
  {
   data = rhs.data;
   lChild = rhs.lChild;
   rChild = rhs.rChild;
   erased = rhs.erased;
  }

 public:
  Object data;
  Node* lChild;
  Node* rChild;
  bool erased;
 };

public:
 BSTree() : root(NULL), theSize(0), numErased(0), min(NULL),
  max(NULL) {}
 ~BSTree(){ clear(); }
 BSTree(const BSTree& rhs){}
 BSTree& operator=(const BSTree& rhs){}

public:
 bool contains(const Object& val) const
 { return contains(val, root); }
 bool empty() const
 { return theSize == 0; }
 void printTree(std::ostream& out, bool flag = false)
 { 
  if(empty())
   out << "empty tree/n";
  else
   printTree(root, out, flag); 
 }

 void clear()
 { clear(root); }
 void add(const Object& val)
 { insert(val, root); }
 void del(const Object& val)
 { remove(val, root); }

 Object findMin()
 {
  min = NULL;
  findMin(root, min); 
  return min->data;
 }

 Object findMax()
 {
  max = NULL;
  findMax(root, max);
  return max->data;
 }

 
private:
 void insert(const Object& val, Node* &t)
 {
  if(t == NULL)
  {
   t = new Node(val, NULL, NULL);
   ++theSize;
  }
  else if(val < t->data)
   insert(val, t->lChild);
  else if(t->data < val)
   insert(val, t->rChild);
  else if(t->erased == true)
  {
   t->erased = false;
   ++theSize;
   --numErased;
  }
 }
 
 void remove(const Object& val, Node* &t)
 {
  if(t == NULL)
   return;

  if(val < t->data)
   remove(val, t->lChild);
  else if(t->data < val)
   remove(val, t->rChild);
  else if(theSize <= numErased && numErased != 0)
  {
   t->erased = true;
   --theSize;
   ++numErased;
   doRemove(root);
  }
  else
  {
   t->erased = true;
   ++numErased;
   --theSize;
  }
 }

 void doRemove(Node* &t)
 { 
  if(t != NULL)
  { 
   doRemove(t->lChild);
   doRemove(t->rChild);
   if(t->erased == true)
   {
    removeA(t->data, root);
    --numErased;
   }

  }
 }

 void removeA(const Object& val, Node* &t)
 {
  if(t == NULL)
   return;
  if(val < t->data)
   removeA(val, t->lChild);
  else if(t->data < val)
   removeA(val, t->rChild);
  else if(t->lChild != NULL && t->rChild != NULL)
  {
   Node* p;
   t->data = findMin(t->rChild)->data;
   p = findMin(t->rChild);
   t->erased = p->erased;
   p->erased = true;
   removeA(t->data, t->rChild);
  }
  else
  {
   Node* old = t;
   t = (t->lChild != NULL) ? t->lChild : t->rChild;
   delete old;
  }
 }


 bool contains(const Object& val, Node* t) const
 {
  if(t == NULL)
   return false;
  else if(val < t->data)
   return contains(val, t->lChild);
  else if(t->data < val)
   return contains(val, t->rChild);
  else if(t->erased == false)
   return true;
  else
   return false;
 }

 Node* findMin(Node* t)
 {
  if(t == NULL)
   return NULL;
  if(t->lChild == NULL)
   return t;
  return findMin(t->lChild);
 }
 
 void findMin(Node* t, Node* &m)
 {
  if(t != NULL)
  {
   findMin(t->lChild, m);
   if(t->erased == false)
   {
    if(m == NULL || m->data > t->data)
     m = t;
   }
   findMin(t->rChild, m);
  }
 }

 void findMax(Node* t, Node* &m)
 {
  if(t != NULL)
  {
   findMax(t->rChild, m);
   if(t->erased == false)
   {
    if(m == NULL || m->data < t->data)
     m = t;
   }
   findMax(t->lChild, m);
  }
 }

 void clear(Node* &t)
 {
  if(t != NULL)
  {
   clear(t->lChild);
   clear(t->rChild);
   delete t;
  }
  t = NULL;
 }

 void printTree(Node* t, std::ostream& out, bool flag)
 {
  if(t != NULL)
  {
   printTree(t->lChild, out, flag);
   if(flag)
    out << t->data << "/n";
   else
   {
    if(t->erased == false)
     out << t->data << "/n";
   }
   printTree(t->rChild, out, flag);
  }
 }

private:
 Node* root;
 Node* min;
 Node* max;
 int theSize;
 int numErased;

 friend class Set<Object>;

};

#endif

//4.21-4.22 avltree.hpp

#ifndef AVLTREE_HPP__
#define AVLTREE_HPP__

#include <iostream>

template <typename Object>
class AvlTree
{
  public:
    AvlTree( ) : root( NULL )
      { }
    AvlTree( const AvlTree & rhs ) : root( NULL )
    {
        *this = rhs;
    }

    ~AvlTree( )
    {
        makeEmpty( );
    }

    const Object & findMin( ) const
    {
        if( isEmpty( ) )
   std::cerr << "Underflow/n";
        return findMin( root )->element;
    }

    const Object & findMax( ) const
    {
        if( isEmpty( ) )
            std::cerr << "Underflow/n";
        return findMax( root )->element;
    }

    bool contains( const Object & x ) const
    {
        return contains( x, root );
    }

    bool isEmpty( ) const
    {
        return root == NULL;
    }

    void printTree( ) const
    {
        if( isEmpty( ) )
   std::cout << "Empty tree" << std::endl;
        else
            printTree( root );
    }

    void makeEmpty( )
    {
        makeEmpty( root );
    }

    void insert( const Object & x )
    {
        insert( x, root );
    }
    

    void remove( const Object & x )
    {
        cout << "Sorry, remove unimplemented; " << x <<
                " still present" << endl;
    }

    const AvlTree & operator=( const AvlTree & rhs )
    {
        if( this != &rhs )
        {
            makeEmpty( );
            root = clone( rhs.root );
        }
        return *this;
    }

 void printHeight()
 {
  int rHeight = -1, lHeight = -1;
  if(root->right != NULL) 
   rHeight = height(root->right);
  if(root->left != NULL)
   lHeight = height(root->left);

  std::cout << "Height of left sub-tree: "
   << lHeight << "/tHeight of right sub-tree: "
   << rHeight << "/n" << "root height: "
   << root->height;
 }


  private:
    struct AvlNode
    {
        Object element;
        AvlNode   *left;
        AvlNode   *right;
        int       height;

        AvlNode( const Object & theElement, AvlNode *lt,
                AvlNode *rt, int h = 0 )
          : element( theElement ), left( lt ), right( rt ), height( h ) { }
    };

    AvlNode *root;

    void insert( const Object & x, AvlNode * & t )
    {
        if( t == NULL )
            t = new AvlNode( x, NULL, NULL );
        else if( x < t->element )
        {
            insert( x, t->left );
            if( height( t->left ) - height( t->right ) == 2 )
                if( x < t->left->element )
                    rotateWithLeftChild( t );
                else
                    doubleWithLeftChild( t );
        }
        else if( t->element < x )
        {
            insert( x, t->right );
            if( height( t->right ) - height( t->left ) == 2 )
                if( t->right->element < x )
                    rotateWithRightChild( t );
                else
                    doubleWithRightChild( t );
        }
        else
            ; 
        t->height = max( height( t->left ), height( t->right ) ) + 1;
    }


    AvlNode * findMin( AvlNode *t ) const
    {
        if( t == NULL )
            return NULL;
        if( t->left == NULL )
            return t;
        return findMin( t->left );
    }

    AvlNode * findMax( AvlNode *t ) const
    {
        if( t != NULL )
            while( t->right != NULL )
                t = t->right;
        return t;
    }

    bool contains( const Object & x, AvlNode *t ) const
    {
        if( t == NULL )
            return false;
        else if( x < t->element )
            return contains( x, t->left );
        else if( t->element < x )
            return contains( x, t->right );
        else
            return true;    // Match
    }

    void makeEmpty( AvlNode * & t )
    {
        if( t != NULL )
        {
            makeEmpty( t->left );
            makeEmpty( t->right );
            delete t;
        }
        t = NULL;
    }

    void printTree( AvlNode *t ) const
    {
        if( t != NULL )
        {
            printTree( t->left );
    std::cout << t->element << std::endl;
            printTree( t->right );
        }
    }

    AvlNode * clone( AvlNode *t ) const
    {
        if( t == NULL )
            return NULL;
        else
            return new AvlNode( t->element, clone( t->left ), clone( t->right ), t->height );
    }
        // Avl manipulations

 int height( AvlNode *t ) const
    {
        return t == NULL ? -1 : t->height;
    }

    int max( int lhs, int rhs ) const
    {
        return lhs > rhs ? lhs : rhs;
    }

    void rotateWithLeftChild( AvlNode * & k2 )
    {
        AvlNode *k1 = k2->left;
        k2->left = k1->right;
        k1->right = k2;
        k2->height = max( height( k2->left ), height( k2->right ) ) + 1;
        k1->height = max( height( k1->left ), k2->height ) + 1;
        k2 = k1;
    }

    void rotateWithRightChild( AvlNode * & k1 )
    {
        AvlNode *k2 = k1->right;
        k1->right = k2->left;
        k2->left = k1;
        k1->height = max( height( k1->left ), height( k1->right ) ) + 1;
        k2->height = max( height( k2->right ), k1->height ) + 1;
        k1 = k2;
    }

    void doubleWithLeftChild( AvlNode * & k3 )
    {
        rotateWithRightChild( k3->left );
        rotateWithLeftChild( k3 );
    }

    void doubleWithRightChild( AvlNode * & k1 )
    {
        rotateWithLeftChild( k1->right );
        rotateWithRightChild( k1 );
    }
 
};

#endif 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值