二叉搜索树—增删查
来源:互联网 发布:警察查封淘宝假章 编辑:程序博客网 时间:2024/06/14 11:57
性质
-每个节点的key值各不相同
-左子树上所有节点的key值小于根结点
-右子树上的所有节点key值大于根结点
-左右子树都是二叉搜索树
Insert插入
bool Insert(const K& key)//非递归插入 { if (_root == NULL) { _root = new Node (key); return true; } Node* cur = _root; Node* parent = NULL; while (cur) { parent = cur; if (key > parent->_key) { cur = parent->_right; } else if (key < parent->_key) { cur = parent->_left; } else { return false; } } //cur找到NULL了,插入新节点 if (key < parent->_key) { parent->_left = new Node(key); } else { parent->_right = new Node(key); } return true; }
Find查找
bool Find(const K& key)//非递归查找 { if (_root == NULL) //空树直接返回 { return false; } //非空树 Node* cur = _root: while (cur) { if (key > cur->_key) //key值大 往右子树找 { cur = cur->_right; } else if (key < cur->_key) //反之 左子树 { cur = cur->_left; } else //找到了返回真 { return true; } } return false; //遍历之后发现并不存在 }
Remove删除
bool Remove(const K& key)//非递归删除 { if (_root == NULL) { return false; } Node* cur = _root; Node* parent = NULL; while (cur) { if (cur->_key > key) { parent = cur; cur = cur->_left; } else if (cur->_key < key) { parent = cur; cur = cur->_right; } else //找到了 分三种情况 { if (cur->_left == NULL)//根的左为空 { if (parent == NULL) { _root = cur->_right; delete cur; return true; } else { Node* tmp = cur->_right; if (parent->_left == cur) { parent->_left = tmp; } else if (parent->_right == cur) { parent->_right = tmp; } delete cur; return true; } } else if(cur->_right == NULL) { Node* tmp = cur->_left; if (parent->_left == cur) { parent->_left = tmp; } else if (parent->_right == cur) { parent->_right = tmp; } delete cur; return true; } else//cur左右两个孩子均不为空 { parent = cur; Node* subleft = cur->_right;//找右孩子的最左节点 while (subleft->_left) { parent = subleft; subleft = subleft->_left; } cur->_key = subleft->_key; if (parent->_left == subleft) { parent->_left = subleft->_right; } else if (parent ->_right == subleft) { parent->_right = subleft->_right; } delete subleft; return true; } } } return false; }
二叉搜索树的退化和缺陷
-如果插入的数接近有序或者基本有序时,会成为一条单向单一的树,类似于链表
例如:{0,1,2,3,4,5,6,7,8,9}
这个时候它的时间复杂度为O(N),所以要考虑高度
附上详细代码
#pragma oncetemplate<class K>struct BinarySearchTreeNode{ K _key; BinarySearchTreeNode<K>* _left; BinarySearchTreeNode<K>* _right; BinarySearchTreeNode(const K& key) :_key(key) ,_left(NULL) ,_right(NULL) {}};template<class K>class BSTree{ typedef BinarySearchTreeNode<K> Node;public: BSTree() //无参构造 :_root(NULL) {} BSTree(K* a, size_t n) //构造函数 { _root = NULL; for (size_t i = 0; i < n; ++i) { InsertR(a[i]); } } ~BSTree() {} bool Insert(const K& key)//非递归插入 { if (_root == NULL) { _root = new Node (key); return true; } Node* cur = _root; Node* parent = NULL; while (cur) { parent = cur; if (key > parent->_key) { cur = parent->_right; } else if (key < parent->_key) { cur = parent->_left; } else { return false; } } //cur找到NULL了,插入新节点 if (key < parent->_key) { parent->_left = new Node(key); } else { parent->_right = new Node(key); } return true; } bool Find(const K& key)//非递归查找 { if (_root == NULL) //空树直接返回 { return false; } //非空树 Node* cur = _root: while (cur) { if (key > cur->_key) //key值大 往右子树找 { cur = cur->_right; } else if (key < cur->_key) //反之 左子树 { cur = cur->_left; } else //找到了返回真 { return true; } } return false; //遍历之后发现并不存在 } bool Remove(const K& key)//非递归删除 { if (_root == NULL) { return false; } Node* cur = _root; Node* parent = NULL; while (cur) { if (cur->_key > key) { parent = cur; cur = cur->_left; } else if (cur->_key < key) { parent = cur; cur = cur->_right; } else //找到了 分三种情况 { if (cur->_left == NULL)//根的左为空 { if (parent == NULL) { _root = cur->_right; delete cur; return true; } else { Node* tmp = cur->_right; if (parent->_left == cur) { parent->_left = tmp; } else if (parent->_right == cur) { parent->_right = tmp; } delete cur; return true; } } else if(cur->_right == NULL) { Node* tmp = cur->_left; if (parent->_left == cur) { parent->_left = tmp; } else if (parent->_right == cur) { parent->_right = tmp; } delete cur; return true; } else//cur左右两个孩子均不为空 { parent = cur; Node* subleft = cur->_right;//找右孩子的最左节点 while (subleft->_left) { parent = subleft; subleft = subleft->_left; } cur->_key = subleft->_key; if (parent->_left == subleft) { parent->_left = subleft->_right; } else if (parent ->_right == subleft) { parent->_right = subleft->_right; } delete subleft; return true; } } } return false; } //bool Insert(const K& key) //递归插入 //{ // return _InsertR(_root, key); //}// bool RemoveR(const K& key) //递归删除// {// return _RemoveR(_root, key);// } void Inorder() { _Inorder(_root); cout << endl; }protected: bool _InsertR(Node*& root,const K& key) { if (root == NULL) { root = new Node(key); } else { if (key > root->_key) { return _InsertR(root->_right, key); } else { return _InsertR(root->_left, key); } } return true; } bool _RemoveR(Node*& root, const K& key) { if (root == NULL) { return false; } else if (root->_key > key) { return _RemoveR(root->_left, key); } else if (root->_key < key) { return _RemoveR(root->_right, key); } else //刚好根节点就是要删除的节点,分三种情况 { if (root->_left == NULL) //根节点左为空 { root = root->_right; } if (root->_right == NULL) //根节点右为空 { root = root->_left; } else if //根节点左右都不为空,找替代节点 { Node* parent = root; Node* subleft = root->right; while (subleft->_left)//右子树最左节点 { root->key = subleft->key; subleft = subleft->left; } } } } void _Inorder(Node* root) { if (root == NULL) { return; } _Inorder(root->_left); cout << root->_key << " "; _Inorder(root->_right); }protected: Node* _root;};void TestBSTree(){ int a[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9 }; BSTree<int> t1; for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); ++i) { t1.Insert(a[i]); } t1.Inorder(); t1.Remove(1); t1.Inorder(); t1.Remove(0); t1.Inorder(); t1.Remove(9); t1.Inorder(); t1.Remove(5); t1.Inorder(); t1.Remove(2); t1.Inorder(); t1.Remove(3); t1.Inorder(); t1.Remove(4); t1.Inorder(); t1.Remove(6); t1.Inorder(); t1.Remove(7); t1.Inorder(); t1.Remove(8); t1.Inorder();}
阅读全文
0 0
- 二叉搜索树—增删查
- 二叉搜索树的增删查改
- 搜索二叉树的增删查改
- 二叉搜索树的增删查
- 二叉搜索树Java实现(增删改查遍历等操作)
- 二叉搜索树的增删查(递归与非递归)实现
- 实现二叉树增删改查
- 二叉树查找增删改查
- 二叉树的增删改查
- 二叉搜索树 并查集
- 算法习题1:二叉树实现增删改查
- ThinkPHP增删改查 搜索 分页
- yii增删改查搜索分页
- 二叉树排序及二叉树节点的增删改查(java实现)
- 二叉树的增删
- 二叉搜索树—平衡二叉树
- 数据结构—二叉搜索树
- MySQL—增删改查
- Android 生命周期中函数执行过程
- 安卓系统开发常用的框架
- spring xml 文件的一些写法,包括map ,set ,list 等
- 计算机网络应用层(一)应用协议原理
- vmware net转发映射ssh端口
- 二叉搜索树—增删查
- rhel6.4部署gateone
- LeeCode编程训练日记一:Two Sum
- 看雪ctf记录第一题
- Linux误删文件教训,吃一堑长一智
- rhel6.4部署tomcat
- 运算符注意的问题
- 开源框架源码分析:网速监听—facebook/network-connection-class
- Linux-rhel6.4部署nginx