二叉排序树
代码
#include <iostream>
using namespace std;
template <typename T>
struct Node
{
T data;
Node<T> *left;
Node<T> *right;
Node<T> *parent;
Node() : left(nullptr), right(nullptr), parent(nullptr) {}
Node(const T &value) : data(value), left(nullptr), right(nullptr), parent(nullptr) {}
};
template <typename T>
Node<T>* create_node(const T &data)
{
Node<T> *pNode = new Node<T>(data);
return pNode;
}
template <typename T>
class BinarySortTree
{
private:
Node<T> *m_pRoot;
public:
BinarySortTree()
: m_pRoot(nullptr) {}
~BinarySortTree()
{
destroy(m_pRoot);
}
bool isEmpty() const
{
return (m_pRoot == nullptr);
}
void insert(const T &data)
{
Node<T> *pNode = create_node(data);
if (m_pRoot == nullptr)
{
m_pRoot = pNode;
}
else
{
Node<T> *pCur = m_pRoot;
Node<T> *pPre = nullptr;
while (pCur != nullptr)
{
pPre = pCur;
if (data < pCur->data)
{
pCur = pCur->left;
}
else if (data > pCur->data)
{
pCur = pCur->right;
}
else
{
delete pNode;
return;
}
}
if (data < pPre->data)
{
pPre->left = pNode;
}
else
{
pPre->right = pNode;
}
pNode->parent = pPre;
}
}
void insertByRecur(const T &data)
{
if (m_pRoot == nullptr)
{
Node<T> *pNode = create_node(data);
m_pRoot = pNode;
}
else
{
insert(m_pRoot, data);
}
}
Node<T>* find(const T &data)
{
Node<T> *pCur = m_pRoot;
while (pCur != nullptr)
{
if (data < pCur->data)
{
pCur = pCur->left;
}
else if (data > pCur->data)
{
pCur = pCur->right;
}
else
{
break;
}
}
return pCur;
}
void deleteSubTree(const T &data)
{
Node<T> *pNode = find(data);
if (pNode != nullptr)
{
deleteSubTree(pNode);
}
}
void deleteNode(const T &data)
{
Node<T> *pNode = find(data);
if (pNode != nullptr)
{
deleteNodeImpl(pNode);
}
}
void print() const
{
print(m_pRoot);
cout << endl;
}
private:
static void destroy(Node<T> *pRoot)
{
if (pRoot == nullptr)
return;
destroy(pRoot->left);
destroy(pRoot->right);
delete pRoot;
pRoot = nullptr;
}
static void insert(Node<T> *pRoot, const T &data)
{
if (data < pRoot->data)
{
if (pRoot->left == nullptr)
{
Node<T> *pNode = create_node(data);
pRoot->left = pNode;
pNode->parent = pRoot;
}
else
{
insert(pRoot->left, data);
}
}
else if (data > pRoot->data)
{
if (pRoot->right == nullptr)
{
Node<T> *pNode = create_node(data);
pRoot->right = pNode;
pNode->parent = pRoot;
}
else
{
insert(pRoot->right, data);
}
}
else
{
return;
}
}
void deleteSubTree(Node<T> *pRoot)
{
if (pRoot->left != nullptr)
deleteSubTree(pRoot->left);
if (pRoot->right != nullptr)
deleteSubTree(pRoot->right);
if (pRoot->parent == nullptr)
{
delete pRoot;
m_pRoot = nullptr;
return;
}
if (pRoot->data < pRoot->parent->data)
pRoot->parent->left = nullptr;
else
pRoot->parent->right = nullptr;
delete pRoot;
}
void deleteNodeImpl(Node<T> *pNode)
{
if ((pNode->left == nullptr) && (pNode->right == nullptr))
deleteLeafNode(pNode);
else if ((pNode->left != nullptr) && (pNode->right == nullptr))
deleteNodeHasLeft(pNode);
else if ((pNode->left == nullptr) && (pNode->right != nullptr))
deleteNodeHasRight(pNode);
else
deleteNodeHasBoth(pNode);
}
void deleteLeafNode(Node<T> *pNode)
{
if (pNode->parent == nullptr)
{
m_pRoot = nullptr;
}
else
{
if (pNode->data < pNode->parent->data)
pNode->parent->left = nullptr;
else if (pNode->data > pNode->parent->data)
pNode->parent->right = nullptr;
}
delete pNode;
}
void deleteNodeHasLeft(Node<T> *pNode)
{
if (pNode->parent == nullptr)
{
m_pRoot = pNode->left;
m_pRoot->parent = nullptr;
}
else
{
pNode->left->parent = pNode->parent;
if (pNode->data < pNode->parent->data)
pNode->parent->left = pNode->left;
else if (pNode->data > pNode->parent->data)
pNode->parent->right = pNode->left;
}
delete pNode;
}
void deleteNodeHasRight(Node<T> *pNode)
{
if (pNode->parent == nullptr)
{
m_pRoot = pNode->right;
m_pRoot->parent = nullptr;
delete pNode;
}
else
{
pNode->right->parent = pNode->parent;
if (pNode->data < pNode->parent->data)
pNode->parent->left = pNode->right;
else if (pNode->data > pNode->parent->data)
pNode->parent->right = pNode->right;
}
delete pNode;
}
void deleteNodeHasBoth(Node<T> *pNode)
{
Node<T> *pCur = pNode->left;
Node<T> *pPre = nullptr;
while (pCur != nullptr)
{
pPre = pCur;
pCur = pCur->right;
}
T backup = pPre->data;
deleteNodeImpl(pPre);
pNode->data = backup;
}
static void print(Node<T> *pRoot)
{
if (pRoot == nullptr)
return;
print(pRoot->left);
cout << pRoot->data << " ";
print(pRoot->right);
}
};
int main()
{
BinarySortTree<int> sortTree;
cout << "is the tree empty: " << sortTree.isEmpty() << endl;
sortTree.insert(32);
sortTree.insert(45);
sortTree.insert(16);
sortTree.insert(7);
sortTree.insert(28);
sortTree.insert(40);
cout << "is the tree empty after inserting: " << sortTree.isEmpty() << endl;
sortTree.print();
sortTree.insertByRecur(30);
sortTree.insertByRecur(19);
sortTree.insertByRecur(7);
sortTree.insertByRecur(56);
sortTree.insertByRecur(43);
sortTree.insertByRecur(78);
cout << "is the tree empty after inserting: " << sortTree.isEmpty() << endl;
sortTree.print();
auto pNode = sortTree.find(40);
cout << "is there 40: " << ((pNode == nullptr) ? "no" : "yes") << endl;
pNode = sortTree.find(31);
cout << "is there 31: " << ((pNode == nullptr) ? "no" : "yes") << endl;
sortTree.deleteNode(28);
cout << "after deleting 28, the tree is: " << endl;
sortTree.print();
sortTree.deleteNode(31);
cout << "after deleting 31, the tree is: " << endl;
sortTree.print();
sortTree.deleteSubTree(45);
cout << "after deleting subtree 45, the tree is: " << endl;
sortTree.print();
sortTree.deleteNode(32);
cout << "after deleting root 35, the tree is: " << endl;
sortTree.print();
sortTree.deleteSubTree(16);
cout << "after deleting subtree root 16, the tree is: " << endl;
cout << (sortTree.isEmpty() ? "empty" : "has elem") << endl;
return 0;
}
测试结果