C++数据结构——二叉树之一普通二叉树

本次实现为平衡二叉树做基础,如有问题,欢迎指出!

编译环境:GCC 7.3、vs 2005

该普通二叉树的功能有:

1. 新增结点。

2. 删除结点。具体思路:

①当被删除结点的左子树深度大于右子树时,将被删除结点 与 左子树中序遍历顺序的最后的结点 交换数据,然后以被交换的结点作为被删除的结点,继续执行删除操作,直到被交换的结点是叶子结点时,直接删除该叶子结点。

②当被删除结点的左子树深度不小于右子树时,将被删除结点 与 右子树中序遍历顺序的最前的结点 交换数据,然后以被交换的结点作为被删除的结点,继续执行删除操作,直到被交换的结点是叶子结点时,直接删除该叶子结点。

③当被删除结点没有孩子结点时,即被删除的结点是叶子结点时,直接删除该结点。

3. 前、中、后序遍历树。

4. 反向的前、中、后序遍历树。

5. 以某个结点为锚点进行左旋转和右旋转。

#ifndef __BTREE_H__
#define __BTREE_H__

#if __cplusplus >= 201103L
#include <type_traits> // std::forward、std::move
#endif

#if __cplusplus >= 201103L
#define null nullptr
#else
#define null NULL
#endif

template<typename __Type>
static void swap(__Type &a, __Type &b)
{
    __Type tmp = a;
    a = b;
    b = tmp;
}

// 二叉树结点
template<typename _Tp>
struct BTreeNode
{
    typedef BTreeNode     self;
    typedef _Tp           value_type;
    typedef _Tp *         pointer;
    typedef _Tp &         reference;
    typedef unsigned long size_type;
    typedef unsigned long color_type;

    // 前置保证v不为空,前置保证v为堆空间对象
    BTreeNode(pointer v, self *left = null, self *right = null, self *parent = null)
     : _M_value(v), _M_left(left), _M_right(right), _M_parent(parent), _M_child_size(0), _M_depth(1), _M_color(0)
    {
        if(null != left)
        {
            _M_child_size += left->child_size() + 1;
            _M_depth += left->depth();
            left->_M_parent = this;
        }
        if(null != right)
        {
            _M_child_size += right->child_size() + 1;
            _M_depth = _M_depth > right->depth() ? _M_depth : right->depth();
            right->_M_parent = this;
        }
    }

    // 前置保证node不为空,复制结点
    BTreeNode(self *node, self *parent = null)
     : _M_value(null), _M_left(null), _M_right(null), _M_parent(parent), _M_child_size(0), _M_depth(1), _M_color(0)
    {
        _M_child_size = node->child_size();
        _M_depth = node->depth();
        _M_value = new value_type(*node->value());

        if(null != node->left_child())
        { _M_left = new BTreeNode(node->left_child(), this); }
        if(null != node->right_child())
        { _M_right = new BTreeNode(node->right_child(), this); }
    }

    ~BTreeNode()
    {
        delete _M_value;
        if(null != _M_left)
        { delete _M_left; }
        if(null != _M_right)
        { delete _M_right; }
    }

    void add_child_number(size_type size)
    {
        BTreeNode *node = this;
        while(null != node)
        {
            node->_M_child_size += size;
            node = node->_M_parent;
        }
    }

    void update_size()
    {
        BTreeNode *node = this;
        while(null != node)
        {
            node->_M_child_size = 0;
            node->_M_depth = 1;
            if(null != node->_M_left)
            {
                node->_M_depth = node->_M_left->_M_depth + 1;
                node->_M_child_size += node->_M_left->child_size() + 1;
            }
            if(null != node->_M_right)
            {
                node->_M_child_size += node->_M_right->child_size() + 1;
                size_type tmp = node->_M_right->_M_depth + 1;
                node->_M_depth = tmp > node->_M_depth ? tmp : node->_M_depth;
            }
            node = node->_M_parent;
        }
    }

    self* append_node(self *node)
    {
        if(null != node)
        { node->_M_parent = this; }
        update_size();
        return node;
    }

