如何深度首次打印B + Tree C ++?

时间:2013-10-30 03:28:02

标签: c++

我有一个订单5 Btree,包含插入,高度,查找和打印方法。我很难理解如何打印深度的第一个A-Z?我有一个打印功能将显示每个节点和其中的元素,但想了解如何按顺序打印。我更喜欢AVL树。

#include <iostream>
#include <stdlib.h>
#include <string>

using namespace std;


const int MAX = 4 ; //maximum # of keys
const int MIN = 2 ; //minimum # of keys

struct btnode  
{
    int count ;
    string value[MAX + 1] ;  //number of elements + 1;
    btnode *child[MAX + 1] ;
} ;

class btree   
{
    private :
        btnode *root ;
    public :
        btree( ) ;
        void insert ( string val ) ;
        int setValue ( string val, btnode *n, string *p, btnode **c ) ;
        static int searchNode ( string val, btnode *n, int *pos ) ;
        void fillNode ( string val, btnode *c, btnode *n, int k ) ;
        void split ( string val, btnode *c, btnode *n, int k, string *y, btnode **newnode ) ;
        void show( ) ;
        //void search(string key);
        int searchPos(string key,string *key_arr,int n);  //sub-function for search
        static void display ( btnode *root) ;
       // void height(string key);
} ;


btree :: btree( )
{
    root = NULL ;
}

int btree :: searchNode ( string val, btnode *n, int *pos )  //searches for string in node
{
    if ( val < n -> value[1] )
    {
        *pos = 0 ;
        return 0 ;
    }
    else
    {
        *pos = n -> count ;
        while ( ( val < n -> value[*pos] ) && *pos > 1 )
            ( *pos )-- ;
        if ( val == n -> value[*pos] )      //if value exists in the node returns 
        {    
            for(int j =0; j <= n->count; j++)
            {
                //cout<<"Test in searchmode function"<<endl;
                cout<<n->value[j]<<endl;
            }
        return 1 ;
        }   

        else
            return 0 ;
    }
}

void btree :: insert ( string val )  //inputting a string
{
    string in ;
    btnode *c, *n ;
    int flag ;
    flag = setValue ( val, root, &in, &c );  //in flag has value

    if ( flag )
    {
        n = new btnode ;            //create a new btnode
        n -> count = 1 ;            //initiates the count to 1
        n -> value[1] = in ;        //value of our node is set to the String passed in
        n -> child[0] = root ;      //setting pointer of child[0] to root
        n -> child[1] = c ;         
        root = n ;
    }
}
int btree :: setValue ( string val, btnode *n, string *p, btnode **ch )    //returns  1 or 0 to set flag
{
    int key ;

    if ( n == NULL )
    {
        *p = val ;
        *ch = NULL ;
        return 1 ;      //if root is NULL 1 is returned to flag and node is created
    }
    else
    {
        if ( searchNode ( val, n, &key ) )  //checks if the value has already been entered
            cout << endl << "Key value already exists." << endl ;

        if ( setValue ( val, n -> child[key], p, ch ) )  
        {
            if ( n -> count < MAX )   //if the node is less than MAX order the node is filled
            {
                fillNode ( *p, *ch, n, key ) ;      
                return 0 ;          //value is returned as 0 to flag    
            }
            else                    //if the MAX for node is met split
            {
                split ( *p, *ch, n, key, p, ch ) ;
                return 1 ;          //after split 1 is returned to flag to set node value
            }
        }
        return 0 ;
    }
}

void btree :: fillNode ( string val, btnode *c, btnode *n, int k )   //function to fill the node
{
    int i ;
    for ( i = n -> count ; i > k ; i-- )     //first node count is = to 1, k=0
    {
        n -> value[i + 1] = n -> value[i] ; 
        n -> child[i + 1] = n -> child[i] ;
    }
    n -> value[k + 1] = val ;       //assigns string to location in node
    n -> child[k + 1] = c ;         //assigns pointer to child
    n -> count++ ;                  //increments node count by one

}

void btree :: split ( string val, btnode *c, btnode *n,
        int k, string *y, btnode **newnode )
{
    int i, mid ;
    cout<<"In split function k is :"<<k;
    if ( k <= MIN )     
        mid = MIN ;     //Min is defined as 2, the minimum number in a node
    else
        mid = MIN + 1 ; //k passing as 3 or 4 will make the midpoint 3

    *newnode = new btnode ;

    for ( i = mid + 1 ; i <= MAX ; i++ )
    {
        ( *newnode ) -> value[i - mid] = n -> value[i] ;  //new node value is placed at i - mid point setting it as first position in split node
        ( *newnode ) -> child[i - mid] = n -> child[i] ;
    }

    ( *newnode ) -> count = MAX - mid ;
    n -> count = mid ;

    if ( k <= MIN )
        fillNode ( val, c, n, k ) ;
    else
        fillNode ( val, c, *newnode, k - mid ) ;  //fillNode is called and *newnode

    *y = n -> value[n -> count] ;                           //mid point moves up to root node
    ( *newnode ) -> child[0] = n -> child[n -> count] ;   
    n -> count-- ;
}


