平衡二叉搜索树搜索功能

时间:2015-12-01 21:19:33

标签: c++ search binary-search-tree avl-tree

我正在为水果集市编写代码,其中每个用户的数据都存储在二叉树中。当用户想要登录时,他应该输入他的用户名。程序应该在树中搜索用户名并执行相关的功能。

当用户名不存在时,搜索功能会返回正确的值,并显示相应的消息,但在找到用户名时,它不会显示任何消息或错误。(根据程序,它应显示&#39) ;你好')。通过使用' inorder'功能我检查了树是否正确形成 - 它是否正确形成。附上的是代码。

#include <iostream>
#include<fstream>
#include<string.h>
using namespace std;

class node                  //Create a class for node.
{  public:
    char First_Name[30];
    char Last_Name[30];
    char Email_id[50];
    int long Phone;
    char Username[20];
    char Location[25];
    node *lc;
    node *rc;
    int h;
    friend class avl;

};

class avl                   //Create a class for avl.
{public:
    node* root;
    avl()
    {
        root=NULL;          //Initialise root to NULL.
    }
    node *insert(node *root,char[],char[],char[],char[],char[],int long);
    void insert1();
    int height(node *);
    int bal_fac(node*);
    node *LL(node*);
    node *LR(node*);
    node *RL(node*);
    node *RR(node*);
    int search(char[]);                                  
    node *getinfo(char[]);
    void inorder(node*);
};

void avl::inorder(node *root)   //To print the inorder sequence.
{
    if(root==NULL)
        return ;
    else
    {
        inorder(root->lc);
        cout<<root->Username<<" ";
        inorder(root->rc);
    }
}

void avl:: insert1()        //Insert1 function to read file contents.
{
    char firstname[30]=" ";
    char lastname[30]=" ";
    char email_id[50]=" ";
    int long contact=0;
    char name[20];
    cout<<endl<<"Enter your First name: ";
    cin>>firstname;
    cin.ignore();
    cout<<endl<<"Enter your Last name: ";
    cin>>lastname;
    cin.ignore();
    cout<<endl<<"Enter your Email id: ";
    cin>>email_id;
    cin.ignore();
    cout<<endl<<"Enter your phone number: ";
    cin>>contact;
    cin.ignore();
    cout<<endl<<"Enter your User name: ";
    cin>>name;
    cin.ignore();
    int len=strlen(name);
    len+=4;
    char file[len];

    fstream myfile;
    int i;
    for (i=0;i<strlen(name);i++)
    {
        file[i]=name[i];
    }
    file[i++]='.';
    file[i++]='t';
    file[i++]='x';
    file[i++]='t';
    file[i]='\0';

    myfile.open(file,ios::app); //To read from file using object myfile.
    if(myfile.is_open())
    {

        myfile<<"Item\t\tQuantity\t\tTime "<<endl;
        root=insert(root,firstname,lastname,email_id,name,file,contact);   
        myfile.close();
            }
    else
        cout<<"Unable to open file"<<endl;

            }

int avl::search(char username[20])
{
    int flag=0;

    node *ptr;
    ptr=root;
    while(ptr!=NULL)
    {
        int a=strcmp(ptr->Username,username);                          
        if (a>0)                  //if the entered word is smaller than ptr
            ptr=ptr->lc;                    //traverse left sub-tree
        else
            if (a<0)              //if the entered word is greater than ptr
                ptr=ptr->rc;                //traverse right sub-tree
            else
                if(a==0)               //if ptr is the entered word
                {
                    flag=1;
                    cout<<"Heyy!!";
                    return flag;
                }
    }
    return flag;
}

node* avl::getinfo(char username[20])
{
    node *ptr;
    node *temp;
    ptr=root;
    while(ptr!=NULL)
    {
        int a=strcmp(ptr->Username,username);                          
        if (a>0)                //if the entered word is smaller than ptr
            ptr=ptr->lc;                   //traverse left sub-tree
        else
            if (a<0)          //if the entered word is greater than ptr
                ptr=ptr->rc;                   //traverse right sub-tree
            else
                if(a==0)                //if ptr is the entered word
                {
                    temp=ptr;
                }
    }
    return temp;
}

node *avl::insert(node *root,char firstname[30], char lastname[30], char email_id[50], char username[20], char filename[25], long int number)
{
    int bal;
    if(root==NULL)                  //Initial node
    {
        root=new node;
        strcpy(root->First_Name,firstname);
        strcpy(root->Last_Name,lastname);
        strcpy(root->Email_id,email_id);
        root->Phone=number;
        strcpy(root->Username,username);
        strcpy(root->Location,filename);
        root->lc=NULL;
        root->rc=NULL;
        root->h=0;
        return(root);
    }
    if(strcmp(username,root->Username)<0)//Inserted node is smaller than root.
    {
 root->lc=insert(root->lc,firstname,lastname,email_id,username,filename,number);
        bal=bal_fac(root);      //Calculate balance factor.
        if(bal==2)      //Left child of unbalanced node is affected.
        {
            if(strcmp(username,root->lc->Username)<0)
        {
                   root=LL(root);   //Left sub-tree is affected.
        }
            else
                root=LR(root);      //Right sub-tree is affected.
        }
    }
    else            //Inserted node is greater than root.
        {
            root->rc=insert(root->rc,firstname,lastname,email_id,username,filename,number);//Insert to the right.
            bal=bal_fac(root);      //Calculate balance factor.
            if(bal==-2)     //Right child of unbalanced node is affected.
            {
                if(strcmp(username,root->rc->Username)>0)
                    root=RR(root) ; //Right sub-tree is affected.
                else
                    root=RL(root);  //Left sub-tree is affected.

            }
        }
        root->h=height(root);       //Calculate height of node.
        return(root);
    }


int avl::height(node*root)
{
    int lh,rh;

    if(root==NULL)
    {
        return 0;
    }


    if (root->lc==NULL)
    lh= 0;
    else
    lh= 1+root->lc->h;

        if (root->rc==NULL)
            rh= 0;
            else
            rh= 1+root->rc->h;
        if(lh>rh)
            return lh;
        else
            return rh;
}
int avl::bal_fac(node *root)
{
    if (root== NULL)
    return 0;
    int lh=0;

    if (root->lc==NULL)
    lh= 0;
    else
    lh= 1+height(root->lc);
    int rh=0;
    if (root->rc==NULL)
        rh= 0;
        else
        rh= 1+height(root->rc);
    int bf=lh-rh;
    return bf;
}
node *avl::LL(node *root)
{
    node *temp;
temp=root->lc;
root->lc=temp->rc;
temp->rc=root;
temp->h=height(temp);
root->h=height(root);
cout<<"LL"<<endl;
return temp;        //Return the new root.


}
node *avl::RR(node *root)
{
    node *temp;
    temp=root->rc;
    root->rc=temp->lc;
    temp->lc=root;
    temp->h=height(temp);
    root->h=height(root);
    cout<<"RR"<<endl;
    return temp;        //Return the new root.
}
node *avl::LR(node *root)
{
    root->lc=RR(root->lc);

    root=LL(root);
    cout<<"LR"<<endl;
    return root;        //Return the new root.

}
node *avl::RL(node *root)
{
    root->rc=LL(root->rc);

    root=RR(root);
    cout<<"RL"<<endl;
    return root;        //Return the new root.
}


int main() {
    avl a;
    int user=0;
    char ch,uname[20]=" ",choice;
    cout<<endl<<"Welcome to XYZ Fruit Mart!!!"<<endl;
    do
    {
        cout<<"Are you an existing customer?"<<endl;
        cout<<"(Press y/Y for yes or n/N for no):  ";
        cin>>ch;
        if(ch=='y'||ch=='Y')
        {
            cout<<endl<<"Enter your Username:  ";
            cin>>uname;
            user=a.search(uname);
            if(user==0)
            {
                cout<<endl<<"THIS USERNAME DOES NOT EXIST. PLEASE CHECK YOUR USERNAME AGAIN";
            }
            else
            {
                cout<<"Hello";
                a.activity(uname);
            }
        }
        if(ch=='n'||ch=='N')
        {
            cout<<endl<<"Create your own login with us to use our services.";
            a.insert1();
            cout<<endl<<"Your Account is now created. Login again to acess services.";
        }
        cout<<endl<<"Do you want to login again? (Press y/Y for yes or n/N for no):  ";
        cin>>choice;
    }while(choice=='y'||choice=='Y');


    return 0;
}

1 个答案:

答案 0 :(得分:0)

insert1()中存在内存损坏。

创建文件名时,您要在名称长度上添加4,以便能够添加&#34; .txt&#34;。不幸的是,你不计算结局&#39; \ 0&#39;这可能会造成很多附带损害。

纠正长度:

int len = strlen(name);
len += 5;

我使用更正后的代码进行了一些调整,它按预期工作(我注释掉了a.activitiy(),因为它没有定义)。

重要说明:

您正在使用可变长度数组(char file[len];)。这可能适用于某些编译器,但不是C ++标准的一部分,并且不可移植。最好忘了它。不要使用这样的char数组和C样式strxxx()函数,而应考虑认真使用c ++ std::string

从设计的角度来看,在AVL类的功能中管理I / O或应用程序命令并不是最佳选择。 I / O在这里与节点更相关,应作为节点的成员函数进行管理,或作为标准提取器的重载进行管理。