    self* set_left(self *left)
    {
        _M_child_size -= null == _M_left ? 0 : (_M_left->child_size() + 1);
        return append_node(_M_left = left);
    }

    self* set_right(self *right)
    {
        _M_child_size -= null == _M_right ? 0 : (_M_right->child_size() + 1);
        return append_node(_M_right = right);
    }

    size_type child_size() const
    { return _M_child_size; }

    size_type depth() const
    { return _M_depth; }

    pointer value()
    { return _M_value; }

    const pointer value() const
    { return _M_value; }

    self* left_child()
    { return _M_left; }

    const self* left_child() const
    { return _M_left; }

    self* right_child()
    { return _M_right; }

    const self* right_child() const
    { return _M_right; }

    self* parent()
    { return _M_parent; }

    const self* parent() const
    { return _M_parent; }

    void swap(BTreeNode *node)
    { ::swap<pointer>(node->_M_value, _M_value); }

    color_type color() const 
    { return _M_color; }

    pointer _M_value;
    self *_M_left;
    self *_M_right;
    self *_M_parent;
    size_type _M_child_size;
    size_type _M_depth;// 深度,包括自己
    color_type _M_color;
};

// 普通二叉树
template<typename _Tp, typename _Node = BTreeNode<_Tp>>
class BinaryTree
{
public:
    typedef _Tp           value_type;
    typedef _Tp &         reference;
    typedef const _Tp &   const_reference;
    typedef unsigned long size_type;
    typedef _Node         node_type;

#if __cplusplus >= 201103L
    typedef _Tp &&        rvalue_reference;
#endif

public:
    BinaryTree()
     : _M_root(null) { }

    BinaryTree(const BinaryTree &bt)
     : _M_root(null)
    { operator=(bt); }

#if __cplusplus >= 201103L
    BinaryTree(BinaryTree &&bt)
     : _M_root(null)
    { swap(bt._M_root, _M_root); }
#endif

    ~BinaryTree()
    { clear(); }

    void swap(BinaryTree &bt)
    { ::swap<node_type*>(bt._M_root, _M_root); }

    size_type size() const
    { return null == _M_root ? 0 : (_M_root->child_size() + 1); }

    size_type depth() const
    { return null == _M_root ? 0 : _M_root->depth(); }

    BinaryTree& operator=(const BinaryTree &bt)
    {
        clear();
        if(null != bt._M_root)
        { _M_root = new node_type(bt._M_root); }
        return *this;
    }

    void clear()
    {
        if(null != _M_root)
        { delete _M_root; }
    }

    node_type* root()
    { return _M_root; }

    const node_type* root() const
    { return _M_root; }

    // 结点拼接
#if __cplusplus < 201103L
    node_type* append_root(const_reference value)
    { return _M_root = new node_type(new value_type(value), _M_root); }

    node_type* append_left(node_type *node, const_reference chlid_value)
    { return node->set_left(new node_type(new value_type(chlid_value), node->left_child(), null)); }

    node_type* append_right(node_type *node, const_reference child_value)
    { return node->set_right(new node_type(new value_type(child_value), null, node->right_child())); }

#else
    template<typename ... Args>
    node_type* append_root(Args && ... args)
    { return _M_root = new node_type(new value_type(std::forward<Args>(args)...), _M_root); }

    template<typename ... Args>
    node_type* append_left(node_type *node, Args && ... args)
    { return node->set_left(new node_type(new value_type(std::forward<Args>(args)...), node->left_child(), null)); }

    template<typename ... Args>
    node_type* append_right(node_type *node, Args && ... args)
    { return node->set_right(new node_type(new value_type(std::forward<Args>(args)...), null, node->right_child())); }
#endif

    /* 需要移除的结点
     * 1. 如果node的左子树深度 大于 右子树深度,则返回node的左子树最右边的叶子结点
     * 2. 如果node的左子树深度 小于 右子树深度,则返回node的右子树最左边的结点
     * 3. 如果node的左右子树深度一样,则直接删除
     * @return  返回被删除的叶子结点的父结点
     */
    node_type* erase(node_type *node)
    {
        node = get_erase_replace(node);
        if(null != node)
        { return erase_leaf(node); }
        return null;
    }

