2009-11-19 143 views
1

林有點困惑。林想知道如果基於數組的二叉搜索樹是這樣實現的?二進制搜索樹C++

void BST::insert(item &items, const data & aData) 
{//helper function. 
    Parent++; 
    data *new_data = new data(aData); 
    this->insert(*new_data); 
} 

// insert a new item into the BST 
void BST::insert(const data &aData) 
{ 
    if (items[Parent].empty) 
    { 
     items[Parent].theData = aData; 
     items[Parent].empty = false; 
    } 
    else if (aData < items[Parent].theData) 
    { 
       if (Parent >= maxSize) this->reallocate(); 
       this->insert(items[2*Parent+1], aData); 
    } 
    else 
    { 
      this->insert(items[2*Parent+2], aData); 
    } 
} 

// ctor我在哪裏讓我的傷口。

BST::BST(int capacity) : items(new item[capacity]), 
Parent(0), leftChild(0), rightChild(0), maxSize(capacity) 
{ 
} 
+0

你在問什麼? – Inverse 2009-11-19 06:26:30

+0

@相反:看看他最近的問題歷史... – dmckee 2009-11-19 06:50:31

回答

3

我不知道基於陣列中的二叉樹是最好的主意,因爲它:

  1. 防止節點平衡(優化對不平衡樹的查找)
  2. 浪費空間 - 它的噸,特別是如果樹不平衡。

話雖如此,這是一種有效的方法,對於小的修改: 變化

如果(父> = MAXSIZE)這 - >重新分配();

如果(2 *父> = MAXSIZE)這 - >重新分配();

+0

雖然它對平衡,靜態樹木有好處。有更好的地點,特別是前序遍歷。 Ref .: http://en.wikipedia.org/wiki/Binary_tree#Arrays – 2013-01-13 12:09:41

+1

如果我們知道元素查找和訪問的順序(這可能是構建平衡靜態樹的主要用途),那麼我們不妨使用直線陣列偏移量查找 - 即O(n)遍歷和O(1)查找。不能比這更好:) – Fox 2014-07-03 14:12:07

0

這是相當古老的,但我寫了我的大學第二年,這是大約8年前:)。它可以幫助你以某種方式或其他...

//JHermiz 
//Implementation File with def's 
//tree.h 

#include<stdlib.h> 
#include"xcept.h" //file for exceptions that may be thrown 

//BinaryTreeNode class 
template<class T> 
class BinaryTreeNode { 
       public: 
          BinaryTreeNode() {LeftChild=RightChild=NULL;} 
          BinaryTreeNode(const T&e) 
           { 
           data=e; 
           LeftChild=RightChild=NULL; 
           } 
          BinaryTreeNode(const T&e, BinaryTreeNode *l, 
               BinaryTreeNode *r) 
           { 
           data=e; 
           LeftChild=l; 
           RightChild=r; 
           } 

          BinaryTreeNode<T> *LeftChild; //left subtree 
          BinaryTreeNode<T> *RightChild; //right subtree 
          T data; 
          }; 

//BinaryTree Class 
template<class T> 
class BinaryTree{ 
      public: 
         BinaryTree(){root=NULL;} 

         ~BinaryTree(){Delete();} 

         void Delete(){PostOrder(Free, root); root=0;} 

         static void Free(BinaryTreeNode<T>* t){delete t;} 

         int IsEmpty()const 
         {return ((root) ? 0 : 1);} 

         int Root(T& x)const; 

         void MakeTree(const T& element, BinaryTree<T>& left, 
             BinaryTree<T>& right); 

         void BreakTree(T& element, BinaryTree<T>& left, 
              BinaryTree<T>& right); 

         void PreOrder(void(*Visit)(BinaryTreeNode<T> *u)) 
          {PreOrder(Visit, root);} 

         void InOrder(void(*Visit)(BinaryTreeNode<T> *u)) 
          {InOrder(Visit, root);} 

         void PostOrder(void(*Visit)(BinaryTreeNode<T> *u)) 
          {PostOrder(Visit, root);} 

         BinaryTreeNode<T>* root; //root pointer 

        //traversal methods 
         void PreOrder(void(*Visit) 
          (BinaryTreeNode<T> *u), BinaryTreeNode<T> *t); 

         void InOrder(void(*Visit) 
          (BinaryTreeNode<T> *u), BinaryTreeNode<T> *t); 

