BST
#ifndef BINARYTREE_H
#define BINARYTREE_H
#include <vector>
#include <list>
#include <type_traits>
#include <queue>
#include <map>
#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 ) {
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()) {
if (degree == 1) {
target_node->getNodeParent()->getNodeChildLeft() = target_node->getNodeChildRight();
node_type_ptr min_node = findMin(target_node->getNodeChildRight());
min_node->getNodeChildLeft() = target_node->getNodeChildLeft();
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();
target_node->getNodeChildRight()->getNodeParent() = max_node;
target_node->getNodeChildLeft()->getNodeParent() = target_node->getNodeParent();
}
}
else if ((!target_node->getNodeChildLeft() && !target_node->getNodeChildRight())) {
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 {
node_type_ptr temp = target_node->getNodeChildLeft() ? target_node->getNodeChildLeft() : target_node->getNodeChildRight();
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 ) {
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) {
remove(_t, _node);
}
else if (target_node->getNodeChildLeft() && target_node->getNodeChildRight()) {
value_type t1 = target_node->getNodeChildLeft()->getNodeData();
value_type t2 = target_node->getNodeChildRight()->getNodeData();
removeReserve(t1, _node);
removeReserve(t2, _node);
removeReserve(_t, _node);
}
else {
node_type_ptr temp = target_node->getNodeChildLeft() ?
target_node->getNodeChildLeft() : target_node->getNodeChildRight();
value_type t = temp->getNodeData();
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) {
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{};
{
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
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());
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();
}
remove
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();
}
AVL
#pragma once
#ifndef BBINARYTREE_H
#define 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) {
if (_parent == nullptr) {
_parent = new node_type(_t);
return;
}
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;
}
updateNodeHeight(_parent);
blanceNode(_parent);
}
void remove(const_value_type _t, node_type_ptr& _node) {
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()) {
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) {
node_type_ptr temp = _node;
_node = nullptr;
LOGXD("remove ", temp->getNodeData());
delete temp;
}
else{
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;
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) {
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 (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) {
node_type_ptr new_root = _node->getNodeChildLeft();
_node->getNodeChildLeft() = new_root->getNodeChildRight();
new_root->getNodeChildRight() = _node;
if (_node->getNodeChildLeft())_node->getNodeChildLeft()->getNodeParent() = _node;
new_root->getNodeParent() = _node->getNodeParent();
_node->getNodeParent() = new_root;
updateNodeHeight(_node);
updateNodeHeight(new_root);
_node = new_root;
}
void rrRotate(node_type_ptr& _node) {
node_type_ptr new_root = _node->getNodeChildRight();
_node->getNodeChildRight() = new_root->getNodeChildLeft();
new_root->getNodeChildLeft() = _node;
if (_node->getNodeChildRight())_node->getNodeChildRight()->getNodeParent() = _node;
new_root->getNodeParent() = _node->getNodeParent();
_node->getNodeParent() = new_root;
updateNodeHeight(_node);
updateNodeHeight(new_root);
_node = new_root;
}
void lrRotate(node_type_ptr& _node) {
rrRotate(_node->getNodeChildLeft());
llRotate(_node);
}
void rlRotate(node_type_ptr& _node) {
llRotate(_node->getNodeChildRight());
rrRotate(_node);
}
};
#endif
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)