一.什么是二叉搜索树
1. 每个节点都有一个作为搜索依据的关键码(key),所有节点的关键码互不相同。
2. 左子树上所有节点的关键码(key)都小于根节点的关键码(key)。
3. 右子树上所有节点的关键码(key)都大于根节点的关键码(key)。
4. 左右子树都是二叉搜索树。
- #pragma once
- using namespace std;
- template<class K>
- struct SelectBinaryTreeNode
- {
- typedef SelectBinaryTreeNode<K> Node;
- K _key;
- Node* _left;
- Node* _right;
- SelectBinaryTreeNode(const K& key)
- :_key(key),_left(NULL),_right(NULL)
- {}
- };
- template<class K>
- class SelectBinaryTree
- {
- public:
- typedef SelectBinaryTreeNode<K> Node;
- SelectBinaryTree()
- {}
- SelectBinaryTree(const SelectBinaryTree& sbt) //拷贝构造,递归实现
- {
- _root=_Copy(sbt._root);
- }
- ~SelectBinaryTree() //析构,递归实现
- {
- _Delete(_root);
- }
- bool Find(const K& key) //非递归查找
- {
- if (NULL == _root)
- return false;
- Node* cur = _root;
- while (cur)
- {
- if (cur->_key < key)
- cur = cur->_right;
- else if (cur->_key>key)
- cur = cur->_left;
- else
- return true;
- }
- return false;
- }
- bool FindR(const K& key) //递归查找
- {
- return _FindR(_root,key);
- }
- void InOrder() //中序遍历
- {
- _InOrder(_root);
- cout << endl;
- }
- bool Insert(const K& key) //非递归插入
- {
- if (NULL == _root)
- {
- _root = new Node(key);
- return true;
- }
- Node* cur = _root;
- Node* parent = NULL;
- while (cur)
- {
- if (cur->_key < key)
- {
- parent = cur;
- cur = cur->_right;
- }
- else if (cur->_key>key)
- {
- parent = cur;
- cur = cur->_left;
- }
- else
- return false;
- }
- if (parent->_key < key)
- {
- parent->_right = new Node(key);
- }
- else
- parent->_left = new Node(key);
- return true;
- }
- bool InsertR(const K& key) //递归插入
- {
- return _InsertR(_root,key);
- }
- bool RemoveR(const K& key) //递归删除
- {
- return _RemoveR(_root,key);
- }
- bool Remove(const K& key) //非递归删除
- {
- if (NULL == _root)
- return false;
- Node* cur = _root;
- Node* parent = NULL;
- while (cur)
- {
- if (cur->_key < key)
- {
- parent = cur;
- cur = cur->_right;
- }
- else if (cur->_key>key)
- {
- parent = cur;
- cur = cur->_left;
- }
- else //找到了进行删除
- {
- Node* del = cur;
- if (cur->_left == NULL ) //左为空
- {
- if (parent == NULL) //要删除的是根节点
- _root = cur->_right;
- else
- {
- if (parent->_left == cur)
- parent->_left = cur->_right;
- else
- parent->_right = cur->_right;
- }
- }
- else if (cur->_right == NULL) //右为空
- {
- if (NULL == parent)
- _root = cur->_left;
- else
- {
- if (parent->_left == cur)
- parent->_left = cur->_left;
- else
- parent->_right = cur->_left;
- }
- }
- else //左右都不为空
- {
- Node* pcur = cur->_right;
- Node* pparent = cur;
- while (pcur->_left) //找到右树的最左结点
- {
- pparent = pcur;
- pcur = pcur->_left;
- }
- //K tmp = cur->_key;
- //cur->_key = pcur->_key;
- //pcur->_key = tmp;
- //找到后本应该像上面一样交换,但是因为pcur马上要删除,所以直接赋值就好
- cur->_key = pcur->_key;
- del = pcur;
- if (pparent->_left == pcur)
- pparent->_left = pcur->_right;
- else
- pparent->_right = pcur->_right;
- }
- delete del;
- return true;
- }
- }
- return false;
- }
- protected:
- bool _RemoveR(Node*& root,const K& key)
- {
- if (root->_key < key)
- return _RemoveR(root->_right,key);
- else if (root->_key>key)
- return _RemoveR(root->_left,key);
- else
- {
- Node* del = root;
- if (root->_left == NULL) //要删除的结点左为空
- {
- root = root->_right;
- }
- else if (root->_right == NULL )//要删除的结点右为空
- {
- root = root->_left;
- }
- else //左右都不为空
- {
- Node* pcur = root->_right;
- while (pcur->_left)
- {
- pcur = pcur->_left;
- }
- root->_key = pcur->_key;
- del = pcur;
- }
- delete del;
- return true;
- }
- return false;
- }
- bool _InsertR(Node*& root,const K& key)
- {
- if (NULL == root)
- {
- root = new Node(key);
- return true;
- }
- if (root->_key < key)
- return _InsertR(root->_right,key);
- else if (root->_key>key)
- return _InsertR(root->_left,key);
- else
- return false;
- }
- bool _FindR(Node* root,const K& key)
- {
- if (NULL == root)
- return false;
- if (root->_key == key)
- return true;
- else if (root->_key < key)
- _FindR(root->_right,key);
- else if (root->_key>key)
- _FindR(root->_left,key);
- }
- void _Delete(Node* root) //递归删除
- {
- if (root)
- {
- _Delete(root->_left);
- _Delete(root->_right);
- delete root;
- }
- }
- Node* _Copy(Node* sroot) //递归拷贝
- {
- Node* cur = NULL;
- if (sroot)
- {
- cur = new Node(sroot->_key);
- cur->_left = _Copy(sroot->_left);
- cur->_right = _Copy(sroot->_right);
- }
- return cur;
- }
- void _InOrder(Node* root)
- {
- if (NULL == root)
- return;
- _InOrder(root->_left);
- cout << root->_key<<" ";
- _InOrder(root->_right);
- }
- private:
- Node* _root;
- };
- void TestSelectBinaryTree() //测试非递归版
- {
- int a[] = { 5,3,4,1,7,8,2,6,9 };
- SelectBinaryTree<int> sbt;
- for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); i++)
- {
- sbt.Insert(a[i]);
- }
- SelectBinaryTree<int> sbt1(sbt); //测试拷贝构造
- sbt1.InOrder();
- sbt.InOrder();
- sbt.Remove(0);
- sbt.Remove(1);
- sbt.Remove(2);
- sbt.Remove(3);
- sbt.Remove(4);
- sbt.Remove(5);
- sbt.Remove(6);
- sbt.Remove(7);
- sbt.Remove(8);
- sbt.Remove(9);
- sbt.InOrder();
- //cout<<sbt.Find(11)<<endl;
- }
- void TestSelectBinaryTreeR() //测试递归版
- {
- int a[] = { 5,9 };
- SelectBinaryTree<int> sbt;
- for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); i++)
- {
- sbt.InsertR(a[i]);
- }
- SelectBinaryTree<int> sbt1(sbt); //测试拷贝构造
- sbt1.InOrder();
- sbt.InOrder();
- sbt.RemoveR(0);
- sbt.InOrder();
- sbt.RemoveR(1);
- sbt.InOrder();
- sbt.RemoveR(2);
- sbt.InOrder();
- sbt.RemoveR(3);
- sbt.InOrder();
- sbt.RemoveR(4);
- sbt.InOrder();
- sbt.RemoveR(5);
- sbt.InOrder();
- sbt.RemoveR(6);
- sbt.InOrder();
- sbt.RemoveR(7);
- sbt.InOrder();
- sbt.RemoveR(8);
- sbt.InOrder();
- sbt.RemoveR(9);
- sbt.InOrder();
- //cout<<sbt.FindR(11)<<endl;
- }