    // 删除叶子结点,返回父结点
    node_type* erase_leaf(node_type *node)
    {
        node_type *parent = node->parent();
        if(null == parent)
        { _M_root = null; }
        else if(parent->left_child() == node)
        { parent->set_left(null); }
        else
        { parent->set_right(null); }
        delete node;
        return parent;
    }

    /* 获取被删除结点的替换结点
     * @node  需要删除的结点
     * @flag  没有替换结点——0,替换结点位于左子树——1,替换结点位于右子树——2
     * @return  被用于删除的替换结点
     */ 
    node_type* get_erase_replace(node_type *node);

    node_type* get_erase_reserve(node_type *node);

public:
    node_type* right_rotate(node_type *node);// 以node为中心,进行右转操作
    node_type* left_rotate(node_type *node);// 以node为中心,进行左转操作
    static node_type* left_child_under(node_type *node);// 最左边的结点
    static node_type* right_child_under(node_type *node);// 最右边的结点
    static node_type* left_leaves(node_type *node);// 最左边的叶子结点
    static node_type* right_leaves(node_type *node);// 最右边的叶子结点
    static node_type* former_next(node_type *node);// 获取前序遍历的下一个结点
    static node_type* middle_next(node_type *node);// 获取中序遍历的下一个结点
    static node_type* after_next(node_type *node);// 获取后续遍历的下一个结点
    static node_type* former_previous(node_type *node);// 获取前序遍历的上一个结点
    static node_type* middle_previous(node_type *node);// 获取中序遍历的上一个结点
    static node_type* after_previous(node_type *node);// 获取后续遍历的上一个结点

private:
    node_type *_M_root;
};

//---------------------***************---------------------//
//---------------------***************---------------------//
//---------------------***************---------------------//

template<typename _Tp, typename _Node>
typename BinaryTree<_Tp, _Node>::node_type*
    BinaryTree<_Tp, _Node>::right_rotate(node_type *node)
{
    if(null == node || null == node->left_child())
    { return null; }

    node_type *left_node = node->left_child();
    node_type *original_parent = node->parent();
    node_type *left_node_right_child = left_node->right_child();
    if(null != original_parent)
    {
        if(original_parent->right_child() == node)
        { original_parent->_M_right = left_node; }
        else
        { original_parent->_M_left = left_node; }
    }

    node->_M_parent = null;
    left_node->_M_parent = null;

    size_type left_node_right_child_size = left_node_right_child == null ? 0 : (left_node_right_child->child_size() + 1);

    node->add_child_number(- (left_node->child_size() + 1));
    node->add_child_number(left_node_right_child_size);

    left_node->add_child_number(-left_node_right_child_size);
    left_node->add_child_number(node->child_size() + 1);

    node->_M_parent = left_node;
    node->_M_left = left_node_right_child;
    left_node->_M_right = node;
    left_node->_M_parent = original_parent;
    if(left_node_right_child != null)
    { left_node_right_child->_M_parent = node; }

    if(node == root())
    { _M_root = left_node; }

    node->update_size();
    return left_node;
}

template<typename _Tp, typename _Node>
typename BinaryTree<_Tp, _Node>::node_type*
    BinaryTree<_Tp, _Node>::left_rotate(node_type *node)
{
    if(null == node || null == node->right_child())
    { return null; }

    node_type *right_node = node->right_child();
    node_type *original_parent = node->parent();
    node_type *right_node_left_child = null == right_node ? null : right_node->left_child();

    if(null != original_parent)
    {
        if(original_parent->right_child() == node)
        { original_parent->_M_right = right_node; }
        else
        { original_parent->_M_left = right_node; }
    }
    node->_M_parent = null;
    right_node->_M_parent = null;

    size_type left_node_right_child_size = right_node_left_child == null ? 0 : (right_node_left_child->child_size() + 1);

    node->add_child_number(- (right_node->child_size() + 1));
    node->add_child_number(left_node_right_child_size);

    right_node->add_child_number(-left_node_right_child_size);
    right_node->add_child_number(node->child_size() + 1);

    node->_M_parent = right_node;
    node->_M_right = right_node_left_child;
    right_node->_M_left = node;
    right_node->_M_parent = original_parent;
    if(right_node_left_child != null)
    { right_node_left_child->_M_parent = node; }

    if(node == root())
    { _M_root = right_node; }

    node->update_size();
    return right_node;
}