         void PostOrder(void(*Visit) 
          (BinaryTreeNode<T> *u), BinaryTreeNode<T> *t); 

         static void Output(BinaryTreeNode<T> *t) 
          { 
           cout << t->data << " "; 
          } 

         void PreOutput() 
         { 
          PreOrder(Output, root); 
          cout << endl; 
         } 

         void InOutput() 
         { 
          InOrder(Output, root); 
          cout << endl; 
         } 

         void PostOutput() 
         { 
          PostOrder(Output, root); 
          cout << endl; 
         } 
        }; 

//base class is BinaryTree - BSTree is the derived class 
template<class E, class K> 
class BSTree : public BinaryTree<E>{ 
     public: 
        int Search(const K& k, E& e)const; 
        BSTree<E,K>& Insert(const E& e); 
        BSTree<E,K>& Delete(const K& k, E& e); 
        //stores the maximum element of the tree in e 
        void MaxNode(E& e)const; 
     }; 


/*---------------------BinaryTree Methods()-------------------------*/ 
template<class T> 
int BinaryTree<T>::Root(T& x) const 
    { //Set x to root->data 
    //return false if no root 
    if(root) 
     { 
     x=root->data; 
     return 1; 
     } 
    else return 0; //no root 
    } 

template<class T> 
void BinaryTree<T>::MakeTree(const T& element, 
         BinaryTree<T>& left, BinaryTree<T>& right) 
    {//Combine left, right, and element to make new tree. 
    //left, right, and this must be different trees. 
    //create combined tree 

    root=new BinaryTreeNode<T>(element, left.root, right.root); 

    //deny access from trees left and right 
    left.root=right.root=0; 
    } 

template<class T> 
void BinaryTree<T>::BreakTree(T& element, 
         BinaryTree<T>& left, BinaryTree<T>& right) 
    {//left, right, and this must be of different trees. 
    //check if empty 

    if(!root) //empty tree 
     throw BadInput(); 

    //break the tree 
    element=root->data; 
    left.root=root->LeftChild; 
    right.root=root->RightChild; 

    delete root; 
    root=0; 
    } 

template<class T> 
void BinaryTree<T>::PreOrder(void(*Visit) 
         (BinaryTreeNode<T>* u), BinaryTreeNode<T>* t) 
    {//preorder traversal 

    if(t) 
     { 
     Visit(t); 
     PreOrder(Visit, t->LeftChild); 
     PreOrder(Visit, t->RightChild); 
     } 
    } 

template<class T> 
void BinaryTree<T>::InOrder(void(*Visit)(BinaryTreeNode<T>* u), 
            BinaryTreeNode<T>* t) 
    {//inorder traversal 

     if(t) 
     { 
      InOrder(Visit, t->LeftChild); 
      Visit(t); 
      InOrder(Visit, t->RightChild); 
     } 
    } 

template<class T> 
void BinaryTree<T>::PostOrder(void(*Visit)(BinaryTreeNode<T>* u), 
             BinaryTreeNode<T>* t) 
    {//postorder traversal 

    if(t) 
     { 
     PostOrder(Visit, t->LeftChild); 
     PostOrder(Visit, t->RightChild); 
     Visit(t); 
     } 
    } 
/*----------------------End of BinaryTree Methods()------------------*/ 

/*------------------------BSTree Methods()---------------------------*/ 

template<class E, class K> 
int BSTree<E,K>::Search(const K& k, E& e) const 
{//Search for element that matches k. 
    //Pointer p starts at the root and moves through 
    //the tree looking for an element with key k. 

    BinaryTreeNode<E> *p=root; 

    while(p) //examine p if >, <, or == 
     { 
     if(k<p->data) 
      p=p->LeftChild; 
     else if(k>p->data) 
      p=p->RightChild; 
     else{ //element is found 
       e=p->data; 
       return 1; 
      } 
     } 
    return 0; 
    } 

