Implementation of BinaryTree (binary tree) of data structure

Summarize

  1. remove is not in BinNode, but in BinTree

  2. Two ways of writing recursion
    From top to bottom: recursion of the same object (one more parameter, use one sentence to judge empty), recursion of sub-objects (parameter void, two sentences to judge empty) (because of bifurcation, recursion is true recursion) from bottom to top: no bifurcation, for efficiency, you can use
    loop

// 我的最初写法(递归更新一条路径上的全部节点high值)
template <typename T>
void BinNode<T>::updateHigh(void)
{
    
    
	int oldHigh = high;
	high = std::max(getHigh(left), getHigh(right)) + 1;
	if (parent != NULL && oldHigh != high) parent->updateHigh();
}

// 调用
rt->updateHigh();
// 改良版(循环更新一条路径上的全部节点high值)
template <typename T>
void BinTree<T>::updateHighAbove(BinNode<T> * rt)
{
    
    
	while (rt)
	{
    
    
		if (!rt->updateHigh()) break; //这是书里说的优化,但书中并未实现
		rt = rt->parent;
	}
}
template <typename T>
bool BinNode<T>::updateHigh(void) //返回是否更新了树高
{
    
    
	int oldHigh = high;
	high = std::max(getHigh(left), getHigh(right)) + 1;
	return oldHigh != high;
}
// 调用
updateHighAbove(rt);
  1. The difference between the whole tree and the root node: the type of the whole tree is BinTree and the type of the root node is BinNode. Both have member variables high and size to change the size of the root node, but not to change the size of the entire tree

  2. It is found that high also has the problem of the previous article. In the book, the BinTree is not set to high, and the BinNode has no size, so delete it and update it separately

  3. Why write two removes, because 切断来自parent的指针the 更新高度sum does not need to be performed layer by layer, or to improve efficiency. remove_core is responsible for recursion, and remove is responsible for the outermost layer 切断来自parent的指针and更新高度

code BinNode

# pragma once
# include <algorithm>
# define getHigh(x) x ? x->high : -1

// 仿函数:打印功能
template <typename T>
struct print {
    
    
	void operator ()(T data)
	{
    
    
		std::cout << data << std::endl;
	}
};

template <typename T>
struct BinNode {
    
    

	int high;
	T data;

	BinNode<T> * left;
	BinNode<T> * right;
	BinNode<T> * parent;
	
	int Size(BinNode<T> * x)
	{
    
    
		if (x)
		{
    
    
			return 1 + Size(x->left) + Size(x->right);
		}
		return 0;
	}

	BinNode(T const & d, BinNode<T> * p) : data(d), parent(p), left(NULL), right(NULL), size(1), high(0) {
    
    }

	BinNode<T> * insertAsLeft(T const & val)
	{
    
    
		left = new BinNode<T>(val, this);
		return left;
	}

	BinNode<T> * insertAsRight(T const & val)
	{
    
    
		right = new BinNode<T>(val, this);
		return right;
	}

	bool updateHigh(void)
	{
    
    
		int oldHigh = high;
		high = std::max(getHigh(left), getHigh(right)) + 1;
		return oldHigh != high;
		//if (parent != NULL && oldHigh != high) parent->updateHigh();
	}


	template <typename T2>
	void travPre(T2 visit)
	{
    
    
		visit(data);
		if (left) left->travPre(visit);
		if (right) right->travPre(visit);
	}

	template <typename T2>
	void travIn(T2 visit)
	{
    
    
		if (left) left->travIn(visit);
		visit(data);
		if (right) right->travIn(visit);
	}

	template <typename T2>
	void travPost(T2 visit)
	{
    
    
		if (left) left->travPost(visit);
		if (right) right->travPost(visit);
		visit(data);
	}
};

code BinTree

# pragma once
# include "BinNode.h"

template <typename T>
class BinTree
{
    
    
protected:
public:
	int size;
	BinNode<T> * root;

public:
	BinTree():size(0), root(NULL){
    
    }
	~BinTree() {
    
     if (root) remove(root); }

	//***********************************************************只读*********************************************************

	int Size(void) const {
    
     return size; }
	bool empty(void) const {
    
     return size == 0; }
	BinNode<T> * Root(void) const {
    
     return root; }

	//***********************************************************可写*********************************************************

	// 节点插入
	BinNode<T> * insertAsRoot(T const & e)
	{
    
    
		size = 1;
		root = new BinNode<T>(e, NULL);
		return root;
	}

	BinNode<T> * insertAsLeft(T const & e, BinNode<T> * rt)
	{
    
    
		++size;
		rt->insertAsLeft(e);
		updateHighAbove(rt);
		return rt->left;
	}

	
	BinNode<T> * insertAsRight(T const & e, BinNode<T> * rt)
	{
    
    
		++size;
		rt->insertAsRight(e);
		updateHighAbove(rt);
		return rt->right;
	}

	// 子树接入,返回接入位置rt
	BinNode<T> * attachAsLeft(BinTree<T> * newSubtree, BinNode<T> * rt)
	{
    
    
		size += newSubtree->size;
		rt->left = newSubtree->root;
		updateHighAbove(rt);

		// 清空newSubtree原来的东西
		newSubtree->size = 0;
		newSubtree->root = NULL;
		return rt;
	}

	BinNode<T> * attachAsRight(BinNode<T> * newSubtree, BinNode<T> * rt)
	{
    
    
		size += newSubtree->size;
		rt->right = newSubtree->root;
		updateHighAbove(rt);

		// 清空newSubtree原来的东西
		newSubtree->size = 0;
		newSubtree->root = NULL;
		return rt;
	}

	int remove(BinNode<T> * rt)
	{
    
    
		// 切断来自parent的指针
		fromParentTo(rt) = NULL;

		// 更新高度
		updateHighAbove(rt->parent);

		int ans = remove_core(BinNode<T> * rt);

		size -= ans
		return ans;
	}

	int remove_core(BinNode<T> * rt)
	{
    
    
		if (!rt) return 0; // 递归出口
		int ans = remove(rt->left) + remove(rt->right) + 1;
		delete rt;
		return ans;
	}

	BinTree<T> * secede(BinNode<T> * rt) // 先不考虑 如果rt是树根
	{
    
    
		// 切断来自parent的指针
		fromParentTo(rt) = NULL;

		size -= BinNode<T>::Size(rt);

		BinTree<T> * newTree = new BinTree<T>();
		newTree->root = rt;
		rt->parent = NULL;

		updateHighAbove(rt->parent);
		
		return newTree;
	}

	void updateHighAbove(BinNode<T> * rt)
	{
    
    
		while (rt)
		{
    
    
			if (!rt->updateHigh()) break;
			rt = rt->parent;
		}
	}

	//***********************************************************遍历*********************************************************
	template <typename T2>
	void travPre(T2 visit)
	{
    
    
		if (root) root->travPre(visit);
	}

	template <typename T2>
	void travIn(T2 visit)
	{
    
    
		if (root) root->travIn(visit);
	}

	template <typename T2>
	void travPost(T2 visit)
	{
    
    
		if (root) root->travPost(visit);
	}

private:
	BinNode<T> * & fromParentTo(BinNode<T> * x)
	{
    
    
		if (x == x->parent->left) return x->parent->left;
		else return x->parent->right;
	}
};

おすすめ

転載: blog.csdn.net/weixin_45339670/article/details/131861927