赞
踩
二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:
template <class T>
struct BSTreeNode
{
typedef BSTreeNode Node;
Node* _left;
Node* _right;
T _key;
BSTreeNode(const T& val)
:_left(nullptr)
,_right(nullptr)
,_key(val)
{}
};
bool Find(const T& val)
{
Node* cur = _root;
while (cur)
{
if (val > cur->_key)
cur = cur->_right;
else if (val < cur->_key)
cur = cur->_left;
else return true;
}
return false;
}
注意细节:
bool Insert(const T& val) { //记录链接的节点。 Node* parent = nullptr; Node* cur = _root; //当插入的节点是第一个节点时 if (_root == nullptr) { _root = new Node(val); return true; } while (cur) { if (val > cur->_key) { parent = cur; cur = cur->_right; } else if (val < cur->_key) { parent = cur; cur = cur->_left; } else { return false; } } cur = new Node(val); //判断是链接右节点还是左节点。 if (parent->_key < val) parent->_right = cur; else parent->_left = cur; return true; }
删除分三种情况:
bool Erase(const T& val) { Node* cur = _root; Node* parent = nullptr; while (cur) { if (val > cur->_key) { parent = cur; cur = cur->_right; } else if (val < cur->_key) { parent = cur; cur = cur->_left; } else { if (cur->_left == nullptr) { //处理删除头节点的情况 if (cur == _root) { _root = cur->_right; } else { if (parent->_left == cur) { parent->_left = cur->_right; } else { parent->_right = cur->_right; } delete cur; } } else if (cur->_right == nullptr) { //处理删除头节点的情况 if (cur == _root) { _root = cur->_left; } else { if (parent->_left == cur) { parent->_left = cur->_left; } else { parent->_right = cur->_left; } delete cur; } } else { //替换法 //这里要注意力RightMin不能定义成nullptr,因为如果删除的是头节点就会出现野指针的问题,所以这里要定义成cur Node* RightMin = cur; //定义右子树,找到右子树最左节点 Node* RightCur = cur->_right; while (RightCur->_left) { RightMin = RightCur; RightMin = RightMin->_left; } //交换值 swap(RightCur->_key, cur->_key); if (RightMin->_left == RightCur) { RightMin -> _left = RightCur->_right; } else { RightMin->_right = RightCur->_right; } delete RightCur; } return true; } } return false; }
这里我们会发现中序遍历搜索二叉树得到是一个有序的数列。
//这里说明一下,因为中序是要使用到递归的,也就是要传_root成员变量的。 //但是我们又不能修改_root所以要额外写一个函数来是由递归。 void Inorder() { _Inorder(_root); cout << endl; } private: void _Inorder(Node* root) { if (root == nullptr) return; _Inorder(root->_left); cout << root->_key << " "; _Inorder(root->_right); }
BSTree(Node* root = nullptr) :_root(root) {} BSTree(const BSTree<T>& b) { _root = Copy(b._root); } BSTree<T>& operator=(BSTree<T> b) { swap(_root, b._root); return *this; } ~BSTree() { Destroy(_root); } private: //前序常见节点 Node* Copy(Node* root) { if (root == nullptr) return nullptr; Node* newNode = new Node(root->_key); newNode->_left = Copy(root->_left); newNode->_right = Copy(root->_right); return newNode; } //后序delete节点 void Destroy(Node* root) { if (root == nullptr) return; Destroy(root->_left); Destroy(root->_right); }
递归版本的整体思路是一样的。
bool FindR(const T& val) { return _FindR(val, _root); } bool _FindR(const T& val, Node* root) { if (root == nullptr) return false; if (val > root->_key) return _FindR(val, root->_right); else if (val < root->_key) return _FindR(val, root->_left); else return true; }
bool InsertR(const T& val) { return _InsertR(val, _root); } bool _InsertR(const T& val, Node*& root) { if (root == nullptr) { root = new Node(val); return true; } if (val > root->_key) return _InsertR(val, root->_right); else if (val < root->_key) return _InsertR(val, root->_left); else return false; }
删除也是一样的参数传递Node*& root
但是当删除的节点左右都不为空的时候就可以不用替换法了,只需要将将最左节点和删除的点swap一下,在递归删除节点指向的_right也就是右子树再次递归一下即可。
bool EraseR(const T& val) { return _EraseR(val, _root); } bool _EraseR(const T& val, Node*& root) { if (root == nullptr) return false; if (val > root->_key) return _EraseR(val, root->_right); else if (val < root->_key) return _EraseR(val, root->_left); else { Node* del = root; if (root->_left == nullptr) { root = root->_right; } else if (root->_right == nullptr) { root = root->_left; } else { Node* cur = root->_right; while (cur->_left) { cur = cur->_left; } //交换cur节点和最左节点 swap(root->_key, cur->_key); 递归右子树 return _EraseR(val, root->_right); } delete del; return true; } }
#pragma once #include <iostream> using namespace std; template <class T> struct BSTreeNode { typedef BSTreeNode Node; Node* _left; Node* _right; T _key; BSTreeNode(const T& val) :_left(nullptr) ,_right(nullptr) ,_key(val) {} }; template <class T> class BSTree { typedef BSTreeNode<T> Node; public: BSTree(Node* root = nullptr) :_root(root) {} BSTree(const BSTree<T>& b) { _root = Copy(b._root); } BSTree<T>& operator=(BSTree<T> b) { swap(_root, b._root); return *this; } ~BSTree() { Destroy(_root); } bool Find(const T& val) { Node* cur = _root; while (cur) { if (val > cur->_key) cur = cur->_right; else if (val < cur->_key) cur = cur->_left; else return true; } return false; } bool Insert(const T& val) { Node* parent = nullptr; Node* cur = _root; if (_root == nullptr) { _root = new Node(val); return true; } while (cur) { if (val > cur->_key) { parent = cur; cur = cur->_right; } else if (val < cur->_key) { parent = cur; cur = cur->_left; } else { return false; } } cur = new Node(val); if (parent->_key < val) parent->_right = cur; else parent->_left = cur; return true; } bool Erase(const T& val) { Node* cur = _root; Node* parent = nullptr; while (cur) { if (val > cur->_key) { parent = cur; cur = cur->_right; } else if (val < cur->_key) { parent = cur; cur = cur->_left; } else { if (cur->_left == nullptr) { if (cur == _root) { _root = cur->_right; } else { if (parent->_left == cur) { parent->_left = cur->_right; } else { parent->_right = cur->_right; } delete cur; } } else if (cur->_right == nullptr) { if (cur == _root) { _root = cur->_left; } else { if (parent->_left == cur) { parent->_left = cur->_left; } else { parent->_right = cur->_left; } delete cur; } } else { //替换法 Node* RightMin = cur; Node* RightCur = cur->_right; while (RightCur->_left) { RightMin = RightCur; RightMin = RightMin->_left; } swap(RightCur->_key, cur->_key); if (RightMin->_left == RightCur) { RightMin -> _left = RightCur->_right; } else { RightMin->_right = RightCur->_right; } delete RightCur; } return true; } } return false; } void Inorder() { _Inorder(_root); cout << endl; } ///递归版本/ bool FindR(const T& val) { return _FindR(val, _root); } bool InsertR(const T& val) { return _InsertR(val, _root); } bool EraseR(const T& val) { return _EraseR(val, _root); } private: bool _EraseR(const T& val, Node*& root) { if (root == nullptr) return false; if (val > root->_key) return _EraseR(val, root->_right); else if (val < root->_key) return _EraseR(val, root->_left); else { Node* del = root; if (root->_left == nullptr) { root = root->_right; } else if (root->_right == nullptr) { root = root->_left; } else { Node* cur = root->_right; while (cur->_left) { cur = cur->_left; } swap(root->_key, cur->_key); return _EraseR(val, root->_right); } delete del; return true; } } bool _InsertR(const T& val, Node*& root) { if (root == nullptr) { root = new Node(val); return true; } if (val > root->_key) return _InsertR(val, root->_right); else if (val < root->_key) return _InsertR(val, root->_left); else return false; } bool _FindR(const T& val, Node* root) { if (root == nullptr) return false; if (val > root->_key) return _FindR(val, root->_right); else if (val < root->_key) return _FindR(val, root->_left); else return true; } private: Node* Copy(Node* root) { if (root == nullptr) return nullptr; Node* newNode = new Node(root->_key); newNode->_left = Copy(root->_left); newNode->_right = Copy(root->_right); return newNode; } void Destroy(Node* root) { if (root == nullptr) return; Destroy(root->_left); Destroy(root->_right); delete root; } void _Inorder(Node* root) { if (root == nullptr) return; _Inorder(root->_left); cout << root->_key << " "; _Inorder(root->_right); } private: Node* _root = nullptr; };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。