64,654
社区成员
发帖
与我相关
我的任务
分享
#include<iostream>
using namespace std;
const int MaxLen=20;
bool flag=false;
class Node
{
public:
int key;
Node *LeftChild;
Node *RightChild;
Node():LeftChild(NULL),RightChild(NULL){}
};
class BiSoTree
{
private:
Node *Root;
int vernum;
void InOrder(Node *);
void Search_Inseart(Node *,int);
void Delete(Node *&t);
public:
BiSoTree():Root(NULL){}
void Search_Inseart1(int);
void InOrder();
};
void BiSoTree::Search_Inseart1(int key)
{
Search_Inseart(Root,key);
}
//本程序中不关心&Root、&p的值,只关心Root、p的值。
void BiSoTree::Search_Inseart(Node *p,int k) // 也可以不用传Root过去,直接在函数里使用Root,Node *p=Root;
{
Node *pre=NULL;
while(p!=NULL)
{
pre=p; // pre始终为p的父亲
if(k>p->key)
p=p->RightChild;
else if(k<p->key)
p=p->LeftChild;
else if(k==p->key)
{
Delete(p);
cout<<p<<endl; // 输出是0,可以证明结点已删除
InOrder(); // 中序遍历到55的右孩子时,输出不是0,竟然是一个地址?
cout<<endl;
return;
}
}
if(p==NULL) // p跳到根结点或者叶子结点
{
if(flag)
return;
else
{
p=new Node(); // p创建一个新的结点
p->LeftChild=NULL;
p->RightChild=NULL;
p->key=k;
if(pre==NULL)
Root=p;
else
{
if(pre->key<p->key)
pre->RightChild=p; // 让原本指向空的右孩子指向一个新的p结点
else
pre->LeftChild=p;
}
}
}
}
void BiSoTree::Delete(Node *&t) // 这个是指针的别名,如果传入的是&p,用2级指针**t的话,
*t->LeftChild为什么会报错
{
Node *q=t,*s;
if(t->LeftChild==NULL)
{
t=t->RightChild;
delete q;
}
else if(t->RightChild==NULL)
{
t=t->LeftChild;
delete q;
}
else
{
s=t->LeftChild;
while(s->RightChild)
{
q=s;
s=s->RightChild;
}
t->key=s->key;
if(q!=t)
q->RightChild=s->LeftChild;
else
q->LeftChild=s->LeftChild;
delete s;
}
}
void BiSoTree::InOrder()
{
InOrder(Root);
}
void BiSoTree::InOrder(Node *T)
{
if(T!=NULL)
{
InOrder(T->LeftChild);
cout<<T->key<<" ";
InOrder(T->RightChild);
}
}
int main()
{
BiSoTree b;
int t,n,array[MaxLen],n1,array1[MaxLen],i,j;
cin>>t;
while(t--)
{
cin>>n;
for(i=0;i<n;i++)
cin>>array[i];
cin>>n1;
for(i=0;i<n1;i++)
cin>>array1[i];
for(i=0;i<n;i++)
b.Search_Inseart1(array[i]);
b.InOrder();
cout<<endl;
flag=true;
for(i=0;i<n1;i++)
b.Search_Inseart1(array1[i]);
}
return 0;
}
Sample Input
1
6
22 33 55 66 11 44 // 建立一个二叉排序树
3 // 删除3个结点
66
22
77 // 如果结点不存在则不做改变
Sample Output
11 22 33 44 55 66
11 22 33 44 55
11 33 44 55
11 33 44 55
if(t->LeftChild==NULL)
{
t=t->RightChild;
delete q;
}
else if(t->RightChild==NULL)
{
t=t->LeftChild;
delete q;
}
好好看看你这段代码,t是个引用表示void BiSoTree::Search_Inseart(Node *p,int k)
中的p,这里的p是个形参,他的改变修改不了你的树本身的结构,然后你delete q, 这个被delete掉的节点就仍然存在于你的树结构中,遍历时访问到这个节点自然会崩溃。
干嘛要重置?不是只要修改孩子的值为0不就行了吗?而且delete的是另一个结点q,q的内容只是复制p而已,把q delete 对p和父节点没影响吧?[/quote]
else
{
s=t->LeftChild;
while(s->RightChild)
{
q=s;
s=s->RightChild;
}
t->key=s->key;
if(q!=t)
q->RightChild=s->LeftChild;
else
q->LeftChild=s->LeftChild;
delete s;
}