您的位置:首页 > 其它

二叉搜索树实现

2015-06-05 22:45 232 查看
这只是作为我学习的笔记

#ifndef BINARYTREE_H_
#define BINARYTREE_H_
#include<iostream>
typedef int Item;
struct Btreenode
{
Item data;
Btreenode *left,*right;
};
class BinaryTree
{
public:
Btreenode * BST;//树的根节点
BinaryTree(){BST=NULL;}
bool Insert(const Item & x);//合适的位置插入节点x
bool Delete(const Item & x);//删除并调整树
void create(const Item * x, int n);//创建n个树节点,调用insert
bool find(Btreenode & p, const Item & x)const;//查找等于x的树节点并赋给p
};
#endif // !BinaryTree_H_

#include"BinaryTree.h"

void BinaryTree::create(const Item * x, int n)
{
for(int i=0;i<=n-1;i++)
{
Insert(x[i]);
}
}
bool BinaryTree::Insert(const Item & x)//肯定是要放在合适的叶子节点位置
{
if(BST==NULL)//根指针
{
Btreenode * p=new Btreenode;
p->data=x;
p->left=p->right=0;
BST=p;
return true;
}
Btreenode *p=BST,*q=BST;
int f=0;
while(p!=NULL)//非递归查找叶子节点位置
{
if(p->data>x)
{q=p;f=1;p=p->left;}
else if(p->data<x)
{q=p;f=2;p=p->right;}
else
return false;   //如果插入相等的数返回false
}
if(p==NULL)
{
Btreenode * temp=new Btreenode;
temp->data=x;
temp->left=temp->right=NULL;//把叶子节点的后继孩子置为NULL指针
if(f==1)q->left=temp;
else if(f==2)q->right=temp;
return true;
}
else return false;
}

bool BinaryTree::find(Btreenode & p,const Item & x)const
{
if(BST==NULL)
return false;
else
{
Btreenode * temp=BST;
while(temp!=NULL)//非递归实现,递归实现
{
if(temp->data==x)
{
p=*temp;   //返回所指向的节点内容
return true;
}
else if(temp->data>x)
temp=temp->left;
else
temp=temp->right;
}
return false;
}
}

bool BinaryTree::Delete(const Item & x)
{
if(!BST)
return false;
Btreenode * s=NULL;
Btreenode * t= BST;
while(t!=NULL)   //定位 x的位置,其父节点
{
if(t->data==x)
break;
else if(t->data>x)
{s=t;t=t->left;}//s指向t的父节点
else
{s=t;t=t->right;}
}
if(t==NULL) return false;//不存在该节点,删不掉
if(t->left==NULL && t->right==NULL)//t是叶节点,可以直接删掉置父节点孩子为NULL
{
if(t==BST)  //若t是根节点,单独考虑 s=NULL
BST=NULL;
else if(t==s->left)
s->left=NULL;
else
s->right=NULL;
delete t;
}

else if(t->left==NULL || t->right==NULL)//左孩子或右孩子为空,把非空的后继节点支脉给其父节点s
{
if(t==BST)
{
if(t->left==NULL)BST=BST->right;
else BST=BST->left;
delete t;
}
else
{
if(t==s->left && t->left!=NULL)
s->left=t->left;
else if(t==s->left && t->right!=NULL)
s->left=t->right;
else if(t==s->right && t->left!=NULL)
s->right=t->left;
else if(t==s->right && t->right!=NULL)
s->right=t->right;
}
}
else if(t->left!=NULL && t->right!=NULL)//如果都非空
//法1:把左支脉给s节点相应缺失的孩子,右支脉放在t->left最大的位置(一直找右孩子,直至右孩子)
//法2:用t->left后续最大节点代替t
{
if(s->left==t)//t指向的是s的左孩子
s->left=t->left;
else
s->right=t->left;
Btreenode * q=t->left;
Btreenode * p=t;
while(q!=NULL)
{
p=q;q=q->right; //q是t->left最大的位置.p没有右孩子
}
p->right=t->right;
delete t;
}
return false;
}

#include<iostream>
#include"BinaryTree.h"
typedef BinaryTree T;

void InOrder(Btreenode * r)//二叉查找树排序
{
if(r!=NULL)
{
InOrder(r->left);
std::cout<<r->data<<" ";
InOrder(r->right);
}
return;
}

int  main()
{
using namespace std;
T mr;
int n = 11;
Item  a[]={66,80,3,10,88,98,15,77,25,65,35};
mr.create(a, n);
InOrder(mr.BST);
Btreenode p;
mr.find(p, 10);
cout<< p.data<<endl;
mr.Delete(65);
InOrder(mr.BST);

system("pause");
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: