二叉搜索树
来源:互联网 发布:淘宝上的海外专营店 编辑:程序博客网 时间:2024/06/12 01:16
二叉查找树(Binary Search Tree)(二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树:
1. 每个节点都有一个作为搜索依据的关键码(key),所有节点的关键码互不同。
2. 左子树上所有节点的关键码(key)都小于根节点的关键码(key)。
3. 右子树上所有节点的关键码(key)都大于根节点的关键码(key)。
4. 左右子树都是二叉搜索树。
对于二叉搜索树,在实现它的结点的插入、删除、查找时,插入结点不是很复杂,但是对于其删除有一定的难度。在实现删除时,要考虑的情况较多。
一、对二叉树的定义:
template<class K,class V>struct BSTNode{K _key;V _value;BSTNode<K, V>* _Left;BSTNode<K, V>* _Right;BSTNode(K key,V value):_key(key),_value(value),_Left(NULL),_Right(NULL){}};template<class K, class V>class BSTree{typedef BSTNode<K, V> Node;public:BSTree():_root(NULL){}}对于定义,应该没什么问题。那就来说说它的插入、删除、查找的实现。
二、插入的实现
对于插入,在此我用两种方法来实现(递归和非递归)
首先,非递归的方法:(在插入时,都要按照二叉树的性质来实现即要在合适位置)
思想:1、先考虑根结点为空。
2、保存上一个节点,插入时要找上一个结点。
3、找到合适的位置(要插入的key小于当前key就往左子树找反之往右子树找)
4、找到合适位置后,插入结点。
bool Insert(const K& key, const V& value){if (_root == NULL){ _root = new Node(key, value); return true;}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{return false;}}if (parent->_key > key){parent->_Left = new Node(key, value);}else{parent->_Right = new Node(key, value);}return true;}非递归完成后,我们来看一下Insert的递归的形式
bool _Insert_R(Node* &root, const K& key, const V& value){if (root == NULL){root = new Node(key, value);return true;}if (root->_key > key){return _Insert_R(root->_Left,key,value);}else if (root->_key < key){return _Insert_R(root->_Right,key,value);}return false;}接下来就是的查找和删除,先看一下查找:
三、查找的实现(非递归形式):
Node* _Find(Node* root, const K& key){if (root == NULL)return NULL;Node* cur = root;while (cur){if (cur->_key > key){cur = cur->_Left;}else if (cur->_key < key){cur = cur->_Right;}else {return cur;}}return NULL;}查找的递归形式:
Node* _Find_R(Node* &root, const K& key){if (root == NULL) //没有结点return root;if (root->_key == key)return root;if (root->_key < key){return _Find_R(root->_Right, key);}else{return _Find_R(root->_Left, key);}}四、删除的实现:(非递归)对于删除,在此需要考虑的情况非常多。
下面是删除的思想:
(在删除时,也要和查找一样,先查找到要删除的结点,然后删除)
1、考虑根结点为空情况和一个结点情况
2、当有多个结点时,根据上图中的情形考虑到不同情况
(1)要删除的左结点的左子树或右子数为空。
(2)要删除的结点是根结点。
(3)要删除的结点的左右结点都不为空。
bool _Remove(Node* root, const K& key){if (root == NULL) //没有结点return false;if (root->_Left == NULL&&root->_Right == NULL) //一个结点{if (root->_key == key){delete root;root = NULL;return true;}else{return false;}}Node* cur = root; //多个节点Node* prev = NULL;while (cur){if (cur->_key > key){prev = cur;cur = cur->_Left;}else if (cur->_key < key){prev = cur;cur = cur->_Right;}else //找到了要删除的结点,判断左子树是否为空,若为空,把删除点的左子树设为删除点右子树的左子树{Node *del = cur;if (cur->_Left == NULL){if (prev== NULL){_root = cur->_Right;}else{if (prev->_Left == cur){prev->_Left = cur->_Right;}else{prev->_Right = cur->_Right;}}}else if (cur->_Right == NULL){if (prev == NULL){_root= cur->_Left;}else{if (prev->_Left == cur){prev->_Left = cur->_Left;}else{prev->_Right = cur->_Left;}}}else //左右都不为空{prev = cur;Node* fistleft = cur->_Right;while (fistleft->_Left){prev = fistleft;fistleft = fistleft->_Left;}swap(cur->_key, fistleft->_key);swap(cur->_value, fistleft->_value);del = fistleft;if (prev->_Left == fistleft){prev->_Left = fistleft->_Right;}else{prev->_Right = fistleft->_Right;}}delete del;return true;}}return false;}删除的递归形式:
bool _Remove_R(Node* &root, const K& key) //引用{if (root == NULL){return false;}if (root->_key < key){return _Remove_R(root->_Right,key);}else if (root->_key > key){return _Remove_R(root->_Left,key);}else{if (root->_Left == NULL){root = root->_Right;}else if (root->_Right==NULL){root = root->_Left;}else{Node* firstleft = root->_Right;while (firstleft->_Left){firstleft = firstleft->_Left;}swap(firstleft->_key, root->_key);swap(firstleft->_value, root->_value);_Remove_R(firstleft,key);}return true;}}五、二叉查找树的时间复杂度
它和二分查找一样,插入和查找的时间复杂度均为lgN,但是在最坏的情况下仍然会有N的时间复杂度。原因在于插入和删除元素的时候,树没有保持平衡。
- 【二叉搜索数】HDU3791二叉搜索树
- 二叉树--二叉搜索树
- 【二叉树】二叉搜索树
- 二叉树- 二叉搜索树
- 【搜索树】二叉搜索树
- 二叉搜索树BSTree
- 二叉搜索树
- 二叉搜索树
- 二叉搜索树
- 最优二叉搜索树
- 二叉搜索树
- 二叉搜索树
- HDOJ3791 二叉搜索树
- 二叉查找树搜索
- 二叉搜索树
- 二叉搜索树
- BST 二叉搜索树
- 二叉搜索树
- Hadoop计算框架shuffle过程详解
- cs231学习笔记二 线性分类器、SVM、Softmax
- C语言代码合并神器for Mac
- LeetCode 63. Unique Paths II
- myEclipse中的web项目直接引入到eclipse中运行
- 二叉搜索树
- hibernate笔记
- 线程同步(计时器)
- SecureCRT 连接虚拟机Linux
- SpringMvc Eclipse搭建web项目
- C语言代码计算神器for Mac
- A* 寻路
- 软件开发生命周期的管理
- android五中方式调用服务service中的方法