//-----------------------------------------------------------//
//----------------------静态方法类外实现----------------------//
//-----------------------------------------------------------//

template<typename _Tp, typename _Node>
typename BinaryTree<_Tp, _Node>::node_type*
    BinaryTree<_Tp, _Node>::left_child_under(node_type *node)
{
    while(null != node && null != node->left_child())
    { node = node->left_child(); }
    return node;
}

template<typename _Tp, typename _Node>
typename BinaryTree<_Tp, _Node>::node_type*
    BinaryTree<_Tp, _Node>::right_child_under(node_type *node)
{
    while(null != node && null != node->right_child())
    { node = node->right_child(); }
    return node;
}

template<typename _Tp, typename _Node>
typename BinaryTree<_Tp, _Node>::node_type*
    BinaryTree<_Tp, _Node>::left_leaves(node_type *node)
{
    node = left_child_under(node);
    while(null != node && null != node->right_child())
    { node = left_child_under(node->right_child()); }
    return node;
}

template<typename _Tp, typename _Node>
typename BinaryTree<_Tp, _Node>::node_type*
    BinaryTree<_Tp, _Node>::right_leaves(node_type *node)
{
    node = right_child_under(node);
    while(null != node && null != node->left_child())
    { node = right_child_under(node->left_child()); }
    return node;
}

template<typename _Tp, typename _Node>
typename BinaryTree<_Tp, _Node>::node_type*
    BinaryTree<_Tp, _Node>::former_next(node_type *node)
{
    if(null == node)
    { return null; }

    if(null != node->left_child())
    { return node->left_child(); }

    if(null != node->right_child())
    { return node->right_child(); }

    node_type *temp = node;
    node = node->parent();
    while(null != node && (node->right_child() == temp || null == node->right_child()))
    {
        temp = node;
        node = node->parent();
    }

    if(null == node)
    { return null; }

    return node->right_child();
}

template<typename _Tp, typename _Node>
typename BinaryTree<_Tp, _Node>::node_type*
    BinaryTree<_Tp, _Node>::middle_next(node_type *node)
{
    if(null == node)
    { return null; }

    if(null != node->right_child())
    { return left_child_under(node->right_child()); }

    if(node != node->parent()->right_child())
    { return node->parent(); }

    node_type *temp = node;
    node = node->parent();
    while(null != node && node->right_child() == temp)
    {
        temp = node;
        node = node->parent();
    }
    return node;
}

template<typename _Tp, typename _Node>
typename BinaryTree<_Tp, _Node>::node_type*
    BinaryTree<_Tp, _Node>::after_next(node_type *node)
{
    if(null == node || null == node->parent())
    { return null; }

    if(node == node->parent()->left_child())
    {
        if(null == node->parent()->right_child())
        { return node->parent(); }

        return left_leaves(node->parent()->right_child());
    }

    if(node == node->parent()->right_child())
    { return node->parent(); }
    return null;
}

template<typename _Tp, typename _Node>
typename BinaryTree<_Tp, _Node>::node_type*
    BinaryTree<_Tp, _Node>::former_previous(node_type *node)
{
    if(null == node || null == node->parent())
    { return null; }

    if(node == node->parent()->left_child())
    { return node->parent(); }

    if(node == node->parent()->right_child())
    {
        node = node->parent();
        if(null != node->left_child())
        { return right_leaves(node->left_child()); }
        return node;
    }
    return null;
}

