二叉查找树C++实现

二叉排序树(Binary Sort Tree)又称二叉查找树,它的特点是:

(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;

(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;

 (3)左、右子树也分别为二叉排序树;

 

但你看到定义可能会奇怪,如果出现相等元素咋整啊.这里我们就假设右子树的结点值大于或等于根结点得了.

在这里我们实现二叉树的如下简单功能:(二叉树结点类为BTreeNode<T>)

void Insert(T val); //往二叉树中插入数据,自然要保证插入数据后仍然是二叉树

BTreeNode<T>* Search(T val); //查找值为val的结点

BTreeNode<T>* SearchMinVal(); //查找值最小的结点

BTreeNode<T>* SearchMaxVal();//查找值最大的结点

void Delete(T val); //删除任意节点

 

 

1.先定义一个二叉树的结点类

template<class T>

class BTreeNode{

public:

T val;

BTreeNode<T>* left; //指向左孩子的指针

BTreeNode<T>* right;

BTreeNode<T>* parent; //指向父结点的指针

BTreeNode(T tVal){

val = tVal;

left = right = parent = NULL;

}

bool operator==(BTreeNode<T>* bt){ //重载操作符比较两结点是否相等

return bt.val == val ? true: false;

}

 

};

 

2.定义二叉查找树的类BSortTree

 

#include "BTreeNode.h"

template<class T>

class BSortTree{

private:

BTreeNode<T>* root; //根结点指针

int size; //树中元素总个数

 

public:

BSortTree(void){

root = NULL;

size = 0;

}

~BSortTree(void){}

int Size() { return size;}

 

void Insert(T val){ //插入结点元素

if(root == NULL){ //树为空

BTreeNode<T>* pNode = new BTreeNode<T>(val);

root = pNode;

size++;

return;

}

InsertTree(root, val); //树不为空时插入元素

}

BTreeNode<T>* Search(T val){ //查找结点

return SearchTree(root, val);

}

BTreeNode<T>* SearchMinVal(){ //查找最小值元素

SearchTreeMinVal(root);

}

BTreeNode<T>* SearchMaxVal(){ //查找最大值元素

SearchTreeMaxVal(root);

}

void Delete(T val){ //删除任意结点

DeleteTreeNode(root, val);

}

 

private:

 

//删除节点分4种情况

//1.如果是叶子,则直接删除

//2.如果只有左子树,则删除结点后左子树上移即可

//3.如果只有右子树,则删除结点后右子树上移即可

//4.如果左右子树都有,则查找要删除结点(p)的左子树中的最大结点(m),把m的结点值赋给p,然后删除m.

void DeleteTreeNode(BTreeNode<T>* pRoot, T val){ //删除结点

BTreeNode<T>* node = Search(val); //要删除的结点

if(node == NULL) //要删除的结点不存在

return;

//1.被删结点是叶子,直接删

if(node->left==NULL && node->right==NULL){

if(node->parent == NULL){ //只有一个结点的树

size = 0;

root = NULL;

}

else if(node->parent->left == node)//被删结点是左孩子

node->parent->left = NULL;

else //结点是右孩子

node->parent->right = NULL;

delete node;

size--;

return;

}

//2.被删结点只有左子树

if(node->left !=NULL && node->right==NULL){

node->left->parent = node->parent;

if(node->parent == NULL) //被删结点是根结点

root = node->left;

else if(node->parent->left == node)//被删结点是左孩子

node->parent->left = node->left;

else //被删结点是右孩子

node->parent->right = node->right;

delete node;

size--;

return;

 

}

//3.被删结点只有右子树

if(node->right !=NULL && node->left==NULL){

node->right->parent = node->parent;

if(node->parent == NULL) //被删结点是根结点

root = node->right;

else if(node->parent->left == node)//被删结点是左孩子

node->parent->left = node->left;

else //被删结点是右孩子

node->parent->right = node->right;

delete node;

size--;

return;

 

}

//4.被删结点左右孩子都有

if(node->left !=NULL && node->right != NULL){

BTreeNode<T>* replaceNode = SearchTreeMinVal(node->right); //也可以替换成查找左子树最大值

node->val = replaceNode->val;

DeleteTreeNode(root, replaceNode->val);

}

}

 

 

void InsertTree(BTreeNode<T>* pRoot,T val)

{

BTreeNode<T>* pNode = new BTreeNode<T>(val);

if(pRoot->left == NULL && val < pRoot->val){

pRoot->left = pNode;

pNode->parent = pRoot;

size++;

return;

}

if(pRoot->right == NULL && val >= pRoot->val){

pRoot->right = pNode;

pNode->parent = pRoot;

size++;

return;

}

if(val < pRoot->val)

InsertTree(pRoot->left,val);

else

InsertTree(pRoot->right,val);

}

 

BTreeNode<T>* SearchTree(BTreeNode<T>* pRoot,T val){

if(pRoot == NULL)

return NULL;

else if(val == pRoot->val)

return pRoot;

else if(val < pRoot->val)

return SearchTree(pRoot->left,val);

else

return SearchTree(pRoot->right, val);

}

BTreeNode<T>* SearchTreeMinVal(BTreeNode<T>* pRoot){

if(pRoot==NULL)

return NULL;

else if(pRoot->left == NULL)

return pRoot;

else

return SearchTreeMinVal(pRoot->left);

}

 

BTreeNode<T>* SearchTreeMaxVal(BTreeNode<T>* pRoot){

if(pRoot==NULL)

return NULL;

else if(pRoot->right == NULL)

return pRoot;

else

return SearchTreeMinVal(pRoot->right);

} 

};

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值