入门二叉搜索树的世界
来源:互联网 发布:js收藏地址兼容谷歌 编辑:程序博客网 时间:2024/05/16 06:45
入门二叉搜索树的世界
1. 二叉搜索树的概念
二叉搜索树,二叉查找树,二叉排序树说的都是一个概念。这篇博文中我们称其为二叉搜索树。二叉搜索树指的是一棵空树,或者具有下列性质的二叉树:
1)弱左字数不空,则左子树上所有节点的值均小于根节点的值;
2)若右子树不空,则右子树上所有节点的值均大于根节点的值;
3)左、右子树也分别为二叉搜索树;
2. 二叉搜索树的程序实现
#include <iostream>using namespace std;struct node{ int data; node *left; node *right;};node *root=NULL;node * insert(node *currentNode, int key) //插入节点函数,currentNode是当前节点,key是需要插入的值{ if(currentNode==NULL) //如果当前节点为空,那么要么是叶子,要么是空树的情况 { currentNode=new node; //申请一个节点空间 currentNode->data=key; currentNode->left=currentNode->right=NULL; //其子代指向空 if(root==NULL) //如果根节点为空,那么就是一个空树插入数据的情况 root=currentNode; //那么就直接把该节点作为根节点即可 } else { if(key<currentNode->data) //需要插入的值比节点小 currentNode->left=insert(currentNode->left, key); else //需要插入的值比节点大 currentNode->right=insert(currentNode->right, key); } return currentNode;}void print(node *currentNode) //中序遍历,输出的是递增序列{ if(currentNode!=NULL) { if(currentNode->left!=NULL) print(currentNode->left); cout<<currentNode->data<<' '; //中序遍历 if(currentNode->right!=NULL) print(currentNode->right); }}node * search(node *currentNode, int x) //查找元素,currentNode是当前节点,不能是root,x是需要查找的值{ node *result=NULL; if(currentNode!=NULL) { if(currentNode->data==x) result=currentNode; else if(x<currentNode->data) result=search(currentNode->left, x); else result=search(currentNode->right, x); } return result;}node * findParent(node *currentNode, int x){ node *result=NULL; if(currentNode!=NULL) { if(x<currentNode->data && currentNode->left!=NULL) //一旦进入if,就意味中需要找的父节点一定在根节点的左子树中 { if(x==currentNode->left->data) result=currentNode; else { result=findParent(currentNode->left, x); //继续寻找左子树 if(result==NULL) result=findParent(currentNode->right, x); //如果左子树没有,则寻找右子树 } } if(x>currentNode->data && currentNode->right!=NULL) //一旦进入if,就意味中需要找的父节点一定在根节点的右子树中 { if(x==currentNode->right->data) result=currentNode; else { result=findParent(currentNode->left, x); //继续寻找左子树 if(result==NULL) result=findParent(currentNode->right, x); //如果左子树没有,则寻找右子树 } } } return result;}void deleteNode(int x){ node *parent=findParent(root, x); node *dNode=search(root, x); if(dNode==NULL) { cout<<"Not Found!"<<endl; return; } if(dNode->left==NULL && dNode->right==NULL) //需要删除的节点是叶子节点 { if(parent==NULL) root=NULL; else { if(dNode==parent->left) parent->left=NULL; //删除节点直接令它为空,不像链表中就比较复杂 else parent->right=NULL; } } else if(dNode->left==NULL) //需要删除的节点只有左子树 { if(parent==NULL) root=NULL; else { if(dNode==parent->left) parent->left=NULL; else parent->right=NULL; } } else if(dNode->right==NULL) //需要删除的节点只有右子树 { if(parent==NULL) root=NULL; else { if(dNode==parent->left) parent->left=NULL; else parent->right=NULL; } } else //如果删除节点左子树右子树都有。 //首先,找到删除节点的直接后继节点和后继节点的父节点; //然后,让后继节点替换掉删除节点,注意这里要先把删除节点的左右子树复制给后继节点的子树,再把删除节点的父节点作为后继节点的父节点 //最后,在把后继节点的父节点的左子树(即后继节点原来的位置)删除,即可。 { node *newNode=dNode->right; node *newNodeParent=NULL; while(newNode->left!=NULL) //找到删除节点的直接后继节点,也就是删除节点的右子树中最左的那个 { newNodeParent=newNode; newNode=newNode->left; } if(newNode!=dNode->left) newNode->left=dNode->left; if(newNode!=dNode->right) newNode->right=dNode->right; if(parent==NULL) root=newNode; else { if(dNode==parent->left) parent->left=newNode; else parent->right=newNode; } if(newNodeParent!=NULL) newNodeParent->left=NULL; }}int main(){ int dataArray[12]={15,6,18,3,7,17,20,2,4,13,9,21}; int length=12; //新建一个二叉搜索树 for(int i=0; i<length; i++) //构建二叉搜索树是一个不断插入节点的过程 { insert(root, dataArray[i]); } //打印二叉搜索树 中序遍历 print(root); cout<<endl; //查找元素 node *result=search(root, 15); if(result!=NULL) cout<<"Found!"<<endl; else cout<<"None!"<<endl; //找到一个值的父节点 result=findParent(root, 4); //这儿若是根节点,则返回空,否则都是可以找到的。数组的第一个元素就是根节点 if(result!=NULL) cout<<"Found! "<<result->data<<endl; //可以输出根节点 else cout<<"None!"<<endl; //删除节点 deleteNode(4); //删除叶子节点 print(root); cout<<endl; deleteNode(21); //删除只有右子树节点 print(root); cout<<endl; deleteNode(13); //删除只有左子树节点 print(root); cout<<endl; deleteNode(15); //6,18,15//删除左右子树都有的节点 print(root); cout<<endl; return 0;}
删除节点是其中最为复杂的,而在删除中最为复杂的就是删除左右子树都有的节点。具体的做法在注释中已经详细说明,发现网上大神的一副图来展示这个删除的过程,说的特别好,粘贴过来~~嘻嘻。
参考链接:
http://www.cnblogs.com/aiyelinglong/archive/2012/03/27/2419972.html
http://blog.csdn.net/lvsi12/article/details/8232052
0 0
- 入门二叉搜索树的世界
- 入门二叉树的世界
- 入门二叉平衡树的世界
- [HNOI2002]营业额统计 二叉搜索树的简单入门 splay
- 入门B-树的世界
- 二叉搜索树的插入,搜索,删除
- 二叉搜索树的实现
- 二叉搜索树的建立
- 搜索二叉树的初始化
- 二叉搜索树的插入
- 搜索二叉树的应用
- 二叉搜索树的实现
- 二叉搜索树的实现
- 二叉搜索树的实现
- 搜索二叉树的操作
- 二叉搜索树的遍历
- 搜索二叉树的实现
- 二叉搜索树的实现
- 矩形类2
- 清除浏览器的缓存
- libjingle thread的使用
- R语言书籍的学习路线图
- linux 安装 jdk
- 入门二叉搜索树的世界
- lua实现的循环背景
- ant压缩和解压文件
- 润乾集算报表提升性能之并行取数
- wav文件提取出pcm数据
- IE9版本以下ajax 跨域问题解决
- 解压
- 小白程序员初探APP推广
- VS2010调试快捷键