二叉搜索树的增删查
来源:互联网 发布:如何代理淘宝网店 编辑:程序博客网 时间: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
- 二叉搜索树的增删查改
- 搜索二叉树的增删查改
- 二叉搜索树的增删查
- 二叉搜索树—增删查
- 二叉搜索树的增删查(递归与非递归)实现
- 二叉树的增删改查
- 二叉搜索树Java实现(增删改查遍历等操作)
- 实现二叉树增删改查
- 二叉树查找增删改查
- 二叉树的增删
- 二叉树排序及二叉树节点的增删改查(java实现)
- 二叉搜索树 并查集
- 分布式搜索elasticsearch 索引文档的增删改查 入门
- 分布式搜索elasticsearch 索引文档的增删改查 入门
- 分布式搜索elasticsearch 索引文档的增删改查 入门
- 算法习题1:二叉树实现增删改查
- 二叉树的定义,节点的增删改查以及父节点、子节点的各种操作。
- zTree树节点的增删改查。
- 关于JCAPTCHA源码的重新编译
- Android自定义控件:动画类(十一)----联合动画的XML实现与使用示例
- activiti 为什么需要采用乐观锁?
- Volley+Gson
- CCF计算机软件能力认证模拟试题-最大的矩形(Java参考答案学习记录)
- 二叉搜索树的增删查
- iOS开发:相册或相机调用
- 进程和线程的区别
- iOS 制作自已的framework
- 《OpenCV3编程入门》目录
- 架构师培训入门知识体系树--转载
- DuKBitmapImages 图片压缩处理技术
- RunTime知识整理
- JAVA的反射机制