template<class E, class K> 
BSTree<E,K>& BSTree<E,K>::Insert(const E& e) 
{ //Insert e if not duplicate 

    BinaryTreeNode<E> *p=NULL; //search pointer 
    BinaryTreeNode<E> *pp=NULL;  //parent of p 

    //find place to insert throw BadInput if a duplicate element 
    p=root;  //p is now the root 

    while(p) 
    { 
    pp=p; 
    //move p to a child depending if p is > or < 

    if(e<p->data) 
     p=p->LeftChild; 

    else if(e>p->data) 
     p=p->RightChild; 

    else 
     throw BadInput(); //a duplicate element 
    } 

    //Get a node (memory) for e and attach to pp 
    BinaryTreeNode<E> *r=new BinaryTreeNode<E>(e); 

    if(root) 
     {//tree not empty 

     if(e<pp->data) 
     pp->LeftChild=r; 

     else if(e>pp->data) 
     pp->RightChild=r; 
     } 

    else //we need a root first! 
     root=r; 

    return *this; 
    } 

template<class E, class K> 
BSTree<E,K>& BSTree<E,K>:: Delete(const K& k, E& e) 
{//Delete element with key k and put it in e. 
    //set p to point to node with key k 

    BinaryTreeNode<E> *p=NULL; //a search pointer 
    BinaryTreeNode<E> *pp=NULL; //parent of p 

    p=root; 

    while(p && p->data != k) 
    {//move to a child of p 

    pp=p; 

     if(k < p->data) 
     p=p->LeftChild; 

     else 
     p=p->RightChild; 
    } 

    if(!p)    //no element with key k 
    throw NoElement(); 

    e=p->data; //save element to delete 

    //restructure the tree so it remains a BSTree 
    if(p->LeftChild && p->RightChild) //handle the node with 2 children if any 
     {//convert it to point to NULL or one child case 
     //find largest element in left subtree of p 

     BinaryTreeNode<E> *s=p->LeftChild; 
     BinaryTreeNode<E> *ps=p; //parent of s which is actually p 

     while(s->RightChild) 
     {//move to the larger element 
      ps=s; 
      s=s->RightChild; 
     }//end while 

     //move largest from s to p 
     p->data=s->data; 
     p=s; 
     pp=ps; 
     }//end all if 

    //p only had one child 
    //save child pointer in c 
    BinaryTreeNode<E> *c; 

    if(p->LeftChild) 
    c=p->LeftChild; 

    else 
    c=p->RightChild; 
    //delete p 

    if(p==root) 
     root=c; 

    else{ 
      //is p left or right child of pp? 
      if(p==pp->LeftChild) 
       pp->LeftChild=c; 

      else 
       pp->RightChild=c; 
     }//end else 
    delete p; 
    return *this; 
} 

template<class E, class K> 
void BSTree<E,K>::MaxNode(E &e)const 
{//function returns max. value of tree (rightmost value) 

    BinaryTreeNode<E>* p=NULL; //root node 
    BinaryTreeNode<E>* pp=NULL; //parent of p 

    p=root; 

    while(p) 
    { 
    pp=p; 
    p=p->RightChild; 
    } 
    //p points to NULL, pp points to node before NULL 
e=pp->data; //max. value stored 
} 

char Menu() 
{ 
    char choice; 

    //a menu 
    cout << "\n\t\tBST TREE MENU\n"; 
    cout << "\t********************************\n"; 
    cout << "\t* 1)Type 1 to insert an element*\n"; 
    cout << "\t* 2)Type 2 to delete an element*\n"; 
    cout << "\t* 3)Type 3 to output pre-order *\n"; 
    cout << "\t* 4)Type 4 to output in-order *\n"; 
    cout << "\t* 5)Type 5 to output post-order*\n"; 
    cout << "\t* 6)Type 6 for maximum element *\n"; 
    cout << "\t* 7)Type 7 to output root  *\n"; 
    cout << "\t* 8)Type 8 to search for a # *\n"; 
    cout << "\t* 9)Type 9 to exit program. *\n"; 
    cout << "\t********************************\n"; 

    cout << "Input your choice: "; 
    cin >> choice; 

    while(choice!='1' && choice!='2' && choice!='3' 
      && choice!='4' && choice!='5' && choice!='6' 
      && choice!='7' && choice!='8' && choice!='9') 
     {//user typed in wrong key 
      cout << "\nType choice as 1-9: "; 
      cin >> choice; 
     } 
    return choice; 
} 
+0

!!!!! TABS !!!!! – 2009-11-19 16:26:43

+0

嘿,現在它的很多代碼! 開源:)再加上記得我剛上大學! – JonH 2009-11-19 16:54:45