普通二叉排序树
来源:互联网 发布:网络平台计划书 编辑:程序博客网 时间:2024/05/17 03:54
1.二叉查找树(BST,Binary Search Tree)
注意和堆排序中的堆区分开。
参考我的博客,常见内排序算法中的堆排序。
定义:1)如果左子树不空,那么左子树的所有节点均小于根节点
2)如果右子树不空,那么右子树的所有节点均大于根节点
3)左右子树也都是BST
1.1二叉查找树的查找
如何在二叉查找树上查找某个为key的节点?
首先比较key和根节点,如果其大小等于根节点,退出;
如果小于根节点,递归搜索左子树;
如果大于根节点,递归搜索右子树。
1.2如何在二叉查找树中插入一个节点
1)如果树上已经有关键字相等的节点,不插入
2)否则,要插入的节点,必定是叶子节点,利用1.1中的查找算法,查找不成功的最后一
个节点必然是要插入节点的父亲节点。然后判定要插入节点是该父亲节点的左孩子还是右孩子。
1.3如何在二叉查找树上删除一个节点
1)找到该节点d
2)删除该节点d并修改相应指针。
我看严蔚敏老师那本树上搞的甚是复杂,我老婆比较厉害,帮我总结了个简单的,先看性质,再看图说话。
性质:对于二叉排序树上的任意一个节点,如果它有子树,则有如下性质, 其左子树的最右侧子树的值是小于它的最大值,
其右子树的最左侧子树的值是大于它的最小值,这个小于它的最大值和大于它的最小值都可以替代删除节点做根。我取左子树的最右侧
子树。
删除节点d,共有四种情况:
1)d的左右子树均NULL,删除d,把d父亲节点的相应指针置NULL。
提醒:注意图片2中的特殊情况,d没有父亲,删除d后,整个树为NULL。
图片1 图片2
2)d的左子树不空,右子树NULL,删除d,把d的左子树链接到d的父亲节点。
提醒:图片4中的特殊情况,d无父亲节点,删除d后,整个树的根需要变动,否则我们将失去树根。
图片3 图片4
3)d的左子树NULL,右子树不空,删除d,把d的右子树链接到d的父亲节点
提醒:图片6中的特殊情况,d无父亲节点,删除d后,整个树根要变动,否则我们将永远失去树根。
图片5 图片6
4)d有左子树和右子树,d转左子树,然后向右直到最右r,修改d的关键字为r的关键字,删除r,将r的左子树链接到r的父亲(r不可能有
右子树)
图片7
1.4二叉查找树的宽度优先遍历
写这个功能,主要是为了测试上面1.1,1.2,1.3几个功能的实现是否正确,可以自己造几个
数据插入,然后调用我写的宽度优先遍历打印出来和自己手工画的做比较。
用了STL中的list做队列,没有自己写队列。
1.5二叉查找树的中序遍历
中序遍历的结果是一个有序序列,这也可以作为一种排序方法。
完整代码(没有实现遍历并删除所有节点,道理都一样,懒得写了,你可自己写):
#include <iostream>#include <list>using namespace std;struct BstTreeNode{ int key; struct BstTreeNode *left; struct BstTreeNode *right;};struct BstTreeNode *parent = NULL;struct BstTreeNode *search_result = NULL;//BST search bool bst_search(struct BstTreeNode *root, int key) { if(root == NULL) { return false; } if(key == root->key) { search_result = root; return true; } if(key < root->key) { parent = root; return bst_search(root->left, key); } if(key > root->key) { parent = root; return bst_search(root->right, key); }}//BST addbool bst_add(struct BstTreeNode *root, int key) { parent = NULL; search_result = NULL; if(bst_search(root, key)) { return false; //already have this node } else if(parent != NULL){ struct BstTreeNode *node = new BstTreeNode; node->key = key; node->left = NULL; node->right = NULL; if(key < parent->key) parent->left = node; else parent->right = node; return true; } return false;}//BST Delete//Use C++ reference to record the root of the tree//bool bst_delete(struct BstTreeNode * &root, int key) { parent = NULL; search_result = NULL; if(!bst_search(root, key)) { return false; //have nod this node } if(search_result->left == NULL && search_result->right == NULL) { if(parent != NULL) { if(search_result == parent->left) parent->left = NULL; else if(search_result == parent->right) parent->right = NULL; } else { root = NULL; } delete search_result; } else if(search_result->left != NULL && search_result->right == NULL) { if(parent != NULL) { if(search_result == parent->left) parent->left = search_result->left; else if(search_result == parent->right) parent->right = search_result->left; } else { root = search_result->left; } delete search_result; } else if(search_result->left == NULL && search_result->right != NULL) { if(parent != NULL) { if(search_result == parent->left) parent->left = search_result->right; else if(search_result == parent->right) parent->right = search_result->right; } else { root = search_result->right; } delete search_result; } else { struct BstTreeNode *replace = search_result->left; struct BstTreeNode *replace_parent= replace; while(replace->right) { replace_parent = replace; replace = replace->right; } search_result->key = replace->key; if(replace == replace_parent->left) replace_parent->left = replace->left; else if(replace == replace_parent->right) replace_parent->right = replace->left; delete replace; } return true;} //BST traverse, width first search//Use STL list as a list structure for ease, I do not implement a list //Of course, you can implement a list yourself//void bst_traverse_wfs(struct BstTreeNode *root) { list<BstTreeNode *> my_list; if(root != NULL) { my_list.push_back(root); } else { return; } while(!my_list.empty()) { struct BstTreeNode *tmp = my_list.front(); if(tmp->left) my_list.push_back(tmp->left); if(tmp->right) my_list.push_back(tmp->right); cout<<tmp->key<<" "; my_list.pop_front(); } cout<<endl;} //BST traverse, depth first search, inorder//Inorder recursive implementvoid bst_traverse_dfs_inorder(struct BstTreeNode *root) { if(root == NULL) return; bst_traverse_dfs_inorder(root->left); cout<<root->key<<" "; bst_traverse_dfs_inorder(root->right);}int main() { /* 7 * 3 9 * 2 5 10 * 1 4 6 * */ struct BstTreeNode *root = new BstTreeNode; root->key = 7; root->left = NULL; root->right = NULL; //construct & print bst_add(root,3); bst_add(root,9); bst_add(root,2); bst_add(root,5); bst_add(root,10); bst_add(root,1); bst_add(root,4); bst_add(root,6); bst_traverse_wfs(root); bst_traverse_dfs_inorder(root); cout<<endl; cout<<"************************"<<endl; //delete & print bst_delete(root, 7); bst_traverse_wfs(root); bst_traverse_dfs_inorder(root); cout<<endl; cout<<"************************"<<endl; return 0;}
- 普通二叉排序树
- 二叉排序树
- 二叉排序树
- 二叉排序树
- 二叉排序树
- 二叉排序树
- 二叉排序树
- 二叉排序树
- 二叉排序树
- 二叉排序树
- 二叉排序树
- 二叉排序树
- 二叉排序树
- 二叉排序树
- 二叉排序树
- 二叉排序树
- 二叉排序树
- 二叉排序树
- mplayer从模式翻译文档
- Android开发基础:Android源代码结构解析
- 各种卡类说明
- 基于WSP/WTP的MMS传输——MMS 传输
- 谁说美女不编程
- 普通二叉排序树
- 关于sql条件语句where id in (@参数)执行报错问题(转换成数据类型 int 时失败)(
- 基于WSP/WTP的MMS传输(2)——MMS PDU结构
- 添加的SWT控件没有显示出来
- Mafire1 S50与S70区别
- 有用的MeeGo链接
- 14443-A 与14443-B区别
- ArcGIS 10.0 地图数据与图层数据打包(用好此功能受益不浅)
- linux 常用命令及技巧