Binary Search Tree

BST
#ifndef BINARYTREE_H
#define BINARYTREE_H
//---------------------------------------------------------------------------
//
// BinaryTree.h
//---------------------------------------------------------------------------

#include <vector>
#include <list>
#include <type_traits>
#include <queue>
#include <map>//it use return node array location
#define  TEST_NODE 1

template <typename T>
struct BSTNode{
	using height_value_type = long;
	using value_type = T;
	using const_value_type_refrence = const T&;
	using node_type_ptr = BSTNode<T>*;
	
	BSTNode(const value_type& data = value_type()) :_data(data),_height(1), _left(nullptr), _right(nullptr),_parent(nullptr) {}
	node_type_ptr& getNodeChildRight() { return _right; }
	node_type_ptr& getNodeChildLeft() { return _left; }
	node_type_ptr& getNodeParent() { return _parent; }
	height_value_type& getNodeHeight() { return _height; }
	value_type& getNodeData() { return _data; }
private:
	value_type _data;
	height_value_type _height;
	node_type_ptr _left;
	node_type_ptr _right;
	node_type_ptr _parent;
};

template<typename T>
class BSTree {
	using value_type = T;
	using reference_value_type = T&;
	using const_value_type = const T&;
	using node_type = BSTNode<T>;
	using node_type_ptr = BSTNode<T>*;
	using const_node_type_ptr = const BSTNode<T>*;

	node_type_ptr m_root = nullptr;
public:
	virtual ~BSTree() { removeReserve(getRoot()->getNodeData(), getRoot()); }
	node_type_ptr& getRoot() { return m_root; }
	void create(const std::vector<value_type>& _vec) {
		for (auto it:_vec) {
			insert(it, getRoot());
		}
	}
	virtual void insert(const_value_type _t, node_type_ptr& _parent) {
		if (_parent==nullptr){
			_parent= new node_type(_t);
			
		}
		else if (_t < _parent->getNodeData()) {
			insert(_t, _parent->getNodeChildLeft());
			_parent->getNodeChildLeft()->getNodeParent() = _parent;
			
		}
		else if(_t > _parent->getNodeData()){
			insert(_t, _parent->getNodeChildRight());
			_parent->getNodeChildRight()->getNodeParent() = _parent;
		}

		
	}
	

	virtual void remove(const_value_type _t, node_type_ptr& _node ) {
		/*
		* delete one node 
		*/

		if (_node == nullptr)return;
		node_type_ptr target_node = nullptr;
		find(_t, _node,target_node);
		if (target_node == nullptr)return;
		auto degree = getDegree(target_node);



		if (target_node->getNodeChildLeft() && target_node->getNodeChildRight()) {//2 child
			if (degree == 1) {
				//list
				target_node->getNodeParent()->getNodeChildLeft() = target_node->getNodeChildRight();
				node_type_ptr min_node = findMin(target_node->getNodeChildRight());
				min_node->getNodeChildLeft() = target_node->getNodeChildLeft();
				//parent
				target_node->getNodeChildLeft()->getNodeParent() = min_node;
				target_node->getNodeChildRight()->getNodeParent() = target_node->getNodeParent();

			}
			else if (degree == 2) {
				target_node->getNodeParent()->getNodeChildRight() = target_node->getNodeChildLeft();
				node_type_ptr max_node = findMax(target_node->getNodeChildLeft());
				max_node->getNodeChildRight() = target_node->getNodeChildRight();
				//parent
				target_node->getNodeChildRight()->getNodeParent() = max_node;
				target_node->getNodeChildLeft()->getNodeParent() = target_node->getNodeParent();
			}
			
			

		}
		else if ((!target_node->getNodeChildLeft() && !target_node->getNodeChildRight())) {//0 child
			//parent
			if (degree == 1)target_node->getNodeParent()->getNodeChildLeft() = nullptr;
			else if (degree == 2)target_node->getNodeParent()->getNodeChildRight() = nullptr;
			else if (degree == 0 && target_node == getRoot()) {
				getRoot() = nullptr;
			}
		}
		else {//1 child
			node_type_ptr temp = target_node->getNodeChildLeft() ? target_node->getNodeChildLeft() : target_node->getNodeChildRight();
			//parent
			if(temp)temp->getNodeParent() = target_node->getNodeParent();
			if (degree == 1)target_node->getNodeParent()->getNodeChildLeft() = temp;
			else if (degree == 2)target_node->getNodeParent()->getNodeChildRight() = temp;
			else if (degree == 0 && target_node == getRoot()) {
				if (temp)temp->getNodeParent() = nullptr;
				getRoot() = temp;
			}
			else {
				LOGXF("tree have error");
			}

		}

		LOGXD("remove ",target_node->getNodeData());
		delete target_node;
		target_node = nullptr;
		

	}