void btree :: show( )
{
    display ( root ) ;
}


void btree :: display ( btnode *root)  
{

    int i=0;
    if ( root != NULL )
    {

        for ( i = 0 ; i < root -> count ; i++ )
        {
               cout<< root->value[i]  ;
           display ( root -> child[i] ) ;

        }
       display ( root-> child[i] ) ;
        //cout<< root->value[i]  ;
    }



}

int main( )
{
    btree b ;
    int choice;
    string key;
    string t = "temp"; //to run through height function.
    do{
    cout<<"\n\n\tSELECT YOUR CHOICE\n\n1. insert\n2. search\n3. display\n4. height\n\n5. EXIT\n\n\n=";
    cin>>choice;
    switch(choice)
    {
                  case 1:cout<<"\n\nEnter the string to be inserted:";
                         cin>>key;
                         b.insert(key);
                         break;
                  case 2:cout<<"\n\nEnter search:";
                          cin>>key;
                         // b.search(key);
                          break;
                  case 3:
                    cout<<"could not get to print A-Z?!." <<endl;
                       b.show();
                       cout<<"\n";
                         break;
                    case 4:

                       //b.height(t);
                       cout<<"\n";
                         break;      

                 case 5:break;
                   default:cout<<"\nINVALID ENTRY";
                           break;};
                           }while(choice!=5);

    return 0;
}

2 个答案:

答案 0 :(得分:0)

void btree :: display ( btnode *root)  
{
    int i=0;
    if ( root != NULL )
    {
        for ( i = 0 ; i < root -> count ; i++ )
        {
               cout<< root->value[i]  ;
           display ( root -> child[i] ) ;

        }

到目前为止一切顺利。

       display ( root-> child[i] ) ;
        //cout<< root->value[i]  ;

删除它。它再次显示root-&gt; child [0]。你已经做到了。

    }
}

答案 1 :(得分:0)

我调试代码的方式是(a)使其成为非交互式的,这样我就可以轻松地运行测试,(b)添加打印功能和语句。我从main()中删除了“用户界面”代码,并将其替换为硬编码的内容。

您的部分问题是insert()功能;它可能不会做你认为它做的事情。特别是,它将空树中的第一个值放入value[1],而不是value[0]。我围绕这个问题编写了代码;在您需要拆分节点之前,它会有效。那时,它似乎丢失了一些数据。

玩得开心。

您应该将传递的字符串视为引用而不是值;我已经修复了一些,但绝不是所有这些。我找不到你需要的地方<stdlib.h>;我确实添加了<cassert>和一些断言,但我没有得到断言。

检测代码

#include <cassert>
#include <iostream>
#include <string>

using namespace std;

const int MAX = 4;
const int MIN = 2;

struct btnode
{
    int count;
    string value[MAX + 1];
    btnode *child[MAX + 1];
    void dump(ostream &out, const string &tag);
};

void btnode::dump(ostream &out, const string &tag)
{
    out << "-->> " << tag << ":\n";
    out << "Count:   " << count << "\n";
    assert(value[0] == "");
    for (int i = 1; i <= count; i++)
        out << "Value " << i << " = <<" << value[i] << ">>\n";
    out << "<<-- " << tag << "\n";
}

class btree
{
    private:
        btnode *root;
    public:
        btree() : root(0) {}
        void insert(const string &val);
        int setValue(const string &val, btnode *n, string *p, btnode **c);
        void fillNode(string val, btnode *c, btnode *n, int k);
        void split(string val, btnode *c, btnode *n, int k, string *y, btnode **newnode);
        void show();
        int searchPos(string key,string *key_arr,int n);
        static void display(btnode *root);
        static int searchNode(const string &val, btnode *n, int *pos);
};

int btree::searchNode(const string &val, btnode *n, int *pos)
{
    if (val < n->value[1])
    {
        *pos = 0;
        return 0;
    }
    else
    {
        *pos = n->count;
        while ((val < n->value[*pos]) && *pos > 1)
            (*pos)--;
        if (val == n->value[*pos])
        {
            for(int j =0; j <= n->count; j++)
            {
                cout << n->value[j] << endl;
            }
            return 1;
        }
        else
            return 0;
    }
}

void btree::insert(const string &val)
{
    cout << "-->> btree::insert('" << val << "')\n";
    string in = "";
    btnode *c = 0;
    int flag = setValue(val, root, &in, &c);
    cout << "setValue set flag = " << flag << "\n";

    if (flag)
    {
        cout << "Creating new node\n";
        btnode *n = new btnode;
        assert(n != 0);
        n->count = 1;
        n->value[0] = "";
        n->value[1] = in;
        n->child[0] = root;
        n->child[1] = c;
        n->dump(cout, "New node");
        root = n;
        this->show();
    }
    cout << "<<-- btree::insert()\n";
}

