有谁知道这个程序出了什么问题?
Does any one know what's wrong in this program?
这个程序应该对二进制树节点进行插入、删除。问题是,当我在删除后显示树元素时,程序显示错误。请帮助我的程序中出现的错误。
#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.INSERTn2.DELETE NUMBERn3.DISPLAYn4.EXITnEnter 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);
}
}
}
没有<iostream.h>
。你必须使用<iostream>
。并将<stdlib.h>
替换为<cstdlib>
。
此外,您使用的是cout
和cin
,它们都是在名称空间std
中定义的。因此,在文件开头使用std::cout
或using namespace std;
,尽管我不建议使用后者。
因此,将前三行替换为以下行,您的程序将编译:
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
然而,如果您在编译代码时没有问题,并且您的错误完全不同,那么您应该在问题中添加具体的错误消息。
这有很多错误:
#include <iostream.h>
需要是#include <iostream>
main()
需要是int main()
tree::del
需要返回一个值- CCD_ 15中的开关情况与开关上方的消息输出不匹配
- 如果控制进入最后一个CCD_ 17块,则CCD_
- 由于
Tnode
是使用new
分配的,因此应该使用delete
而不是free
来解除分配 - 偏爱聪明的指针而非原始指针;
Tnode*
可以是std::shared_ptr<Tnode>
,这样可以避免调用delete
tree
不需要从Tnode
继承Tnode
应该是struct
,因为它只有公共成员而没有函数- 有意义的变量名有助于理解(例如
f
是父亲的缩写吗?) - 一般来说,类不应该有公共成员变量,使用公共访问器使类数据私有
- 更喜欢在初始化列表中初始化类成员,而不是通过构造函数主体中的赋值
- 保持一致;例如,坚持使用
NULL
或0
中的任何一个,而不是两者都使用(尽管使用C++11编译器,但一定要坚持使用nullptr
) - 从成员函数参数中消除类成员变量的歧义;两种情况都使用
root
- 注意对齐和格式设置;在一些地方,对齐意味着你希望控制块比实际情况更大。格式化的总体状态会给人一种缺乏小心的直接印象(在这种情况下非常准确),并会让任何读者立即对逻辑产生怀疑
可能还有更多。。。
您没有一个小错误,您有太多错误。我建议您获得一个带有调试器的IDE,并逐步查看代码,看看发生的事情是否符合您的预期。
例如,在Tnode *search
中,您递归调用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;
而不是CCD_ 41。您还没有处理根同时具有left
和right
分支的情况。
等等,剩下的bug对你来说是一个练习。
我不想提及你交换了选项2和3,但这很烦人。
最后一个提示:由于创建了一个具有root
成员的tree
类,因此不需要(也不应该)将root
作为参数传递给成员函数。
相关文章:
- 警告处理为错误这里有什么问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 当我尝试添加 2 个大字符串时,我无法弄清楚出了什么问题
- 违反const正确性:我应该现实地期待什么问题
- 这个带有模板<类 Vector 的C++代码片段有什么问题>
- 我的逻辑反转字符串中的元音有什么问题?
- 需要以下代码的帮助,下面的代码有什么问题
- 常量公共成员有什么问题?
- 以下代码中的函数模板有什么问题?
- 这个返回元素位置的基于循环的函数有什么问题?
- creat_list2功能有什么问题?
- 格式说明符C++有什么问题
- 任何人都可以告诉我我的 C++ 代码出了什么问题?
- 从 argv[1] 转换为字符 * 字符串后有什么问题?
- 我的堆栈和库存清单程序的结构有什么问题?
- 此工厂功能有什么问题?
- 以下 C++ 代码有什么问题?
- 数组为此合并排序函数提供了正确的输出,但向量给出了不正确的输出.出了什么问题?
- reinterpret_cast,只读访问,简单的可复制类型,会出什么问题?
- 它解决了什么问题,对于非真空初始化,生命周期在初始化之前就开始了