	void removeReserve(const_value_type _t, node_type_ptr& _node ) {
		//LOGXD("now ", VAR_DATA(_t));
		if (_node == nullptr)return;
		node_type_ptr target_node = nullptr;
		find(_t, getRoot(), target_node);
		if (target_node == nullptr)return;


		if (target_node->getNodeChildLeft() == nullptr && target_node->getNodeChildRight() == nullptr) {//0 child
			//LOGXT("no child", VAR_DATA(_t));
			remove(_t, _node);
		}
		else if (target_node->getNodeChildLeft() && target_node->getNodeChildRight()) {//2 child
			value_type t1 = target_node->getNodeChildLeft()->getNodeData();
			value_type t2 = target_node->getNodeChildRight()->getNodeData();
			//LOGXT("two child", VAR_DATA(_t), VAR_DATA(t1), VAR_DATA(t2));
			removeReserve(t1, _node);
			removeReserve(t2, _node);
			removeReserve(_t, _node);
		}
		else {//1 child
			node_type_ptr temp = target_node->getNodeChildLeft() ?
				target_node->getNodeChildLeft() : target_node->getNodeChildRight();
			value_type t = temp->getNodeData();
			//LOGXT("one child", VAR_DATA(_t), VAR_DATA(t));
			removeReserve(t, _node);
			removeReserve(_t, _node);
		}

	 }

	auto midOrder(node_type_ptr _start) {
		std::list<T> data{};
		if (_start == nullptr)return data;
		auto d1= midOrder(_start->getNodeChildLeft());
		data.insert(data.end(), d1.begin(),d1.end());
		data.emplace_back(_start->getNodeData());
		auto d2 = midOrder(_start->getNodeChildRight());
		data.insert(data.end(), d2.begin(), d2.end());

		return data;
	}

	auto preOrder(node_type_ptr _start) {
		std::list<T> data{};
		if (_start == nullptr)return data;
		data.emplace_back(_start->getNodeData());
		auto d1 = preOrder(_start->getNodeChildLeft());
		data.insert(data.end(), d1.begin(), d1.end());
		auto d2 = preOrder(_start->getNodeChildRight());
		data.insert(data.end(), d2.begin(), d2.end());

		return data;
	}

	void find(const_value_type _t,node_type_ptr _node,node_type_ptr &_result) {
		if (_node == nullptr)return;
		if (_t == _node->getNodeData()) {
			_result = _node;
		}
		else if (_t < _node->getNodeData()) {
			find(_t, _node->getNodeChildLeft(), _result);
		}
		else {
			find(_t, _node->getNodeChildRight(), _result);
		}
	}

	node_type_ptr findMin(node_type_ptr _node) {
		if (_node == nullptr)return nullptr;
		if (_node->getNodeChildLeft() == nullptr)return _node;
		else return findMin(_node->getNodeChildLeft());
	}

	node_type_ptr findMax(node_type_ptr _node) {
		if (_node == nullptr)return nullptr;
		if (_node->getNodeChildRight() == nullptr)return _node;
		else return findMax(_node->getNodeChildRight());
	}

	int getDegree(node_type_ptr _node) {
		/*
		* return 0,_node is not parent,or _node no exist
		* return 1,_node is child left 
		* return 2, _node is child right
		*/
		if (_node == nullptr)return 0;

		if (_node->getNodeParent() == nullptr)return 0;
		else if (_node == getRoot())return 0;
		else if (_node->getNodeParent()->getNodeChildLeft() && _node->getNodeParent()->getNodeChildLeft() == _node)return 1;
		else if (_node->getNodeParent()->getNodeChildRight()&& _node->getNodeParent()->getNodeChildRight() == _node)return 2;
		else return 0;
	}

#if TEST_NODE
	void arrayInfo(node_type_ptr _node, std::map<node_type_ptr, int> & _info) {
		auto degree = getDegree(_node);
		if (_node == nullptr)return;
		if (_node == getRoot())_info[_node] = 1;
		else _info[_node] =degree==1?_info[_node->getNodeParent()]*2:degree==2?_info[_node->getNodeParent()]*2+1:1;
		
		arrayInfo(_node->getNodeChildLeft(), _info);
		arrayInfo(_node->getNodeChildRight(), _info);
		
	}

