几段重要的代码以及讲解
一.findMin和findMax
Node* findMin(Node* t) const
{
if (t == nullptr) return nullptr;
if (t->left == nullptr) return t;
return findMin(t->left);
}
Node* findMax(Node* t) const
{
if (t == nullptr) return nullptr;
if (t->right == nullptr) return t;
return findMax(t->right);
}
二.insert
/*
void insert(E x, Node* t)
{
if (t == nullptr)
t = new Node{ x,nullptr,nullptr };
else if (x < t->data) insert(x, t->left);
else if (x > t->data) insert(x, t->right);
else;
}
*/
void insert(const E &x, Node* &t)
{
if (t == nullptr)
t = new Node{ x,nullptr,nullptr };
else if (x < t->data) insert(x, t->left);
else if (x > t->data) insert(x, t->right);
else;
}
void insert(E&& x,Node*& t)
{
if (t == nullptr)
t = new Node{ std::move(x),nullptr,nullptr };
else if (x < t->data)
insert(std::move(x), t->left);
else if (x > t->data)
insert(std::move(x), t->right);
else;
}
三.remove
//这里一定要用Node *&
void remove(const E& x, Node*& t)
{
if (t == nullptr) return;
if (x < t->data) remove(x, t->left);
else if (x > t->data) remove(x, t->right);
else if (t->left != nullptr && t->right != nullptr) //两个儿子
{
t->data = findMin(t->right)->data; //用右子树的最小值来代替这个要被删除的结点的值
remove(t->data, t->right); //递归的删除用来替代的结点
}
else
{
Node* old = t;
t = (t->left != nullptr) ? t->left : t->right;
delete old;
}
}
/*
void remove(E x, Node* t)
{
if (t == nullptr) return;
if (x < t->data) remove(x, t->left);
else if (x > t->data) remove(x, t->right);
else if (t->left != nullptr && t->right != nullptr) //两个儿子
{
t->data = findMin(t->right)->data; //用右子树的最小值来代替这个要被删除的结点的值
remove(t->data, t->right); //递归的删除用来替代的结点
}
else
{
Node* old = t;
t = (t->left != nullptr) : t->left ? t->right;
delete old;
}
}*/
四.树的遍历(前中后序)
void printTree_Inorder(Node* t) const
{
if (t != nullptr)
{
printTree_Inorder(t->left);
std::cout << t->data << " ";
printTree_Inorder(t->right);
}
}
void printTree_Preorder(Node* t) const
{
if (t != nullptr)
{
std::cout << t->data << " ";
printTree_Preorder(t->left);
printTree_Preorder(t->right);
}
}
void printTree_Postorder(Node* t) const
{
if (t != nullptr)
{
printTree_Postorder(t->left);
printTree_Postorder(t->right);
std::cout << t->data<< " ";
}
}
思想说明
充分利用C++类的特性,所有的public函数只提供接口(即调用private函数),所有的private函数进行实现。
全部实现代码(BinarySearchTree.cpp)
#include<iostream>
/*
public 函数基本只提供接口,所有的实现都在 private 函数里实现
*/
template<typename E>
class BinarySearchTree
{
private:
struct Node
{
E data;
Node* left;
Node* right;
Node(const E& element, Node* lt, Node* rt)
:data{ element }, left{ lt }, right{ rt }
{
}
};
Node* root;
Node* clone(Node* t) const
{
if (t == nullptr) return nullptr;
else return new Node{ t->data,clone(t->left),clone(t->right) };
}
void makeEmpty(Node*& t)
{
if (t != nullptr)
{
makeEmpty(t->left);
makeEmpty(t->right);
delete t;
}
t = nullptr;
}
//这里使用常量引用类型 const E& 避免对x进行修改,同时程序更加高效
//函数为const 避免修改成员函数
bool find(const E& x, Node* t) const
{
/* x=10 */
if (t == nullptr) return false;
else if (x < t->data) return find(x, t->left);
else if (x > t->data) return find(x, t->right);
else return true;
}
Node* findMin(Node* t) const
{
if (t == nullptr) return nullptr;
if (t->left == nullptr) return t;
return findMin(t->left);
}
Node* findMax(Node* t) const
{
if (t == nullptr) return nullptr;
if (t->right == nullptr) return t;
return findMax(t->right);
}
/*
void insert(E x, Node* t)
{
if (t == nullptr)
t = new Node{ x,nullptr,nullptr };
else if (x < t->data) insert(x, t->left);
else if (x > t->data) insert(x, t->right);
else;
}*/
void insert(const E &x, Node* &t)
{
if (t == nullptr)
t = new Node{ x,nullptr,nullptr };
else if (x < t->data) insert(x, t->left);
else if (x > t->data) insert(x, t->right);
else;
}
void insert(E&& x,Node*& t)
{
if (t == nullptr)
t = new Node{ std::move(x),nullptr,nullptr };
else if (x < t->data)
insert(std::move(x), t->left);
else if (x > t->data)
insert(std::move(x), t->right);
else;
}
//这里一定要用Node *&
void remove(const E& x, Node*& t)
{
if (t == nullptr) return;
if (x < t->data) remove(x, t->left);
else if (x > t->data) remove(x, t->right);
else if (t->left != nullptr && t->right != nullptr) //两个儿子
{
t->data = findMin(t->right)->data; //用右子树的最小值来代替这个要被删除的结点的值
remove(t->data, t->right); //递归的删除用来替代的结点
}
else
{
Node* old = t;
t = (t->left != nullptr) ? t->left : t->right;
delete old;
}
}
/*
void remove(E x, Node* t)
{
if (t == nullptr) return;
if (x < t->data) remove(x, t->left);
else if (x > t->data) remove(x, t->right);
else if (t->left != nullptr && t->right != nullptr) //两个儿子
{
t->data = findMin(t->right)->data; //用右子树的最小值来代替这个要被删除的结点的值
remove(t->data, t->right); //递归的删除用来替代的结点
}
else
{
Node* old = t;
t = (t->left != nullptr) : t->left ? t->right;
delete old;
}
}*/
void printTree_Inorder(Node* t) const
{
if (t != nullptr)
{
printTree_Inorder(t->left);
std::cout << t->data << " ";
printTree_Inorder(t->right);
}
}
void printTree_Preorder(Node* t) const
{
if (t != nullptr)
{
std::cout << t->data << " ";
printTree_Preorder(t->left);
printTree_Preorder(t->right);
}
}
void printTree_Postorder(Node* t) const
{
if (t != nullptr)
{
printTree_Postorder(t->left);
printTree_Postorder(t->right);
std::cout << t->data<< " ";
}
}
public:
BinarySearchTree()
:root{nullptr}
{
}
BinarySearchTree(const BinarySearchTree & rhs)
:root{nullptr}
{
root= clone(rhs.root);
}
~BinarySearchTree()
{
makeEmpty(root);
}
E findMinNode() const
{
return findMin(root)->data;
}
E findMaxNode() const
{
return findMax(root)->data;
}
void insert(const E& data)
{
insert(data, root);
}
void remove(const E& data)
{
remove(data, root);
}
bool find(const E& x)
{
return find(x, root);
}
bool isEmpty() const
{
return root == nullptr?true : false;
}
void print(std::string order) const
{
if (order == "in") printTree_Inorder(root);
else if (order == "pre") printTree_Preorder(root);
else if (order == "post") printTree_Postorder(root);
}
};
测试函数(main.cpp)
代码
#include <iostream>
#include "BinarySearchTree.cpp"
int main()
{
BinarySearchTree<int> BST_test;
BST_test.insert(9);
BST_test.insert(4);
BST_test.insert(15);
BST_test.insert(26);
BST_test.insert(11);
BST_test.insert(16);
BST_test.insert(5);
BST_test.insert(7);
BST_test.insert(10);
BST_test.insert(14);
BST_test.insert(19);
BST_test.print("post");
std::cout << std::endl;
BST_test.print("in");
std::cout << std::endl;
BST_test.print("pre");
system("pause");
BST_test.remove(15);
BST_test.print("post");
std::cout << std::endl;
BST_test.print("in");
std::cout << std::endl;
BST_test.print("pre");
system("pause");
std::cout << BST_test.findMinNode() << std::endl;
std::cout << BST_test.findMaxNode() << std::endl;
std::cout << BST_test.isEmpty();
}