前中后序递归 + 非递归 + 二叉树搜索树
#ifndef BINARYTREE_H
#define BINARYTREE_H
#include <iostream>
#include <functional>
#include <queue>
#include <stack>
namespace BinaryTree
{
template<typename T>
struct _SBinaryTreeItem
{
T _value;
struct _SBinaryTreeItem* _right_tree { nullptr };
struct _SBinaryTreeItem* _left_tree { nullptr };
_SBinaryTreeItem(T _val = T()) : _value(_val)
{
}
static _SBinaryTreeItem* create(T _val)
{
return new _SBinaryTreeItem(_val);
}
};
template<typename T>
class TraversalTool
{
using BinaryTreePointer = _SBinaryTreeItem<T>*;
using BinaryTreePointerPair = std::pair< BinaryTreePointer, BinaryTreePointer>;
using BinaryTreeCallBack = std::function<void(BinaryTreePointer)>;
using BinaryTreeCallBacks = std::function<void(BinaryTreePointer, BinaryTreePointer)>;
public:
static void RecursionPreorderTraversal(BinaryTreePointer root, const BinaryTreeCallBack& cb = [](BinaryTreePointer pVal) { std::cout << pVal->_value << std::endl; })
{
if (root == nullptr)
{
return;
}
cb(root);
RecursionPreorderTraversal(root->_left_tree, cb);
RecursionPreorderTraversal(root->_right_tree, cb);
}
static void RecursionInorderTraversal(BinaryTreePointer root, const BinaryTreeCallBack& cb = [](BinaryTreePointer pVal) { std::cout << pVal->_value << std::endl; })
{
if (root == nullptr)
{
return;
}
RecursionInorderTraversal(root->_left_tree, cb);
cb(root);
RecursionInorderTraversal(root->_right_tree, cb);
}
static void RecursionPostorderTraversal(BinaryTreePointer root, const BinaryTreeCallBack& cb = [](BinaryTreePointer pVal) { std::cout << pVal->_value << std::endl; })
{
if (root == nullptr)
{
return;
}
RecursionPostorderTraversal(root->_left_tree, cb);
RecursionPostorderTraversal(root->_right_tree, cb);
cb(root);
}
static void LevelTraversal(BinaryTreePointer root, const BinaryTreeCallBack& cb = [](BinaryTreePointer pVal) { std::cout << pVal->_value << std::endl; })
{
if (root == nullptr)
{
return;
}
std::queue<BinaryTreePointer> _queue;
BinaryTreePointer _temp = nullptr;
_queue.push(root);
while (_queue.size())
{
_temp = _queue.front();
_queue.pop();
if (_temp->_left_tree != nullptr)
{
_queue.push(_temp->_left_tree);
}
if (_temp->_right_tree != nullptr)
{
_queue.push(_temp->_right_tree);
}
cb(_temp);
}
}
static void TraversalCallBack(BinaryTreePointer root, const BinaryTreeCallBacks& cb)
{
if (root == nullptr)
{
return;
}
std::queue<BinaryTreePointerPair> _queue;
BinaryTreePointerPair _temp;
_queue.push(std::make_pair<BinaryTreePointer, BinaryTreePointer>(0, static_cast<BinaryTreePointer&&>(root)));
while (_queue.size())
{
_temp = _queue.front();
_queue.pop();
if (_temp.second->_left_tree != nullptr)
{
_queue.push(std::make_pair(_temp.second, _temp.second->_left_tree));
}
if (_temp.second->_right_tree != nullptr)
{
_queue.push(std::make_pair(_temp.second, _temp.second->_right_tree));
}
cb(_temp.first, _temp.second);
}
}
static void PreOrderTraversal(BinaryTreePointer root, const BinaryTreeCallBack& cb = [](BinaryTreePointer pVal) { std::cout << pVal->_value << std::endl; })
{
if (root == nullptr)
{
return;
}
std::stack<BinaryTreePointer> _stack;
stack.push(root);
BinaryTreePointer pointer = nullptr;
while (_stack.size())
{
pointer = _stack.top();
_stack.pop();
cb(pointer);
if (pointer->_right_tree != nullptr)
{
_stack.push(pointer->_right_tree);
}
if (pointer->_left_tree != nullptr)
{
_stack.push(pointer->_left_tree);
}
}
}
static void InOrderTraversal(BinaryTreePointer root, const BinaryTreeCallBack& cb = [](BinaryTreePointer pVal) { std::cout << pVal->_value << std::endl; })
{
if (root == nullptr)
{
return;
}
std::stack<BinaryTreePointer> _dstack;
BinaryTreePointer pointer = root;
while (_dstack.size() || pointer)
{
if (pointer)
{
_dstack.push(pointer);
pointer = pointer->_left_tree;
}
else
{
pointer = _dstack.top();
cb(pointer);
_dstack.pop();
pointer = pointer->_right_tree;
}
}
}
static void PostOrderTraversal(BinaryTreePointer root, const BinaryTreeCallBack& cb = [](BinaryTreePointer pVal) { std::cout << pVal->_value << std::endl; })
{
if (root == nullptr)
{
return;
}
std::stack<BinaryTreePointer> _dstack;
BinaryTreePointer pointer = root;
BinaryTreePointer flag = nullptr;
while (_dstack.size() || pointer)
{
if (pointer)
{
_dstack.push(pointer);
pointer = pointer->_left_tree;
}
else
{
pointer = _dstack.top();
if (pointer->_right_tree && flag != pointer->_right_tree)
{
pointer = pointer->_right_tree;
}
else
{
_dstack.pop();
cb(pointer);
flag = pointer;
pointer = nullptr;
}
}
}
}
static void FreeBinaryTree(BinaryTreePointer root)
{
LevelTraversal(root, [](BinaryTreePointer pVal) { delete pVal; });
}
};
template<typename T>
class BinaryTree
{
using CMPCall = std::function<bool(const T& f, const T& s)>;
using CMPFind = std::function<bool(const T& f)>;
using BinaryTreePointer = _SBinaryTreeItem<T>*;
using BinaryTreePair = std::pair<BinaryTreePointer, BinaryTreePointer>;
public:
BinaryTree(const std::vector<T>& array, CMPCall compare = [](const T& f, const T& s) { return f < s; })
:_cmp(compare)
{
construct(array);
}
~BinaryTree()
{
destruct(_root);
}
bool insert(const T& _val)
{
if (_root == nullptr)
{
_root = _SBinaryTreeItem<T>::create(_val);
return true;
}
BinaryTreePointer _binaryTree = _root;
BinaryTreePointer _binaryTreeParent = _root;
bool _bool_left = true;
while (_binaryTree)
{
if (_val == _binaryTree->_value)
{
return false;
}
else if(_cmp(_val, _binaryTree->_value))
{
_bool_left = true;
if (_binaryTree->_left_tree == nullptr)
{
break;
}
_binaryTreeParent = _binaryTree;
_binaryTree = _binaryTree->_left_tree;
}
else
{
_bool_left = false;
if (_binaryTree->_right_tree == nullptr)
{
break;
}
_binaryTreeParent = _binaryTree;
_binaryTree = _binaryTree->_right_tree;
}
}
if (_bool_left)
{
_binaryTree->_left_tree = _SBinaryTreeItem<T>::create(_val);
}
else
{
_binaryTree->_right_tree = _SBinaryTreeItem<T>::create(_val);
}
return true;
}
std::vector<BinaryTreePair> match(CMPFind _condition)
{
std::vector<BinaryTreePair> _vect;
TraversalTool<T>::TraversalCallBack(_root, [&_vect, &_condition](BinaryTreePointer _parent, BinaryTreePointer _sub) { if(_condition(_sub->_value)) _vect.push_back(std::make_pair(_parent, _sub)); });
return _vect;
}
BinaryTreePointer find(const T& _val)
{
BinaryTreePointer ret = nullptr;
if (_root == nullptr)
{
return ret;
}
ret = _root;
while (ret)
{
if (ret->_value == _val)
{
break;
}
else if(ret->_value > _val)
{
ret = ret->_left_tree;
}
else
{
ret = ret->_right_tree;
}
}
return ret;
}
BinaryTreePair find_pair(const T& _val)
{
BinaryTreePointer parent = nullptr;
BinaryTreePointer ret = nullptr;
if (_root == nullptr)
{
return std::make_pair(parent, ret);
}
ret = _root;
while (ret)
{
if (ret->_value == _val)
{
return std::make_pair(parent, ret);
}
else if (ret->_value > _val)
{
parent = ret;
ret = ret->_left_tree;
}
else
{
parent = ret;
ret = ret->_right_tree;
}
}
return std::make_pair<BinaryTreePointer, BinaryTreePointer>(nullptr, nullptr);
}
bool erase(const T& _val)
{
return _erases(find_pair(_val));
}
bool erases(CMPFind erase_con)
{
std::vector<BinaryTreePair> matched = match(erase_con);
for (int _i = 0; _i < matched.size(); ++_i)
{
erase(matched[_i].second->_value);
}
return true;
}
operator BinaryTreePointer ()
{
return _root;
}
protected:
void construct(const std::vector<T>& array)
{
for (int _i = 0; _i < array.size(); ++_i)
{
insert(array[_i]);
}
}
static void destruct(BinaryTreePointer root)
{
TraversalTool<T>::FreeBinaryTree(root);
}
bool _erases(const BinaryTreePair& pair)
{
BinaryTreePair matched = pair;
BinaryTreePointer _will_erase_pointer = nullptr;
//
if (matched.second == nullptr)
{
return false;
}
else
{
BinaryTreePointer _erase_pointer = matched.second;
BinaryTreePointer _erase_pointer_parent = matched.first;
bool _left_pointer = _erase_pointer_parent ? _erase_pointer_parent->_left_tree == _erase_pointer : _root->_left_tree == _erase_pointer;
if (_erase_pointer->_left_tree == nullptr && _erase_pointer->_right_tree == nullptr)
{
_will_erase_pointer = _erase_pointer;
if (_erase_pointer_parent != nullptr)
{
if (_left_pointer)
{
_erase_pointer_parent->_left_tree = nullptr;
}
else
{
_erase_pointer_parent->_right_tree = nullptr;
}
}
else
{
_root = nullptr;
}
}
else if (_erase_pointer->_left_tree != nullptr && _erase_pointer->_right_tree == nullptr)
{
if (_erase_pointer_parent)
{
if (_left_pointer)
{
_erase_pointer_parent->_left_tree = _erase_pointer->_left_tree;
}
else
{
_erase_pointer_parent->_right_tree = _erase_pointer->_left_tree;
}
}
else
{
_root = _erase_pointer->_left_tree;
}
_will_erase_pointer = _erase_pointer;
}
else if (_erase_pointer->_left_tree == nullptr && _erase_pointer->_right_tree != nullptr)
{
if (_erase_pointer_parent)
{
if (_left_pointer)
{
_erase_pointer_parent->_left_tree = _erase_pointer->_right_tree;
}
else
{
_erase_pointer_parent->_right_tree = _erase_pointer->_right_tree;
}
}
else
{
_root = _erase_pointer->_right_tree;
}
_will_erase_pointer = _erase_pointer;
}
else
{
BinaryTreePointer _erase_pointer_temp_parent = _erase_pointer;
BinaryTreePointer _erase_pointer_temp = _erase_pointer->_left_tree;
// 需要找被删除的节点的左子树上最大的节点 或 被删除的节点的右边子树上最小的节点
while (_erase_pointer_temp && _erase_pointer_temp->_right_tree)
{
_erase_pointer_temp_parent = _erase_pointer_temp;
_erase_pointer_temp = _erase_pointer_temp->_right_tree;
}
if (_erase_pointer_temp_parent == _erase_pointer)
{
_erase_pointer_temp->_right_tree = _erase_pointer_temp_parent->_right_tree;
}
else
{
_erase_pointer_temp_parent->_right_tree = _erase_pointer_temp->_left_tree;
_erase_pointer_temp->_left_tree = _erase_pointer->_left_tree;
_erase_pointer_temp->_right_tree = _erase_pointer->_right_tree;
}
if (_erase_pointer_parent != nullptr)
{
if (_left_pointer)
{
_erase_pointer_parent->_left_tree = _erase_pointer_temp;
}
else
{
_erase_pointer_parent->_right_tree = _erase_pointer_temp;
}
}
else
{
_root = _erase_pointer_temp;
}
_will_erase_pointer = _erase_pointer;
}
}
_will_erase_pointer->_left_tree = nullptr;
_will_erase_pointer->_right_tree = nullptr;
TraversalTool<T>::FreeBinaryTree(_will_erase_pointer);
}
private:
BinaryTreePointer _root{ nullptr };
CMPCall _cmp;
};
}
#endif // !BINARYTREE_H
案例
#include "BinaryTree.h"
int main(int argc, char** argv)
{
BinaryTree::BinaryTree<int> sort(std::vector<int>{5, 3, 2, 4, 10, 9, 17, 6, 18});
auto vect = sort.match([](int f) { return f < 7; });
auto vectp = sort.find_pair(90);
sort.erases([](int f) { return f < 10; });
BinaryTree::TraversalTool<int>::LevelTraversal(sort);
return 0;
}