⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lbst.h

📁 数据结构c++语言描述 Borland C++实现
💻 H
字号:

// indexed binary search tree with duplicates

#ifndef DIndexedBSTree_
#define DIndexedBSTree_

#include "dbst.h" 
#include "stdlib.h" 

template<class E, class K>
class DIndexedBSTree : public DBSTree<E, K> {
   public:
      bool IndexedSearch(int k, E& e);
      DIndexedBSTree<E,K>& Insert(const E& e);
      DIndexedBSTree<E,K>& Delete(const K& k, E& e);
      DIndexedBSTree<E,K>& IndexedDelete(int k, E& e);
   private:
      void Reset(int r, const K& k);
};


template<class E, class K>
bool DIndexedBSTree<E,K>::IndexedSearch(int k, E& e)
{// Put the k'th element in e.
 // Return false iff there is no k'th element
   BinaryTreeNode<E> *p = root;
   while (p)
      if (k < p->data.LeftSize) p = p->LeftChild;
      else if (k > p->data.LeftSize) {
   	      k -= p->data.LeftSize;
              p = p->RightChild;}
           else {e = p->data;
                return true;}
   return false;
}

template<class E, class K>
DIndexedBSTree<E,K>& DIndexedBSTree<E,K>::
                     Insert(const E& e)
{// Insert e even if it is a duplicate.
   BinaryTreeNode<E> *pp = 0;  // pp is parent of p
   BinaryTreeNode<E> *p = root;
   K k = e; // extract key from e
   // search for k
   while (p) {
      pp = p;
      if (k < p->data) {
         // insert will be in left subtree of p
         p->data.LeftSize++;
         p = p->LeftChild;}
      else if (e > p->data) p = p->RightChild;
           else // make a random decision
                if (rand() % 2) {
                   p->data.LeftSize++;
                   p = p->LeftChild;}
                else p = p->RightChild;
      }

   // get a node for e
   p = new BinaryTreeNode<E> (e);
   // cannot reset LeftSize fields because it is
   // hard to find proper nodes when e equals
   // some existing elements
  
   // attach node p to pp
   p->data.LeftSize = 1;
   if (root) // tree not empty
      if (e < pp->data)
         pp->LeftChild = p;
      else if (e > pp->data)
              pp->RightChild = p;
           else // equal keys, pp has at most one child
                // figure out where p belongs
                if (pp->data.LeftSize == 2 && !pp->LeftChild)
                   pp->LeftChild = p;
                else pp->RightChild = p;
   else // insertion into empty tree
        root = p;

   return *this;
}

template<class E, class K>
void DIndexedBSTree<E,K>::
       Reset(int r, const K& k)
{// Add r to LeftSize on path to k.
   BinaryTreeNode<E> *p = root;
   while (p)
      if (k < p->data) {
         p->data.LeftSize += r;
         p = p->LeftChild;}
      else if (k > p->data) p = p->RightChild;
           else return;
}


template<class E, class K>
DIndexedBSTree<E,K>& DIndexedBSTree<E,K>::
                     Delete(const K& k, E& e)
{// Delete element that matches k.
 // Put deleted element in e.
 // Throw BadInput exception if no matching element.
   // Find element to delete
   BinaryTreeNode<E> *pp = 0;  // parent of p
   BinaryTreeNode<E> *p = root;
   while (p && p->data != k) {
      pp = p;
      if (k < p->data) {
         p->data.LeftSize--;
         p = p->LeftChild;}
      else p = p->RightChild;
      }
   if (!p) {Reset(1, k);
            throw BadInput();} // not found

   e = p->data;  // save matching element

   // proceed to delete from tree
   if (p->LeftChild && p->RightChild) {
      // p has two children
      // find largest element in left subtree of p
      // first move into left subtree, then make as
      // many right child moves as possible
      int ls = p->data.LeftSize - 1; // save value
      BinaryTreeNode<E> *ps = p,  // parent of s
                        *s = p->LeftChild;
      while (s->RightChild) {
         ps = s;
         s = s->RightChild;
         }

      // move largest element to p
      p->data = s->data;
      p->data.LeftSize = ls;
      // set pp and p so that p is node to delete
      pp = ps;
      p = s;
      }

   // now p has at most one child
   // save pointer to single subtree of p in s
   BinaryTreeNode<E> *s;
   if (p->LeftChild) s = p->LeftChild;
   else s = p->RightChild;

   // attach s to pp unless p is root
   if (p == root) root = s;
   else if (p == pp->LeftChild)
           pp->LeftChild = s;
        else pp->RightChild = s;

   delete p;

   return *this;
}

template<class E, class K>
DIndexedBSTree<E,K>& DIndexedBSTree<E,K>::
                     IndexedDelete(int k, E& e)
{// Delete the k'th element.  Put deleted element in e.
 // Throw BadInput exception if no k'th element.
   // find element to delete
   BinaryTreeNode<E> *pp = 0;  // parent of p
   BinaryTreeNode<E> *p = root;
   while (p && p->data.LeftSize != k) {
      pp = p;
      if (k < p->data.LeftSize) {
         p->data.LeftSize--;
         p = p->LeftChild;}
      else {k -= p->data.LeftSize;
            p = p->RightChild;}
      }
   if (!p) {// no element to delete, reset LeftSize
            p = root;
            while (p)
               if (k < p->data.LeftSize) {
                  p->data.LeftSize--;
                  p = p->LeftChild;}
               else {k -= p->data.LeftSize;
                     p = p->RightChild;}

             throw BadInput();
             }

   e = p->data;  // save matching element

   // proceed to delete from tree
   if (p->LeftChild && p->RightChild) {
      // p has two children
      // find largest element in left subtree of p
      // first move into left subtree, then make as
      // many right child moves as possible
      int ls = p->data.LeftSize - 1; // save value
      BinaryTreeNode<E> *ps = p,  // parent of s
                        *s = p->LeftChild;
      while (s->RightChild) {
         ps = s;
         s = s->RightChild;
         }

      // move largest element to p
      p->data = s->data;
      p->data.LeftSize = ls;
      // set pp and p so that p is node to delete
      pp = ps;
      p = s;
      }

   // now p has at most one child
   // save pointer to single subtree of p in s
   BinaryTreeNode<E> *s;
   if (p->LeftChild) s = p->LeftChild;
   else s = p->RightChild;

   // attach s to pp unless p is root
   if (p == root) root = s;
   else if (p == pp->LeftChild)
           pp->LeftChild = s;
        else pp->RightChild = s;

   delete p;

   return *this;
}

#endif;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -