二叉树相关的一些代码

前中后序递归 + 非递归 + 二叉树搜索树

#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;
}

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值