	std::vector<std::string> arrayInfo(node_type_ptr _node) {
		int array_max_len = 0;

		std::map<node_type_ptr, int> array_info{};
		{
			//array_info = bst.arrayInfo();
			arrayInfo(getRoot(), array_info);

		}


		for (const auto& it : array_info) {
			if (array_max_len < it.second)array_max_len = it.second;
		}

		array_max_len += 1;
		std::vector<std::string> vec_str{};
		vec_str.assign(array_max_len, to_string(0));
		std::stringstream ss;

		for (const auto& it : array_info) {
			ss.str("");
			ss.clear();
			ss << it.first->getNodeData();
			vec_str[it.second] = ss.str();
		}
		

		std::cout << "pre:";
		auto pre = preOrder(getRoot());
		for (const auto& it : pre) {
			std::cout << it << " ";
		}
		
		std::cout << "\nmid:";
		auto mid = midOrder(getRoot());
		for (const auto& it : pre) {
			std::cout << it << " ";
		}
		std::cout << "\n";

		return vec_str;

	}
#endif

};


#endif // BINARYTREE_H
insert
		
		for(int i=0;i<arr_len;i++){
			bst.insert(arr[i], bst.getRoot());
			
			LOGXT(VAR_DATA(arr[i]),(bst.findMax(bst.getRoot()))->getNodeData());
			//display
			auto image = getPainter()->drawTreeArray(bst.arrayInfo(bst.getRoot()), [i](const std::string& _image_data) {
				fstream out_file("e:\\desktop\\t\\1\\" + to_string(i+1) + ".jpg", ios::binary | ios::out);
				out_file.write(_image_data.data(), _image_data.size());
				out_file.close();
				
				});
			emit getPainter()->updataTreeLableSignal();
			//this_thread::sleep_for(1s);
		}

在这里插入图片描述

remove
		//2 delete test
		for(int i=0;i<arr_len;i++){
			bst.remove(arr[i],bst.getRoot());
			auto image = getPainter()->drawTreeArray(bst.arrayInfo(bst.getRoot()), [i](const std::string& _image_data) {
				fstream out_file("e:\\desktop\\t\\1\\" + to_string(20+i+1) + ".jpg", ios::binary | ios::out);
				out_file.write(_image_data.data(), _image_data.size());
				out_file.close();
				});
			emit getPainter()->updataTreeLableSignal();
			//this_thread::sleep_for(1s);
		}

在这里插入图片描述

AVL
#pragma once
#ifndef BBINARYTREE_H
#define BBINARYTREE_H
//---------------------------------------------------------------------------
//
// BBinaryTree.h
//---------------------------------------------------------------------------
#include "BinaryTree.h"