int btree::setValue(const string &val, btnode *n, string *p, btnode **ch)
{
    cout << "-->> setValue: <<" << val << ">>\n";
    if (n == NULL)
    {
        *p = val;
        *ch = NULL;
        cout << "<<-- setValue: 1A\n";
        return 1;
    }
    else
    {
        int key;
        if (searchNode(val, n, &key))
            cout << endl << "Key value already exists." << endl;

        if (setValue(val, n->child[key], p, ch))
        {
            if (n->count < MAX)
            {
                fillNode(*p, *ch, n, key);
                cout << "<<-- setValue: 0A\n";
                return 0;
            }
            else
            {
                split(*p, *ch, n, key, p, ch);
                cout << "<<-- setValue: 1B\n";
                return 1;
            }
        }
        cout << "<<-- setValue: 0B\n";
        return 0;
    }
}

void btree::fillNode(string val, btnode *c, btnode *n, int k)
{
    for (int i = n->count; i > k; i--)
    {
        n->value[i + 1] = n->value[i];
        n->child[i + 1] = n->child[i];
    }
    n->value[k + 1] = val;
    n->child[k + 1] = c;
    n->count++;
}

void btree::split(string val, btnode *c, btnode *n,
        int k, string *y, btnode **newnode)
{
    int i, mid;
    cout << "In split function k is: " << k << "\n";
    if (k <= MIN)
        mid = MIN;
    else
        mid = MIN + 1;

    *newnode = new btnode;

    for (i = mid + 1; i <= MAX; i++)
    {
        (*newnode)->value[i - mid] = n->value[i];
        (*newnode)->child[i - mid] = n->child[i];
    }

    (*newnode)->count = MAX - mid;
    n->count = mid;

    if (k <= MIN)
        fillNode(val, c, n, k);
    else
        fillNode(val, c, *newnode, k - mid);

    *y = n->value[n->count];
    (*newnode)->child[0] = n->child[n->count];
    n->count--;
}

void btree::show()
{
    cout << "-->> show():\n";
    display(root);
    cout << "<<-- show()\n";
}

void btree::display(btnode *root)
{
    if (root != NULL)
    {
        cout << "Root is not null\n";
        int i;
        for (i = 1; i <= root->count; i++)
        {
            cout << "Value " << i << " = <<" << root->value[i] << ">>\n";
            if (root->child[i-1])
                display(root->child[i-1]);
        }
        if (root->child[i])
            display(root->child[i]);
    }
    else
        cout << "Root is null\n";
}

int main()
{
    btree b;

    string key = "amaranthine";
    b.insert(key);
    b.show();

    key = "absinthe";
    b.insert(key);
    b.show();

    key = "amazonia";
    b.insert(key);
    b.show();

    key = "zululand";
    b.insert(key);
    b.show();

    key = "asbestos";
    b.insert(key);
    b.show();

    return 0;
}

示例输出

-->> btree::insert('amaranthine')
-->> setValue: <<amaranthine>>
<<-- setValue: 1A
setValue set flag = 1
Creating new node
-->> New node:
Count:   1
Value 1 = <<amaranthine>>
<<-- New node
-->> show():
Root is not null
Value 1 = <<amaranthine>>
<<-- show()
<<-- btree::insert()
-->> show():
Root is not null
Value 1 = <<amaranthine>>
<<-- show()
-->> btree::insert('absinthe')
-->> setValue: <<absinthe>>
-->> setValue: <<absinthe>>
<<-- setValue: 1A
<<-- setValue: 0A
setValue set flag = 0
<<-- btree::insert()
-->> show():
Root is not null
Value 1 = <<absinthe>>
Value 2 = <<amaranthine>>
<<-- show()
-->> btree::insert('amazonia')
-->> setValue: <<amazonia>>
-->> setValue: <<amazonia>>
<<-- setValue: 1A
<<-- setValue: 0A
setValue set flag = 0
<<-- btree::insert()
-->> show():
Root is not null
Value 1 = <<absinthe>>
Value 2 = <<amaranthine>>
Value 3 = <<amazonia>>
<<-- show()
-->> btree::insert('zululand')
-->> setValue: <<zululand>>
-->> setValue: <<zululand>>
<<-- setValue: 1A
<<-- setValue: 0A
setValue set flag = 0
<<-- btree::insert()
-->> show():
Root is not null
Value 1 = <<absinthe>>
Value 2 = <<amaranthine>>
Value 3 = <<amazonia>>
Value 4 = <<zululand>>
<<-- show()
-->> btree::insert('asbestos')
-->> setValue: <<asbestos>>
-->> setValue: <<asbestos>>
<<-- setValue: 1A
In split function k is: 3
<<-- setValue: 1B
setValue set flag = 1
Creating new node
-->> New node:
Count:   1
Value 1 = <<amazonia>>
<<-- New node
-->> show():
Root is not null
Value 1 = <<amazonia>>
Root is not null
Value 1 = <<absinthe>>
Value 2 = <<amaranthine>>
<<-- show()
<<-- btree::insert()
-->> show():
Root is not null
Value 1 = <<amazonia>>
Root is not null
Value 1 = <<absinthe>>
Value 2 = <<amaranthine>>
<<-- show()