二叉搜索树的增删查

来源:互联网 发布:如何代理淘宝网店 编辑:程序博客网 时间:2024/06/07 01:40

     今天把搜索二叉树的思路又理了一遍,把代码又从头到尾敲了一遍,各位看客就不要在意代码粗糙和内存溢出了,主要把插入和删除的过程理了一遍,其中比较复杂的地方就是搜索二叉树的删除,涉及了很多次的指针重新指向,比较容易晕。另外,对于二叉树,在上溯的时候要特别注意根节点这个特殊的临界状态(大部分情况把根节点的父结点指向空,也可以设一个head结点,使root和head的父结点相互指向)。最后注意null结点不能取左右孩子和父结点,这也是一个容易使程序崩的情况。代码如下:

//二叉搜索树的插入和删除struct SerachTree{int data;SerachTree *left_child;SerachTree *right_child;SerachTree *parent_node;};class Serach_Tree{public:Serach_Tree(){root=NULL;}//插入SerachTree* insert(int number){if(root==NULL){root=new SerachTree;root->data=number;root->left_child=NULL;root->right_child=NULL;root->parent_node=NULL;}else{SerachTree *tem_root=root;SerachTree *tem=NULL;while(tem_root!=NULL){tem=tem_root;if(number<tem_root->data)tem_root=tem_root->left_child;elsetem_root=tem_root->right_child;}SerachTree *child=new SerachTree;child->data=number;child->left_child=NULL;child->right_child=NULL;if(number<tem->data){tem->left_child=child;child->parent_node=tem;}else{tem->right_child=child;child->parent_node=tem;}}return root;}//最小值int minimum(SerachTree *root){if(root==NULL)return NULL;while(root->left_child!=NULL)root=root->left_child;return root->data;}//最大值int maximum(SerachTree *root){if(root==NULL)return NULL;while(root->right_child!=NULL)root=root->right_child;return root->data;}//查找指定的值,找到返回该值,找不到就返回空int search(SerachTree *root,int num){if(root==NULL)return NULL;if(root->data==num){return num;}else{if(num<root->data)search(root->left_child,num);elsesearch(root->right_child,num);}return num;}//找一个结点的前驱结点int front_node(int num){if(search(root,num)==NULL){cout<<"no that node!"<<endl;return NULL;}else{SerachTree *tem=root;//肯定能找到while(true){if(tem->data>num)tem=tem->left_child;else if(tem->data<num)tem=tem->right_child;elsebreak;}//找前驱结点if(tem->left_child!=NULL)return maximum(tem->left_child);SerachTree *tem_parent=tem->parent_node;while(tem_parent!=NULL&&tem==tem_parent->left_child){tem=tem_parent;tem_parent=tem_parent->parent_node;}if(tem_parent==NULL)return NULL;elsereturn tem_parent->data;}}//找后继结点int back_node(int num){if(search(root,num)==NULL){cout<<"no node"<<endl;return NULL;}else{SerachTree *tem=root;//肯定能找到while(true){if(tem->data>num)tem=tem->left_child;else if(tem->data<num)tem=tem->right_child;elsebreak;}if(tem->right_child!=NULL)return minimum(tem->right_child);SerachTree *tem_root=tem->parent_node;while(tem_root!=NULL&&tem==tem_root->right_child){tem=tem_root;tem_root=tem_root->parent_node;}if(tem_root==NULL)return NULL;elsereturn tem_root->data;}}//删除结点void delete_node(int num){if(search(root,num)==NULL){cout<<"delete error!"<<endl;return;}else{SerachTree *tem_root=root;while(true){if(tem_root->data<num){tem_root=tem_root->right_child;}else if(tem_root->data>num){tem_root=tem_root->left_child;}elsebreak;}//tem是待删除的结点if(tem_root->left_child==NULL) //没有左孩子,直接右孩子顶上_delete_node(tem_root,tem_root->right_child);else if(tem_root->right_child==NULL) //没有右孩子,直接左孩子顶上_delete_node(tem_root,tem_root->left_child);else  //左右孩子不为空{//先找到右子数最小的结点SerachTree *tem=tem_root->right_child;while(tem->left_child!=NULL){tem=tem->left_child;}if(tem->parent_node!=tem_root)  //找到的点不是与待删除的点直接相连{_delete_node(tem,tem->right_child);tem->right_child=tem_root->right_child;tem->right_child->parent_node=tem;}_delete_node(tem_root,tem);tem->left_child=tem_root->left_child;tem->left_child->parent_node=tem;}cout<<"delete success"<<endl;}}private:void _delete_node(SerachTree *root1,SerachTree *root2){if(root1->parent_node==NULL)  //当前结点是根节点{root=root2;}else if(root1==root1->parent_node->left_child) //当前结点是父结点的左孩子{root1->parent_node->left_child=root2;}else if(root1=root1->parent_node->right_child){root1->parent_node->right_child=root2;}if(root2!=NULL)root2->parent_node=root1->parent_node;}public:SerachTree *root;};int main(){Serach_Tree s;int choose;while(true){cout<<"1:插入  2:max  3:min  4:serach  5:delete  0:exit"<<endl;cin>>choose;if(choose==1){int num;cout<<"insert num:";cin>>num;s.insert(num);}if(choose==2){if(s.maximum(s.root)!=NULL)cout<<s.maximum(s.root)<<endl;elsecout<<"no node"<<endl;}if(choose==3){if(s.minimum(s.root)!=NULL)cout<<s.minimum(s.root)<<endl;elsecout<<"no node"<<endl;}if(choose==4){int num=0;cout<<"search num:";cin>>num;if(s.search(s.root,num)!=NULL)cout<<s.search(s.root,num)<<endl;elsecout<<"no node"<<endl;}if(choose==5){int num=0;cout<<"delete num:";cin>>num;s.delete_node(num);}if(choose==0)break;}return 0;} 
    测试基本没有问题,但不排除特殊案例没考虑到的情况。欢迎指正。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 手机微信红包密码忘了怎么办 qq账号忘了怎么办什么也没绑定 手机银行转账名字对卡号错了怎么办 手机夸行转账卡号输入错了怎么办 移动开通了20元流量卡怎么办? 联通手机充值卡网上充值话费怎么办 提现金额和实际到账不一样怎么办 二冲踏板冷车加油熄火怎么办? qq被盗绑定了别人的银行卡怎么办 如何更改微信支付密码忘记了怎么办 微信钱包没绑银行卡忘记密码怎么办 微信密码忘记了也没绑银行卡怎么办 微信支付密码忘记了没银行卡怎么办 想找回原来的k歌忘了密码怎么办 手机微信钱包支付密码忘了怎么办 微信支付账户被注销了怎么办 微信钱包密码忘了怎么办没绑银行卡 微信钱包密码忘了怎么办不用银行卡 企业网银密码输入三次错误怎么办 微信密码不知道手机也停用了怎么办 手机停用微信密码不记得了怎么办 农商银行登入密码忘记了怎么办 苹果手机忘记四位数解锁密码怎么办 银行卡用支付宝支付限额了怎么办 用银行卡号找回微信被盗密码怎么办 微信钱包密码错误被锁定怎么办 本人没玩财付通结果被扣了钱怎么办 我的银行卡给支付宝充不了钱怎么办 支付宝话费充错了怎么办啊 已充值成功送朋友话费不能送怎么办 微信绑定银行卡被盗刷q币怎么办 微信红包过了24小时没退回怎么办 微信6.67版本红包发错了怎么办 苹果6s还原后激活出错怎么办 q币充给了不存在的账号怎么办 怎么办微信的钱换成淘宝币 学信网密码密保手机号都忘了怎么办 第五人格玩游戏时总是闪退怎么办 qq安全中心密保手机换了怎么办 微信冻结账号绑定了银行卡怎么办 扣扣红包密码是支付密码忘了怎么办