template<typename T>
class BBSTree :public BSTree<T> {
	using value_type = T;
	using reference_value_type = T&;
	using const_value_type = const T&;
	using node_type = BSTNode<T>;
	using node_type_ptr = BSTNode<T>*;
	using const_node_type_ptr = const BSTNode<T>*;
	using height_value_type = long;

public:
	void insert(const_value_type _t, node_type_ptr& _parent) {
		//insert
		if (_parent == nullptr) {
			_parent = new node_type(_t);
			return;//effective good 
		}
		else if (_t < _parent->getNodeData()) {
			insert(_t, _parent->getNodeChildLeft());
			_parent->getNodeChildLeft()->getNodeParent() = _parent;
		}
		else if(_t > _parent->getNodeData()) {
			insert(_t, _parent->getNodeChildRight());
			_parent->getNodeChildRight()->getNodeParent() = _parent;
		}
		else{
			return;
		}
		//balance
		updateNodeHeight(_parent);
		blanceNode(_parent);
		
	}
	void remove(const_value_type _t, node_type_ptr& _node) {
		/*
		* remove self not include child
		*/
		if (_node == nullptr)return;
		if (_t == _node->getNodeData()) {
			if (_node->getNodeParent())LOGXT("find:", VAR_DATA(_t), VAR_DATA(_node->getNodeData()), VAR_DATA(_node->getNodeParent()->getNodeData()));
			else LOGXT("find", VAR_DATA(_t), VAR_DATA(_node->getNodeData()), "parent is null");
			if (_node->getNodeChildRight()  && _node->getNodeChildLeft()) {//have two child
				
				if (height(_node->getNodeChildLeft()) > height(_node->getNodeChildRight())) { 
					auto find_max = findMax(_node->getNodeChildLeft());
					_node->getNodeData() = find_max->getNodeData();
					remove(_t, _node->getNodeChildLeft());
				}
				else {
					node_type_ptr find_min = findMin(_node->getNodeChildRight());
					_node->getNodeData() = find_min->getNodeData();
					remove(_t, _node->getNodeChildRight());
				}

			}
			else if (_node->getNodeChildRight() == nullptr && _node->getNodeChildLeft()==nullptr) {//have 0 child
				node_type_ptr temp = _node;
				_node = nullptr;
				LOGXD("remove ", temp->getNodeData());
				delete temp;
			}
			else{//have one child
				node_type_ptr temp = _node;
				_node = _node->getNodeChildLeft()? _node->getNodeChildLeft(): _node->getNodeChildRight();
				_node->getNodeParent() = _node->getNodeParent()->getNodeParent();
				LOGXD("remove ", temp->getNodeData());
				delete temp;

			}
		}
		else if (_t < _node->getNodeData()) {
			if (_node->getNodeParent())LOGXT("come to left:", VAR_DATA(_t), VAR_DATA(_node->getNodeData()), VAR_DATA(_node->getNodeParent()->getNodeData()));
			else LOGXT("come to left:", VAR_DATA(_t), VAR_DATA(_node->getNodeData()), "parent is null");
			remove(_t, _node->getNodeChildLeft());
		}
		else {
			if (_node->getNodeParent())LOGXT("come to right:", VAR_DATA(_t), VAR_DATA(_node->getNodeData()), VAR_DATA(_node->getNodeParent()->getNodeData()));
			else LOGXT("come to right:", VAR_DATA(_t), VAR_DATA(_node->getNodeData()), "parent is null");
			remove(_t, _node->getNodeChildRight());
		}

		if (_node == nullptr)return;//because _node will change ,is reference
		updateNodeHeight(_node);
		blanceNode( _node);

	}

private:
	height_value_type height(node_type_ptr _node) { if (_node == nullptr)return 0; return _node->getNodeHeight(); }
	void updateNodeHeight(node_type_ptr& _node) {
		//will change node height+=1
		if (_node == nullptr)return;
		_node->getNodeHeight() = std::max(height(_node->getNodeChildLeft()),height(_node->getNodeChildRight()))+1;
	}

	void blanceNode(node_type_ptr& _node) {
		if (_node == nullptr)return;
		auto bf = getNodeBalanceFactor(_node);
		bool first_is_left = getNodeBalanceFactor(_node->getNodeChildRight()) < 0 ? true : false;
		bool second_is_left = getNodeBalanceFactor(_node->getNodeChildLeft()) < 0 ? true : false;

		if (bf > 1) {
			if (/*_t < _node->getNodeChildLeft()->getNodeData()*/first_is_left) {
				LOGXA("ll");
				llRotate(_node);
			}
			else {
				LOGXA("lr");
				lrRotate(_node);
			}
		}
		else if (bf < -1) {
			if (!second_is_left) {
				LOGXA("rr");
				rrRotate(_node);
			}
			else {
				LOGXA("rl");
				rlRotate(_node);
			}
		}
	}
	height_value_type getNodeBalanceFactor(node_type_ptr _node) {
		if (_node == nullptr)return 0;
		return height(_node->getNodeChildLeft()) - height(_node->getNodeChildRight());
	}
	void llRotate(node_type_ptr& _node) {
		//deal list table
		node_type_ptr new_root = _node->getNodeChildLeft();
		_node->getNodeChildLeft() = new_root->getNodeChildRight();
		new_root->getNodeChildRight() = _node;
		//now deal parent
		if (_node->getNodeChildLeft())_node->getNodeChildLeft()->getNodeParent() = _node;
		new_root->getNodeParent() = _node->getNodeParent();
		_node->getNodeParent() = new_root;
		//deal height
		updateNodeHeight(_node);
		updateNodeHeight(new_root);
		_node = new_root;//return  new _node location 

	}
	void rrRotate(node_type_ptr& _node) {
		//deal list table
		node_type_ptr new_root = _node->getNodeChildRight();
		_node->getNodeChildRight() = new_root->getNodeChildLeft();
		new_root->getNodeChildLeft() = _node;
		//now deal parent
		if (_node->getNodeChildRight())_node->getNodeChildRight()->getNodeParent() = _node;
		new_root->getNodeParent() = _node->getNodeParent();
		_node->getNodeParent() = new_root;
		//deal height
		updateNodeHeight(_node);
		updateNodeHeight(new_root);
		_node = new_root;//return  new _node location 
	}
	void lrRotate(node_type_ptr& _node) {
		rrRotate(_node->getNodeChildLeft());
		llRotate(_node);
	}
	void rlRotate(node_type_ptr& _node) {
		llRotate(_node->getNodeChildRight());
		rrRotate(_node);
	}

};