template<typename _Tp, typename _Node>
typename BinaryTree<_Tp, _Node>::node_type*
    BinaryTree<_Tp, _Node>::middle_previous(node_type *node)
{
    if(null == node)
    { return null; }

    if(null != node->left_child())
    { return right_child_under(node->left_child()); }

    if(null == node->parent())
    { return null; }

    if(node == node->parent()->right_child())
    { return node->parent(); }

    while(null != node && null != node->parent() && node == node->parent()->left_child())
    { node = node->parent(); }

    return node->parent();
}

template<typename _Tp, typename _Node>
typename BinaryTree<_Tp, _Node>::node_type*
    BinaryTree<_Tp, _Node>::after_previous(node_type *node)
{
    if(null == node)
    { return null; }

    if(null != node->right_child())
    { return node->right_child(); }

    if(null != node->left_child())
    { return node->left_child(); }

    if(null == node->parent())
    { return null; }

    if(node->parent()->right_child() == node)
    {
        node = node->parent();
        while(null != node && null == node->left_child())
        { node = node->parent(); }
    }
    else
    {
        while(null != node && node->parent()->left_child() == node)
        {
            node = node->parent();
            if(null == node->parent())
            { return null; }
        }
    }

    return null == node ? null : node->left_child();
}

//---------------------***************---------------------//
//---------------------***************---------------------//
//---------------------***************---------------------//
template<typename _Tp, typename _Node>
typename BinaryTree<_Tp, _Node>::node_type*
    BinaryTree<_Tp, _Node>::get_erase_reserve(node_type *node)
{
    node_type *left = null;
    node_type *right = null;

    size_type left_depth = 0;// 左子树深度
    size_type right_depth = 0;// 右子树深度

    left = node->left_child();
    right = node->right_child();

    left_depth = null == left ? 0 : left->depth();
    right_depth = null == right ? 0 : right->depth();

    if(right_depth == 0 && left_depth == 0)
    { return node; }
    if(right_depth > left_depth)
    { return left_child_under(right); }
    else
    { return right_child_under(left); }
}

template<typename _Tp, typename _Node>
typename BinaryTree<_Tp, _Node>::node_type*
    BinaryTree<_Tp, _Node>::get_erase_replace(node_type *node)
{
    while(null != node)
    {
        node_type *reserve = get_erase_reserve(node);// 需要保留数据的结点
        if(null == reserve->left_child() && null == reserve->right_child())
        { return reserve; }
        node->swap(reserve);
        node = reserve;
    }
    return null;
}

#endif // __BTREE_H__

二叉树的基本功能已完成,下面是测试代码:

#include <iostream>
#include <list>
#include "btree.h"

#if __cplusplus < 201103L
#include <sstream>
#endif

#define MAX_NUMBER_BIT 5

static std::string get_string(int v)
{ 
#if __cplusplus < 201103L
	std::stringstream ss;
	ss << v;
	std::string tmp = ss.str();
#else
	std::string tmp = std::to_string(v);
#endif
	std::string result = "";
	for(std::size_t i = 0; i < (MAX_NUMBER_BIT - tmp.size()) / 2; ++i)
	{ result += ' '; }
	result += tmp;
	for(std::size_t i = 0; i < (MAX_NUMBER_BIT - tmp.size()) / 2; ++i)
	{ result += ' '; }
	return result; 
}

struct T
{
	T(int v = 0) : value(v) { }

	void print()
	{ std::cout << get_string(value); }

	int value;
};

typedef BinaryTree<T> TestTree;
typedef TestTree::node_type NodeType;

