Почему рут никогда не меняется и почему я получаю ошибку неверного доступа? - PullRequest
1 голос
/ 21 марта 2012

Я работаю над заданием, чтобы создать самоупорядоченное дерево бинарного поиска, которое реорганизует себя каждый раз, когда дублирующий элемент пытается вставить в дерево. У меня есть несколько ошибок, которые мне нужно решить.

Во-первых, корень дерева никогда не меняется (что я предполагаю, что проблема в методах RotateLeft или RotateRight). У меня есть пример файла, который я читаю, и когда я иду по коду, кажется, все соответственно, но когда появляется первый дубликат, корень никогда не изменяется на узел с более высоким приоритетом.

Вторая ошибка, которую я получаю, это ОШИБКА ДОСТУПА К ДОСТУПАМ (я отметил, где это находится в коде ниже), который я предполагаю, также от одного из тех методов Rotate.

#ifndef SelfOrganizingTree_SOBTree_h
#define SelfOrganizingTree_SOBTree_h

#include "BinaryNode.h"
#include "bst.h"


template <class T>
class BinaryNode;

template <class T>
class SOBTree: public BinarySearchTree<T> {
public:
    SOBTree();
    void insert( const T& x );
    void remove( const T& x );
    bool isEmpty() const;
    void printTree() const;
    int reportComparisonCount();
    double reportCPUTime();


private:
    void insert( const T & x, BinaryNode<T> * & t , BinaryNode<T> * & rootNode);
    void RotateRight(BinaryNode<T> * & root );
    void RotateLeft(BinaryNode<T> * & root );
    void printTree(BinaryNode<T> *t) const;
    BinaryNode<T> *root;
    void balance (BinaryNode<T> * & root);

};

template <class T >
SOBTree<T> ::  SOBTree()
{
    root = NULL; 
}

/**
 * Insert x into the tree
 */
template <class T >
void SOBTree<T > ::  insert( const T & x )
{
    insert( x, root , root);
}

/**
 * Internal method to insert into a subtree.
 * x is the item to insert.
 * t is the node that roots the subtree.
 * Set the new root of the subtree.
 */
template <class T>
void SOBTree<T> ::  insert( const T & x, BinaryNode<T> * & t , BinaryNode<T> * & rootNode)
{
   // BinaryNode<T> *current = t;
    if( t == NULL ){
        t = new BinaryNode<T>( x, NULL, NULL, rootNode );
        //cout << t->element << endl;
        t->priority++;
    }
    else if( x < t->element ){
        //cout << "left" << endl;
        insert( x, t->left , t);
    }
    else if( t->element < x ){
        //cout << "right" << endl;
        insert( x, t->right , t);
    }
    else{
        //cout << "match found" << endl;
        t->priority++;  // Duplicate; rotate right or left if priority is higher than the root
        balance(t);
    }
}

template <class T>
void SOBTree<T>::balance (BinaryNode<T> * & rootN){

    cout << "root: " << root->element << endl;
    if (rootN->parent && rootN->priority > rootN->parent->priority) { //THIS IS WHERE THE BAD ACCESS ERROR IS BEING THROWN
        if (rootN->parent->left == rootN) {

            RotateLeft(rootN->parent);
            balance(rootN->parent);

        }else if (rootN->parent->right == rootN){

            RotateRight(rootN->parent); 
            balance(rootN->parent);

        }
    }

}


template <class T>
void
SOBTree<T>::RotateLeft(BinaryNode<T> * & rootN) {
    /*
     Let P be Q's left child.
     Set P to be the new root.
     Set Q's left child to be P's right child.
     Set P's right child to be Q.
     */

    BinaryNode<T> * oldRoot = rootN;

    // perform rotation
    rootN = rootN->left;
    oldRoot->left = rootN->right;
    rootN->right= oldRoot;

}


template <class T>
void
SOBTree<T>::RotateRight(BinaryNode<T> * & rootN) {
    /*
     Let Q be P's right child.
     Set Q to be the new root.
     Set P's right child to be Q's left child.
     Set Q's left child to be P.
     */

   BinaryNode<T> * oldRoot = rootN;

    // perform rotation
    rootN = rootN->right;
    oldRoot->right = rootN->left;
    rootN->left = oldRoot;

}

template <class T>
bool SOBTree<T> ::  isEmpty( ) const
{
    return root == NULL;
}

/**
 * Print the tree contents in sorted order.
 */
template <class T>
void SOBTree<T> ::  printTree(  ) const
{
    if( isEmpty( ) )
        cout << "Empty tree" << endl;
    else
        printTree( root );
}

template <class T>
void SOBTree<T> ::  printTree( BinaryNode<T> *t ) const
{
    if( t != NULL )
    {

        printTree( t->left );
        cout << t->element << endl;
        printTree( t->right );
    }else
        return;
}



#endif

Вот код для структуры BinaryNode:

template <class Type>
class BinarySearchTree;     //forward declaration so BinaryNode knows about BinarySearchTree

template <class Type>
class BinaryNode{
public:
    Type element;
    BinaryNode<Type>* left;
    BinaryNode<Type>* right;
    BinaryNode<Type>* parent;
    int priority;

    BinaryNode( Type theElement, BinaryNode *lt, BinaryNode* rt, BinaryNode *par = NULL, int pri = 0) :
          element(theElement), left(lt), right(rt) ,  parent(par), priority(pri)
    { }

    friend  class BinarySearchTree<Type>;
};

Кто-нибудь видит что-нибудь, что я мог бы изменить, чтобы помочь?

1 Ответ

0 голосов
/ 22 марта 2012
if (rootN->parent && rootN->priority > rootN->parent->priority) { 

Либо rootN, либо rootN->parent равно NULL, либо неверный указатель.

...