node depth
This commit is contained in:
parent
8fb5f13336
commit
c65f71e997
137
tree.cpp
137
tree.cpp
|
@ -12,16 +12,22 @@ using Node_ptr = std::unique_ptr<Node<T>>;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct Node{
|
struct Node{
|
||||||
T value;
|
T value;
|
||||||
|
int max_depth;
|
||||||
Node_ptr<T> small;
|
Node_ptr<T> small;
|
||||||
Node_ptr<T> big;
|
Node_ptr<T> big;
|
||||||
|
|
||||||
|
bool add(T val);
|
||||||
|
bool add_to_child(Node_ptr<T>* child, T val);
|
||||||
|
void update_depth();
|
||||||
void dump(std::ofstream& ofs) const;
|
void dump(std::ofstream& ofs) const;
|
||||||
|
Node(T v): value{v}, max_depth{0}, small{nullptr}, big{nullptr}{}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class Tree{
|
class Tree{
|
||||||
Node_ptr<T> root;
|
Node_ptr<T> root;
|
||||||
Node_ptr<T>* find(T val);
|
Node_ptr<T>* find(T val);
|
||||||
Node_ptr<T>* find_to_swap(Node_ptr<T>* unwanted);
|
bool try_to_del(Node_ptr<T>* node, T val);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool insert(T val);
|
bool insert(T val);
|
||||||
|
@ -39,69 +45,106 @@ Node_ptr<T>* Tree<T>::find(T val){
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
Node_ptr<T>* Tree<T>::find_to_swap(Node_ptr<T>* unwanted){
|
|
||||||
if((*unwanted)->small) unwanted = &(*unwanted)->small;
|
|
||||||
else return nullptr;
|
|
||||||
while((*unwanted)->big) unwanted = &(*unwanted)->big;
|
|
||||||
return unwanted;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
bool Tree<T>::del(T val){
|
|
||||||
Node_ptr<T>* unwanted = find(val);
|
|
||||||
if(!unwanted) return false;
|
|
||||||
Node_ptr<T>* to_swap = find_to_swap(unwanted);
|
|
||||||
if(!to_swap){
|
|
||||||
(*unwanted).reset((*unwanted)->big.release());
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
std::swap((*unwanted)->value, (*to_swap)->value);
|
|
||||||
(*to_swap).reset((*to_swap)->small.release());
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool Tree<T>::insert(T val){
|
bool Tree<T>::insert(T val){
|
||||||
std::unique_ptr<Node<T>> node = std::make_unique<Node<T>>();
|
if(!root){
|
||||||
node->value = val;
|
root = std::make_unique<Node<T>>(val);
|
||||||
if (!root){
|
return true;
|
||||||
root.swap(node);
|
}
|
||||||
|
else return root->add(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool Node<T>::add(T val){
|
||||||
|
if (val == value) return false;
|
||||||
|
else if (val < value) return add_to_child(&small, val);
|
||||||
|
else return add_to_child(&big, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool Node<T>::add_to_child(Node_ptr<T>* child, T val){
|
||||||
|
if(!(*child)){
|
||||||
|
*child = std::make_unique<Node<T>>(val);
|
||||||
|
update_depth();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
Node<T>* temp = root.get();
|
if((*child)->add(val)){
|
||||||
while(temp){
|
update_depth();
|
||||||
if(val < temp->value){
|
|
||||||
if(temp->small) temp = temp->small.get();
|
|
||||||
else{
|
|
||||||
temp->small.swap(node);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if(val > temp->value){
|
|
||||||
if(temp->big) temp = temp->big.get();
|
|
||||||
else{
|
|
||||||
temp->big.swap(node);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else return false;
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool Tree<T>::del(T val){
|
||||||
|
if(!root) return false;
|
||||||
|
else return try_to_del(&root, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool Tree<T>::try_to_del(Node_ptr<T>* node, T val){
|
||||||
|
if(val == (*node)->value) {
|
||||||
|
Node<T>* temp = (*node).get();
|
||||||
|
std::vector<Node<T>*> path;
|
||||||
|
if((*node)->small) {
|
||||||
|
temp = (*node)->small.get();
|
||||||
|
path.push_back(temp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
node->reset((*node)->big.release());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
while(temp->big){
|
||||||
|
temp = temp->big.get();
|
||||||
|
path.push_back(temp);
|
||||||
|
}
|
||||||
|
//mam temp na 'to swap' nodu...
|
||||||
|
std::swap((*node)->value, temp->value);
|
||||||
|
//temp->steal_values(std::move(temp->small));
|
||||||
|
for(int i = path.size() -1; i >= 0; i--) path[i]->update_depth();
|
||||||
|
path.clear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if(val < (*node)->value){
|
||||||
|
if(!(*node)->small) return false;
|
||||||
|
else {
|
||||||
|
if(try_to_del(&(*node)->small, val)){
|
||||||
|
(*node)->update_depth();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(!(*node)->big) return false;
|
||||||
|
else {
|
||||||
|
if(try_to_del(&(*node)->big, val)){
|
||||||
|
(*node)->update_depth();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void Node<T>::update_depth(){
|
||||||
|
if(small && big) max_depth = std::max(small->max_depth, big->max_depth) + 1;
|
||||||
|
else if (small) max_depth = small->max_depth + 1;
|
||||||
|
else max_depth = big->max_depth + 1;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void Node<T>::dump(std::ofstream& ofs) const {
|
void Node<T>::dump(std::ofstream& ofs) const {
|
||||||
if (small) {
|
if (small) {
|
||||||
ofs << value << " -> " << small->value << '\n';
|
ofs << '"' << value << " : " << max_depth << '"' << " -> " << '"' << small->value << " : " << small->max_depth << '"' << '\n';
|
||||||
small->dump(ofs);
|
small->dump(ofs);
|
||||||
}
|
}
|
||||||
if (big) {
|
if (big) {
|
||||||
ofs << value << " -> " << big->value << '\n';
|
ofs << '"' << value << " : " << max_depth << '"' << " -> " << '"' << big->value << " : " << big->max_depth << '"' << '\n';
|
||||||
big->dump(ofs);
|
big->dump(ofs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,7 +163,7 @@ void Tree<T>::print() const {
|
||||||
|
|
||||||
int main(){
|
int main(){
|
||||||
Tree<int> t;
|
Tree<int> t;
|
||||||
std::vector<int> v = {3, 6, 8, -1, 7, 0, 9, 2, -11, 5};
|
std::vector<int> v = {3, 6, 8};
|
||||||
for(auto i : v){
|
for(auto i : v){
|
||||||
if(t.insert(i)) std::cout << "added " << i << "\n";
|
if(t.insert(i)) std::cout << "added " << i << "\n";
|
||||||
else std::cout << "failed at adding " << i << "\n";
|
else std::cout << "failed at adding " << i << "\n";
|
||||||
|
|
Loading…
Reference in New Issue