void print_tree(const TestTree &tree)
{
	std::list<const NodeType*> s;
	s.push_back(tree.root());
	bool break_flag = false;
	while(!break_flag)
	{
		break_flag = true;
		std::size_t count = s.size();
		int print_count = 0;
		while(count-- > 0)
		{
			const NodeType *t = s.front();
			s.pop_front();
			if(null == t)
			{ 
				T().print();
				s.push_back(null);
				s.push_back(null); 
			}
			else 
			{ 
				t->value()->print(); 
				s.push_back(t->left_child());
				s.push_back(t->right_child());
				break_flag = false;
			}
			if(++print_count % 2 == 0)
			{ std::cout << "|"; }
		}
		std::cout << std::endl;
	}
}
// 前序遍历树
void print_tree_former(TestTree &tree)
{
	NodeType *node = tree.root();
	while(null != node)
	{
		std::cout << node->value()->value << " ";
		node = tree.former_next(node);
	}
	std::cout << std::endl;
}
// 中序遍历树
void print_tree_middle(TestTree &tree)
{
	NodeType *node = tree.left_child_under(tree.root());
	while(null != node)
	{
		std::cout << node->value()->value << " ";
		node = tree.middle_next(node);
	}
	std::cout << std::endl;
}
// 后序遍历树
void print_tree_after(TestTree &tree)
{
	NodeType *node = tree.left_leaves(tree.root());
	while(null != node)
	{
		std::cout << node->value()->value << " ";
		node = tree.after_next(node);
	}
	std::cout << std::endl;
}
// 反序的前序遍历
void print_tree_former_reverse(TestTree &tree)
{
	NodeType *node = tree.right_leaves(tree.root());
	while(null != node)
	{
		std::cout << node->value()->value << " ";
		node = tree.former_previous(node);
	}
	std::cout << std::endl;
}
// 反序的中序遍历
void print_tree_middle_reverse(TestTree &tree)
{
	NodeType *node = tree.right_child_under(tree.root());
	while(null != node)
	{
		std::cout << node->value()->value << " ";
		node = tree.middle_previous(node);
	}
	std::cout << std::endl;
}
// 反序的后序遍历
void print_tree_after_reverse(TestTree &tree)
{
	NodeType *node = tree.root();
	while(null != node)
	{
		std::cout << node->value()->value << " ";
		node = tree.after_previous(node);
	}
	std::cout << std::endl;
}

void main_func()
{
	TestTree bt;
	NodeType *node = bt.append_root(T(1));
	NodeType *node1 = bt.append_left(node, T(100));
	NodeType *node2 = bt.append_right(node, T(20));
	bt.append_left(node1, T(400));
	bt.append_left(node1, T(2));
	bt.append_right(node2, T(5));

	std::cout << "------------------tree node-------------------" << std::endl;
	print_tree(bt);

	std::cout << "-----------------former visit------------------" << std::endl;
	print_tree_former(bt);
	std::cout << "-----------------middle visit------------------" << std::endl;
	print_tree_middle(bt);
	std::cout << "-----------------after visit------------------" << std::endl;
	print_tree_after(bt);
	std::cout << "-----------------reverse former visit------------------" << std::endl;
	print_tree_former_reverse(bt);
	std::cout << "-----------------reverse middle visit------------------" << std::endl;
	print_tree_middle_reverse(bt);
	std::cout << "-----------------reverse after visit------------------" << std::endl;
	print_tree_after_reverse(bt);
	
	std::cout << "------------------tree copy-------------------" << std::endl;
	TestTree bt0(bt);
	print_tree(bt0);
	std::cout << "copy total size: " << bt0.size() << std::endl;
	std::cout << "copy tree depth: " << bt0.depth() << std::endl;

	std::cout << "------------------erase node-------------------" << std::endl;
	bt.erase(node2);
	print_tree(bt);
	bt.erase(node);
	print_tree(bt);

	std::cout << "total size: " << bt.size() << std::endl;
	std::cout << "tree depth: " << bt.depth() << std::endl;

	std::cout << "------------------right rotate-------------------" << std::endl;
	NodeType *node01 = bt0.root();
	NodeType *node02 = node01->left_child();
	NodeType *node03 = node02->left_child();
	bt0.right_rotate(node03);
	print_tree(bt0);
	std::cout << "------------------left rotate-------------------" << std::endl;
	bt0.left_rotate(node01->right_child());
	print_tree(bt0);
	std::cout << "copy total size: " << bt0.size() << std::endl;
	std::cout << "copy tree depth: " << bt0.depth() << std::endl;

}

int main() 
{
    main_func();
    system("pause");
    return 0;
}

运行结果如下:

发布了19 篇原创文章 · 获赞 1 · 访问量 2775

猜你喜欢

转载自blog.csdn.net/qq811299838/article/details/104038745