二叉排序树的创建 、删除操作
【问题描述】
请根据输入的数据创建一棵二叉排序树。然后执行相应操作。
1 删除某一值为x的结点
2 求指定结点y在二叉排序树中的层数
【输入形式】
结点数据,以0代表结束输入。
待删除的x,待求层数的y
【输出形式】
删除后的二叉排序树的中序遍历结果
y所在的层数
【样例输入】
29 39 15 25 28 10 11 2 0
10
11
【样例输出】
2 11 15 25 28 29 39
4
【样例说明】
若待删除的结点包含左右子树,则以其左子树的最右结点代替它。
#include <iostream>
#include<bits/stdc++.h>
#define MAX 100
using namespace std;
/*这样定义在编译时会报错
struct BSTnode
{
int data;
BSTnode *Rchild,*Lchild;
}*BSTree;
错误如下:
error: variable or field 'InsertBST' declared void|
error: 'bst' was not declared in this scope|
error: expected primary-expression before 'int'|
*/
//定义二叉树(以后推荐使用这种定义方法,减少编译器识别时发生出乎意外的error)
typedef struct node
{
int data;
node *Rchild,*Lchild;
}*BSTree,BSTnode;//这里我目前理解为 *BTSree是一个指针,因为指针可以移动,所以可以代表这棵二叉树 、BSTnode表示的只是一个结构体单元,只能代表这棵树的一部分
/*使用指针传递,由于BSTree本身就是一个指针所以,这里就会变成使用指针的指针,在调用函数是还需要使用&,代码看起来就不是很明了
1.在参数框里的 *bst 表示的是定义一个指针的指针
2.在函数体里的*bst表示指针的指针取值,即是表示的是二叉树的指针(指针的指针--->指针)
void InsertBST(BSTree *bst,int data)
{
BSTree t;
if(*bst==NULL)
{
t=(BSTree)malloc(sizeof(BSTnode));
t->data=data;
t->Rchild=NULL;
t->Lchild=NULL;
*bst=t;
}
else if(data>(*bst)->data)
{
InsertBST(&((*bst)->Rchild),data);
}
else if(data<(*bst)->data)
{
InsertBST(&((*bst)->Lchild),data);
}
}*/
//使用引用传递
void InsertBST(BSTree &bst,int data)
{
BSTree t;
if(bst==NULL)
{
t=(BSTree)malloc(sizeof(BSTnode));
t->data=data;
t->Rchild=NULL;
t->Lchild=NULL;
bst=t;
}
else if(data<bst->data)
{
InsertBST(bst->Lchild,data);
}
else if(data>bst->data)
{
InsertBST(bst->Rchild,data);
}
}
void CreatBST(BSTree *bst)
{
int data;
*bst=NULL;
cin>>data;
while(data!=0)
{
InsertBST(*bst,data);//关于这个地方为什么bst需要带指针我还是迷惑的
cin>>data;
}
}
BSTnode *DelBST(BSTree bst,int data)
{
BSTnode *p,*f,*s,*q;
p=bst;f=NULL;
while(p)
{
if(p->data==data) break;
f=p;
if(data>p->data)
{
p=p->Rchild;
}
else
{
p=p->Lchild;
}
}
if(p==NULL) return bst;
if(p->Lchild==NULL)
{
if(f==NULL) bst=p->Rchild;
else if(f->Lchild=p)
{
f->Lchild=p->Rchild;
}
else
{
f->Rchild=p->Rchild;
}
free(p);//在树中短出来的结构单元需要free释放掉
}
else
{
q=p;s=p->Lchild;
while(s->Rchild)
{
q=s;
s=s->Rchild;
}
if(q==p) q->Lchild=s->Lchild;
else q->Rchild=s->Lchild;
p->data=s->data;
free(s);
}
return bst;
}
void Inder(BSTree root)
{
if(root)
{
Inder(root->Lchild);
cout<<root->data<<" ";
Inder(root->Rchild);
}
}
void DeepNum(BSTree bst,int y)
{
int num=1;
while(bst)
{
if(bst->data==y)
{
cout<<num<<endl;
break;
}
if(bst->data>y)
{
num+=1;
bst=bst->Lchild;
}
else
{
num+=1;
bst=bst->Rchild;
}
}
}
int main()
{
BSTree bst;
int deldata;//需要删掉的数据
int y;//需要求节点层数的data
CreatBST(&bst);
cin>>deldata;
bst=DelBST(bst,deldata);
Inder(bst);
cout<<endl;
cin>>y;
DeepNum(bst,y);
return 0;
}
收获提炼:
1.结构体定义的方法不同,有时候编译的时候就会带来不一样的效果
2.函数参数传递的问题:
①值传递
void swap(int x,int y)
{
int tmp;
tmp=x;
x=y;
y=tmp;
}
调用时:swap(a,b);
②地址传递
void swap(int *x,int *y)
{
int tmp;
tmp=*x;
*x=*y;
*y=tmp;
}
swap(&a,&b);
③引用传递
void swap(int &x,int &y)
{
int tmp;
tmp=x;
x=y;
y=tmp;
}
swap(a,b);
版权声明:本文为qq_45774885原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。