搜索二叉树
来源:互联网 发布:vs2017 golang 编辑:程序博客网 时间:2024/04/29 02:25
搜索二叉树的性质
1. 每个节点都有一个作为搜索依据的关键码(key),所有节点的关 键码互不相同。 2. 左子树上所有节点的关键码(key)都小于根节点的关键码(key)。 3. 右子树上所有节点的关键码(key)都大于根节点的关键码(key)。 4. 左右子树都是二叉搜索树。
例如:
第二棵树中,左边的8比根节点5大,右边的4比根节点5小.不满足搜索二叉树的性质。
搜索二叉树的插入
在插入一个数后,依然满足搜索二叉树。
插入分为:
1、为空树,就直接插入。
2、从根节点依次比较,比根节点小,往左树找,比根节点大,往右树找。找到后进行插入。
3、有了这个数就直接返回,不进行插入。
非递归:
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 > cur->_key)//左树进行找 { cur = cur->_right; } else if (key < cur->_key)//右树进行找 { cur = cur->_left; } else//没找到直接返回 { return false; } } if (key < parent->_key) { parent->_left = new Node(key); } else { parent->_right = new Node(key); } return true; }
递归:
bool _InsertR(Node*& cur, size_t key)//递归插入 { if (cur == NULL) { cur = new Node(key); return true; } if (key < cur->_key) { _InsertR(cur->_left,key); } else if(key > cur->_key) { _InsertR(cur->_right,key); } else { return false; } }
搜索二叉树的查找
查找分为:
1、空树,直接返回false。
2、与根节点比较,比根节点小,左子树找,比根节点大,右子树找。找到后返回true。
3、没找到,返回false。
非递归:
bool Find(const K& key)//非递归插入 { if (_root == NULL)//空树 return false; Node* cur = _root; while (cur) { if (key < cur->_key)//左树找 { cur = cur->_left; } else if (key > cur->_key)//右树找 { cur = cur->_right; } else//找到 { return true; } } return false; }
递归:
bool _FindR(Node*& cur, size_t key)//递归查找 { if (cur == NULL) return false; if (key < cur->_key) { _FindR(cur->_left, key); } else if (key > cur->_key) { _FindR(cur->_right, key); } else { return true; } return false; }
搜索二叉树的删除
在删除一个数后,依然满足搜索二叉树。
删除分为:
1、空树,直接返回。
2、先找这个数,找不到返回。
3、找到后,左子树为空。
4、找到后,右子树为空。
5、找到后,左右都不为空。
大致情况为:
非递归:
bool Remove(const K& key) { if (_root == NULL)//空树,删除不了 ,返回false return false; Node* cur = _root; Node* parent = NULL; Node* del = NULL; while (cur) { if (key < cur->_key)//找的数比根节点小,在左子树上继续找 { parent = cur; cur = cur->_left; } else if (key > cur->_key)//找的数比根节点大,在右子树上继续找 { parent = cur; cur = cur->_right; } else//找到了 { if (cur->_left == NULL)//找到的节点的左为空 { if (parent == NULL) _root = cur->_right; else { if (cur == parent->_right) parent->_right = cur->_right; else parent->_left = cur->_right; } del = cur; } else if (cur->_right == NULL)//找到的节点右为空(包括左右都为空的) { if (parent == NULL) _root = cur->_left; else { if (cur == parent->_left) parent->_left = cur->_left; else parent->_right = cur->_left; } del = cur; } else//找到的节点左右都不为空,用替换法删除(左子树的最右节点,右子树的最左节点) { Node* subNode = cur->_left; Node* tmp = cur; while (subNode->_right) { tmp = subNode; subNode = subNode->_right; } swap(subNode->_key, cur->_key); if (subNode == tmp->_left) tmp->_left = subNode->_right; else tmp->_right = subNode->_right; del = subNode; } delete del; del = NULL; return true; } } return false; }
递归:
bool _RemoveR(Node*& cur,size_t key) { if (cur == NULL) { return false; } if (key < cur->_key) { _RemoveR(cur->_left, key); } else if (key > cur->_key) { _RemoveR(cur->_right, key); } else { Node* del = cur; if (cur->_left == NULL) { cur = cur->_left; } else if (cur->_right == NULL) { cur = cur->_right; } else { Node* parent = cur; Node* subNode = cur->_left; while (subNode->_right) { parent = subNode; subNode = subNode->_right; } swap(subNode->_key, cur->_key); if (parent->_right = subNode) parent->_right = subNode->_right; else parent->_left = subNode->_right; del = subNode; } delete del; del = NULL; return true; } return false; }
代码实现:
"SearchBinaryTree.h"#pragma oncetemplate <class K>struct SearchBinaryTreeNode{ K _key; SearchBinaryTreeNode<K>* _left; SearchBinaryTreeNode<K>* _right; SearchBinaryTreeNode(const K& key) :_key(key) , _left(NULL) , _right(NULL) {}};template <class K>class SearchBinaryTree{ typedef SearchBinaryTreeNode<K> Node;public: SearchBinaryTree()//无参构造 :_root(NULL) {} SearchBinaryTree(K* a, size_t n)//构造函数 { _root = NULL; for (size_t i = 0; i < n; ++i) { InsertR(a[i]); } } ~SearchBinaryTree() { _Destory(_root); } 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 > cur->_key) { cur = cur->_right; } else if (key < cur->_key) { cur = cur->_left; } else { return false; } } if (key < parent->_key) { parent->_left = new Node(key); } else { parent->_right = new Node(key); } return true; } bool InsertR(const K& key) { return _InsertR(_root, key); } bool Remove(const K& key) { if (_root == NULL)//空树,删除不了 ,返回false return false; Node* cur = _root; Node* parent = NULL; Node* del = NULL; while (cur) { if (key < cur->_key)//找的数比根节点小,在左子树上继续找 { parent = cur; cur = cur->_left; } else if (key > cur->_key)//找的数比根节点大,在右子树上继续找 { parent = cur; cur = cur->_right; } else//找到了 { if (cur->_left == NULL)//找到的节点的左为空 { if (parent == NULL) _root = cur->_right; else { if (cur == parent->_right) parent->_right = cur->_right; else parent->_left = cur->_right; } del = cur; } else if (cur->_right == NULL)//找到的节点右为空(包括左右都为空的) { if (parent == NULL) _root = cur->_left; else { if (cur == parent->_left) parent->_left = cur->_left; else parent->_right = cur->_left; } del = cur; } else//找到的节点左右都不为空,用替换法删除(左子树的最右节点,右子树的最左节点) { Node* subNode = cur->_left; Node* tmp = cur; while (subNode->_right) { tmp = subNode; subNode = subNode->_right; } swap(subNode->_key, cur->_key); if (subNode == tmp->_left) tmp->_left = subNode->_right; else tmp->_right = subNode->_right; del = subNode; } delete del; del = NULL; return true; } } return false; } bool RemoveR(const K& key) { return _RemoveR(_root, key); } bool Find(const K& key) { if (_root == NULL) return false; Node* cur = _root; while (cur) { if (key < cur->_key) { cur = cur->_left; } else if (key > cur->_key) { cur = cur->_right; } else { return true; } } return false; } bool FindR(const K& key) { return _FindR(_root, key); } void InOrder() { _InOrder(_root); cout << endl; }protected: bool _FindR(Node*& cur, size_t key) { if (cur == NULL) return false; if (key < cur->_key) { _FindR(cur->_left, key); } else if (key > cur->_key) { _FindR(cur->_right, key); } else { return true; } return false; } bool _RemoveR(Node*& cur,size_t key) { if (cur == NULL) { return false; } if (key < cur->_key) { _RemoveR(cur->_left, key); } else if (key > cur->_key) { _RemoveR(cur->_right, key); } else { Node* del = cur; if (cur->_left == NULL) { cur = cur->_left; } else if (cur->_right == NULL) { cur = cur->_right; } else { Node* parent = cur; Node* subNode = cur->_left; while (subNode->_right) { parent = subNode; subNode = subNode->_right; } swap(subNode->_key, cur->_key); if (parent->_right = subNode) parent->_right = subNode->_right; else parent->_left = subNode->_right; del = subNode; } delete del; del = NULL; return true; } return false; } bool _InsertR(Node*& cur, size_t key) { if (cur == NULL) { cur = new Node(key); return true; } if (key < cur->_key) { _InsertR(cur->_left,key); } else if(key > cur->_key) { _InsertR(cur->_right,key); } else { return false; } } void _Destory(Node* cur) { if (cur == NULL) return; _Destory(cur->_left); _Destory(cur->_right); delete cur; cur = NULL; } void _InOrder(Node*& cur) { if (cur == NULL) return; _InOrder(cur->_left); cout << cur->_key << " "; _InOrder(cur->_right); }protected: Node* _root;};void TestSearchBinaryTree(){ int a[] = { 5, 1, 2, 8, 3, 9, 4, 6, 7, 0 }; SearchBinaryTree<int> t(a,sizeof(a)/sizeof(a[0]));}"Test.cpp"#include <iostream>using namespace std;#include "SearchBinaryTree.h"int main(){ TestSearchBinaryTree(); return 0;}
1 0
- 【二叉搜索数】HDU3791二叉搜索树
- 二叉树--二叉搜索树
- 【二叉树】二叉搜索树
- 二叉树- 二叉搜索树
- 【搜索树】二叉搜索树
- 二叉搜索树BSTree
- 二叉搜索树
- 二叉搜索树
- 二叉搜索树
- 最优二叉搜索树
- 二叉搜索树
- 二叉搜索树
- HDOJ3791 二叉搜索树
- 二叉查找树搜索
- 二叉搜索树
- 二叉搜索树
- BST 二叉搜索树
- 二叉搜索树
- C++头文件
- scrapy1.3.2文件结构
- Ceilometr: 2 、Cnocchi技术介绍
- KVC
- solr5.3.1 集成IK中文分词器
- 搜索二叉树
- Spring MVC 入门示例讲解
- XXX is not JSON serializable 另类解决方式
- KVO
- C++中的enum类型
- java 基础运算
- 【SSH网上商城项目实战27】域名空间的申请和项目的部署及发布
- 记录自己有用的链接
- ACM个人模板