#endif // BBINARYTREE_H
insert

在这里插入图片描述

remove
[19]01:23:20[debg][9760]        [BBSTree<int>::remove]  remove   1   (BBinaryTree.h:68)
pre:4 2 3 5 6
mid:4 2 3 5 6
[20]01:23:20[info][9760]        [PaintTree::drawTreeArray]      depath:  4  image_width:  1000  image_heihet:  700   (PaintTree.cpp:62)
[21]01:23:20[test][9760]        [BBSTree<int>::remove]  come to left:  _t:  2  _node->getNodeData():  4  parent is null   (BBinaryTree.h:82)
[22]01:23:20[test][9760]        [BBSTree<int>::remove]  find:  _t:  2  _node->getNodeData():  2  _node->getNodeParent()->getNodeData():  4   (BBinaryTree.h:49)
[23]01:23:20[debg][9760]        [BBSTree<int>::remove]  remove   2   (BBinaryTree.h:75)
pre:4 3 5 6
mid:4 3 5 6
[24]01:23:20[info][9760]        [PaintTree::drawTreeArray]      depath:  4  image_width:  1000  image_heihet:  700   (PaintTree.cpp:62)
[25]01:23:20[test][9760]        [BBSTree<int>::remove]  come to left:  _t:  3  _node->getNodeData():  4  parent is null   (BBinaryTree.h:82)
[26]01:23:20[test][9760]        [BBSTree<int>::remove]  find:  _t:  3  _node->getNodeData():  3  _node->getNodeParent()->getNodeData():  4   (BBinaryTree.h:49)
[27]01:23:20[debg][9760]        [BBSTree<int>::remove]  remove   3   (BBinaryTree.h:68)
[28]01:23:20[info][9760]        [BBSTree<int>::blanceNode]      rr   (BBinaryTree.h:123)
pre:5 4 6
mid:5 4 6
[29]01:23:20[info][9760]        [PaintTree::drawTreeArray]      depath:  3  image_width:  1000  image_heihet:  700   (PaintTree.cpp:62)
[30]01:23:20[test][9760]        [BBSTree<int>::remove]  come to left:  _t:  4  _node->getNodeData():  5  parent is null   (BBinaryTree.h:82)
[31]01:23:20[test][9760]        [BBSTree<int>::remove]  find:  _t:  4  _node->getNodeData():  4  _node->getNodeParent()->getNodeData():  5   (BBinaryTree.h:49)
[32]01:23:20[debg][9760]        [BBSTree<int>::remove]  remove   4   (BBinaryTree.h:68)
pre:5 6
mid:5 6
[33]01:23:20[info][9760]        [PaintTree::drawTreeArray]      depath:  3  image_width:  1000  image_heihet:  700   (PaintTree.cpp:62)
[34]01:23:20[test][9760]        [BBSTree<int>::remove]  find  _t:  5  _node->getNodeData():  5  parent is null   (BBinaryTree.h:50)
[35]01:23:20[debg][9760]        [BBSTree<int>::remove]  remove   5   (BBinaryTree.h:75)
pre:6
mid:6
[36]01:23:20[info][9760]        [PaintTree::drawTreeArray]      depath:  1  image_width:  1000  image_heihet:  700   (PaintTree.cpp:62)
[37]01:23:20[test][9760]        [BBSTree<int>::remove]  find  _t:  6  _node->getNodeData():  6  parent is null   (BBinaryTree.h:50)
[38]01:23:20[debg][9760]        [BBSTree<int>::remove]  remove   6   (BBinaryTree.h:68)
pre:
mid:
[39]01:23:20[info][9760]        [PaintTree::drawTreeArray]      depath:  -2147483648  image_width:  1000  image_heihet:  700   (PaintTree.cpp:62)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值