有没有人知道这个程序有什么问题?

时间:2012-02-28 23:27:51

标签: c++ binary-tree

此程序应插入,删除二叉树节点。 问题是当我删除后显示树元素时,程序显示错误。请帮助我的程序中的错误。

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

class Tnode
{
public:
    class Tnode *left;
    class Tnode *right;
    int info;
};

class tree: public Tnode
{
public:
    int top;
    Tnode *root;

    tree()
    {
        root=NULL;
        top=0;
    }

    void insert(int ch)
    {
        Tnode *temp,*temp1;
        if(root== NULL)
        {
            root=new Tnode;
            root->info=ch;
            root->left=NULL;
            root->right=NULL;
            return;
        }
        temp1=new Tnode;
        temp1->info=ch;
        temp1->right=temp1->left=NULL;
        temp=search(root,ch);
        if(temp->info>ch)
            temp->left=temp1;
        else
            temp->right=temp1;
    }

    Tnode *search(Tnode *temp,int ch)
    {
        if(root== NULL)
        {
            cout <<"no node present";
            return NULL;
        }
        if(temp->left==NULL && temp->right== NULL)
            return temp;

        if(temp->info>ch)
        {
            if(temp->left==NULL) return temp;
            search(temp->left,ch);
        }
        else
        { 
            if(temp->right==NULL) return temp;
            search(temp->right,ch);
        }
    }

    void display(Tnode *temp)
    {
        if(temp==NULL)
            return;

         display(temp->left);
         cout<<temp->info;
         display(temp->right);
    }

    Tnode *getposition(Tnode *root, int x)
    {  
        Tnode *temp;
        temp=root;
        while(temp&&temp->info != x)
            ((temp->info>x)?(temp=temp->left):(temp=temp->right));
        return(temp);
    }

    Tnode *getleft_right_most(Tnode *temp)
    { 
        Tnode *m=temp->left;
        while(temp->right)
            temp=temp->right;
            return temp;
    }

    Tnode *getfather(Tnode *root, Tnode *temp)
    {  
        Tnode *h=root;
        while(h->left!=temp&&h->right!=temp)
            ((h->info>temp->info)?h=h->left : h=h->right);
        return h;
    }

    Tnode *del(Tnode *temp, Tnode *f)
    {
        if(temp->left&&temp->right)
        if(temp->right)
        { 
            (f->left==temp)?f->left=temp->right : f->left=temp->right;
            temp->right=0;
        }
        if(temp->left)
        {
            (f->right==temp)?f->right=temp->left : f->right=temp->right;
            temp->left=0;
        }

        free(temp);
    }

    Tnode *delroot(Tnode *root)
    {  
        Tnode *d=root;
        if((d->right)&&!(d->left))
        { 
            root=d->right;
            d->right=0;
        }
        else if((d->left)&&!(d->right))
        { 
            root=d->left;
            d->left=0;
        }
        else
            root=0;
        return d;
    }

    Tnode *delprocess(Tnode *root, int key)
    {
        Tnode *d=root;
        Tnode *temp,*f,*t,*Re;
        if(root->info==key)
        {
            Re=delroot(d);
            return(Re);
        }
        else
        { 
            temp=getposition(d,key);
            if(temp->left!=0&&temp->right!=0)
            { 
                t=getleft_right_most(temp);
                temp->info=t->info;
                temp=t;
            }

            f=getfather(d,temp);
            Re=del(temp,f);
            return(Re);
        }
    }
};

main()
{
    tree t1;

    int ch,n,i;
    while(1)
    {
        cout <<"\n1.INSERT\n2.DELETE NUMBER\n3.DISPLAY\n4.EXIT\nEnter your                                       choice:";
        cin >> ch;
        switch(ch)
        {
        case 1:   do{
                 cout <<"\nenter the elements you want to insert:";
                    cin >> ch;
                 cout<<"\nto exit insert the number -1.";
                       if(ch!=-1)
                       t1.insert(ch);
                      }while(ch!=-1);
                        break;
        case 2:   t1.display(t1.root);break;
        case 3:    cout<<"\nto delete a number of your insertion enter it : ";
                   cin>>n;
                 t1.root=t1.delprocess(t1.root,n);
                 cout<<"\nthe tree after deletion is : ";
                 t1.display(t1.root); break;
        case 4:   exit(1);
        }
    }
}

3 个答案:

答案 0 :(得分:2)

没有<iostream.h>。您必须使用<iostream>。并将<stdlib.h>替换为<cstdlib>

此外,您使用的是coutcin,它们都在命名空间std中定义。因此,请在文件开头使用std::coutusing namespace std;,但我不建议使用后者。

所以用以下代码替换你的前三行,你的程序将编译:

#include <iostream>
#include <cstdlib>
#include <string>

using namespace std;

但是,如果您编译代码没有问题,并且您的错误完全不同,那么您应该在问题中添加具体的错误消息。

答案 1 :(得分:2)

这有点错误:

  1. #include <iostream.h>需要#include <iostream>
  2. main()需要int main()
  3. tree::del需要返回一个值。
  4. main()中的开关案例与交换机上方的消息输出不匹配。
  5. 如果控件进入最后一个tree::search块,则
  6. if else不会返回值。
  7. 由于Tnode是使用new分配的,因此应使用delete而非free取消分配。
  8. 赞成智能指针而不是原始; Tnode*可以是std::shared_ptr<Tnode>,这样可以避免调用delete
  9. tree无需继承Tnode
  10. Tnode应该是struct,因为它只有公共成员且没有任何功能。
  11. 有意义的变量名称有助于理解(例如父亲的f简称?)
  12. 一般来说,类不应该有公共成员变量,要将类数据与公共访问者私有。
  13. 更喜欢在初始化列表中初始化类成员,而不是在构造函数体中进行赋值
  14. 保持一致;例如坚持NULL0,而不是两者(尽管使用C ++ 11编译器,绝对坚持nullptr
  15. 从成员函数参数中消除类成员变量的歧义;你在两种情况下使用root
  16. 关心对齐和格式化;有几个地方,对齐意味着你希望控制块比它更大。格式的一般状态给人一种立即的印象(在这种情况下非常准确),缺乏关注,应该让任何读者立即怀疑逻辑。
  17. 还有更多......

答案 2 :(得分:0)

你没有一个小错误,你有太多的错误。我建议您使用调试器获取IDE并逐步执行代码,以查看发生的情况是否符合您的预期。

例如,在Tnode *search中,您以递归方式调用搜索,但忘记使用返回的值:

//             search(temp->left,ch);
               return search(temp->left,ch);
//             ^^^^^^
//             search(temp->right,ch);
               return search(temp->left,ch);
//             ^^^^^^

另一个:在Tnode *getleft_right_most中,你可能想要这个:

    Tnode *m=temp->left;
//  while(temp->right)
//      temp=temp->right;
//      return temp;
    while(m->right)
        m=m->right;
        return m;

这是您的编译器可以帮助您的东西。使用-Wall(或启用所有警告),它会指向您创建变量m并忘记使用它。

Tnode *del中,有一个没有正文的if语句:

if(temp->left&&temp->right)
if(temp->right)

编译器将只接受第二个if语句并将其用作缺少的主体:

if(temp->left&&temp->right) {
    if(temp->right)
    { // ...
    }
}

Tnode *delroot中,您可能想要

return root;

而不是return d。您也不处理root同时具有leftright分支的情况。

依此类推,剩下的错误对你来说是一种练习。

我不想提到你换了选项2和3,但这很烦人。

最后一个提示:由于您创建了一个tree成员root成员,因此您不需要(也不应该)将root作为参数传递给成员职能。