mirror of https://github.com/xfarrow/lasd.git
parent
10c5148efc
commit
46c52c6132
|
@ -13,26 +13,27 @@ namespace lasd {
|
||||||
|
|
||||||
// checks if two trees which have the same root node are identical
|
// checks if two trees which have the same root node are identical
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
bool BinaryTree<Data>::Node::operator==(const Node& toEvaluate){
|
bool BinaryTree<Data>::Node::operator==(const Node& toEvaluate) const noexcept{
|
||||||
return EqualNodes(this, &toEvaluate);
|
return EqualNodes(*this, toEvaluate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* given two nodes, checks if the subtree is the same */
|
/* given two nodes, checks if the subtree is the same */
|
||||||
bool BinaryTree<Data>::Node::EqualNodes(Node* n1, Node* n2){
|
template <typename Data>
|
||||||
if(n1->data == n2->data){
|
bool BinaryTree<Data>::Node::EqualNodes(const Node& n1, const Node& n2) const{
|
||||||
if(n1->IsLeaf() && n2->IsLeaf()) return true;
|
if(n1.data == n2.data){
|
||||||
if( (n1->HasLeftChild() && !n2->HasLeftChild()) || (n1->HasRightChild() && !n2->HasRightChild()) ) return false;
|
if(n1.IsLeaf() && n2.IsLeaf()) return true;
|
||||||
return( EqualNodes(n1->LeftChild(),n2->LeftChild()) &&
|
if( (n1.HasLeftChild() && !n2.HasLeftChild()) || (n1.HasRightChild() && !n2.HasRightChild()) ) return false;
|
||||||
EqualNodes(n1->RightChild(),n2->RightChild())
|
return( EqualNodes(n1.LeftChild(),n2.LeftChild()) &&
|
||||||
)
|
EqualNodes(n1.RightChild(),n2.RightChild())
|
||||||
|
);
|
||||||
}else{
|
}else{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
bool BinaryTree<Data>::Node::operator!=(const Node& toEvaluate){
|
bool BinaryTree<Data>::Node::operator!=(const Node& toEvaluate) const noexcept{
|
||||||
return !(*this == toEvaluate)
|
return !(*this == toEvaluate);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
|
@ -41,7 +42,7 @@ Data& BinaryTree<Data>::Node::Element(){
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
const Data& BinaryTree<Data>::Node::Element(){
|
const Data& BinaryTree<Data>::Node::Element() const{
|
||||||
return this->data;
|
return this->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,132 +59,132 @@ bool BinaryTree<Data>::operator!=(const BinaryTree& toCompare) const noexcept{
|
||||||
/* ----- Map and fold functions ----- */
|
/* ----- Map and fold functions ----- */
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
void BinaryTree<Data>::MapPreOrder(const MapFunctor function, void* par){
|
void BinaryTree<Data>::MapPreOrder(const typename MappableContainer<Data>::MapFunctor function, void* par){
|
||||||
MapPreOrder(function, par, &Root());
|
MapPreOrder(function, par, &Root());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
void BinaryTree<Data>::MapPostOrder(const MapFunctor function, void* par){
|
void BinaryTree<Data>::MapPostOrder(const typename MappableContainer<Data>::MapFunctor function, void* par){
|
||||||
MapPostOrder(function, par, &Root());
|
MapPostOrder(function, par, &Root());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
void BinaryTree<Data>::MapInOrder(const MapFunctor function, void* par){
|
void BinaryTree<Data>::MapInOrder(const typename MappableContainer<Data>::MapFunctor function, void* par){
|
||||||
MapInOrder(function, par, &Root());
|
MapInOrder(function, par, &Root());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
void BinaryTree<Data>::MapBreadth(const MapFunctor function, void* par){
|
void BinaryTree<Data>::MapBreadth(const typename MappableContainer<Data>::MapFunctor function, void* par){
|
||||||
MapBreadth(function, par, &Root());
|
MapBreadth(function, par, &Root());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
void BinaryTree<Data>::FoldPreOrder(const FoldFunctor function, const void* par, void* acc){
|
void BinaryTree<Data>::FoldPreOrder(const typename FoldableContainer<Data>::FoldFunctor function, const void* par, void* acc) const{
|
||||||
FoldPreOrder(function, par, acc, &Root());
|
FoldPreOrder(function, par, acc, &Root());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
void BinaryTree<Data>::FoldPostOrder(const FoldFunctor function, const void* par, void* acc) const{
|
void BinaryTree<Data>::FoldPostOrder(const typename FoldableContainer<Data>::FoldFunctor function, const void* par, void* acc) const{
|
||||||
FoldPostOrder(function, par, acc, &Root());
|
FoldPostOrder(function, par, acc, &Root());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
void BinaryTree<Data>::FoldInOrder(const MapFunctor function, const void* par, void* acc) const{
|
void BinaryTree<Data>::FoldInOrder(const typename FoldableContainer<Data>::FoldFunctor function, const void* par, void* acc) const{
|
||||||
FoldInOrder(function, par, acc, &Root());
|
FoldInOrder(function, par, acc, &Root());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
void BinaryTree<Data>::FoldBreadth(const FoldFunctor function, const void* par, void* acc) const{
|
void BinaryTree<Data>::FoldBreadth(const typename FoldableContainer<Data>::FoldFunctor function, const void* par, void* acc) const{
|
||||||
FoldBreadth(function, par, acc, &Root());
|
FoldBreadth(function, par, acc, &Root());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----- Auxiliary map and fold functions ----- */
|
/* ----- Auxiliary map and fold functions ----- */
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
void BinaryTree<Data>::MapPreOrder(const MapFunctor function, void* par, Node* node){
|
void BinaryTree<Data>::MapPreOrder(const typename MappableContainer<Data>::MapFunctor function, void* par, Node* node){
|
||||||
if(node != nullptr){
|
if(node != nullptr){
|
||||||
function(node->Element(), par);
|
function(node->Element(), par);
|
||||||
if(node->HasLeftChild()){
|
if(node->HasLeftChild()){
|
||||||
MapPreOrder(function, par, node->LeftChild());
|
MapPreOrder(function, par, &(node->LeftChild()));
|
||||||
}
|
}
|
||||||
if(node->HasRightChild()){
|
if(node->HasRightChild()){
|
||||||
MapPreOrder(function, par, node->RightChild());
|
MapPreOrder(function, par, &(node->RightChild()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
void BinaryTree<Data>::MapPostOrder(const MapFunctor function, void* par, Node* node){
|
void BinaryTree<Data>::MapPostOrder(const typename MappableContainer<Data>::MapFunctor function, void* par, Node* node){
|
||||||
if(node != nullptr){
|
if(node != nullptr){
|
||||||
if(node->HasLeftChild()){
|
if(node->HasLeftChild()){
|
||||||
MapPreOrder(function, par, node->LeftChild());
|
MapPreOrder(function, par, &(node->LeftChild()));
|
||||||
}
|
}
|
||||||
if(node->HasRightChild()){
|
if(node->HasRightChild()){
|
||||||
MapPreOrder(function, par, node->RightChild());
|
MapPreOrder(function, par, &(node->RightChild()));
|
||||||
}
|
}
|
||||||
function(node->Element(), par);
|
function(node->Element(), par);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
void BinaryTree<Data>::FoldPreOrder(const FoldFunctor function, const void* par, void* acc, const Node* node){
|
void BinaryTree<Data>::FoldPreOrder(const typename FoldableContainer<Data>::FoldFunctor function, const void* par, void* acc, const Node* node) const{
|
||||||
if(node != nullptr){
|
if(node != nullptr){
|
||||||
function(node->Element(), par, acc);
|
function(node->Element(), par, acc);
|
||||||
if(node->HasLeftChild()){
|
if(node->HasLeftChild()){
|
||||||
FoldPreOrder(function, par, acc, node->LeftChild());
|
FoldPreOrder(function, par, acc, &(node->LeftChild()));
|
||||||
}
|
}
|
||||||
if(node->HasRightChild()){
|
if(node->HasRightChild()){
|
||||||
FoldPreOrder(function, par, acc, node->RightChild());
|
FoldPreOrder(function, par, acc, &(node->RightChild()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
void BinaryTree<Data>::FoldPostOrder(const FoldFunctor function, const void* par, void* acc, const Node* node){
|
void BinaryTree<Data>::FoldPostOrder(const typename FoldableContainer<Data>::FoldFunctor function, const void* par, void* acc, const Node* node) const{
|
||||||
if(node != nullptr){
|
if(node != nullptr){
|
||||||
if(node->HasLeftChild()){
|
if(node->HasLeftChild()){
|
||||||
FoldPreOrder(function, par, acc, node->LeftChild());
|
FoldPreOrder(function, par, acc, &(node->LeftChild()));
|
||||||
}
|
}
|
||||||
if(node->HasRightChild()){
|
if(node->HasRightChild()){
|
||||||
MapPreOrder(function, par, acc, node->RightChild());
|
FoldPreOrder(function, par, acc, &(node->RightChild()));
|
||||||
}
|
}
|
||||||
function(node->Element(), par, acc);
|
function(node->Element(), par, acc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
void BinaryTree<Data>::MapInOrder(const MapFunctor function, void* par, Node* node){
|
void BinaryTree<Data>::MapInOrder(const typename MappableContainer<Data>::MapFunctor function, void* par, Node* node){
|
||||||
if(node != nullptr){
|
if(node != nullptr){
|
||||||
if(node->HasLeftChild()){
|
if(node->HasLeftChild()){
|
||||||
MapInOrder(function, par, node->LeftChild());
|
MapInOrder(function, par, &(node->LeftChild()));
|
||||||
}
|
}
|
||||||
function(node->Element(), par);
|
function(node->Element(), par);
|
||||||
if(node->HasRightChild()){
|
if(node->HasRightChild()){
|
||||||
MapInOrder(function, par, node->RightChild());
|
MapInOrder(function, par, &(node->RightChild()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
void FoldInOrder(const FoldFunctor function, const void* par, void* acc, const Node* node) const{
|
void BinaryTree<Data>::FoldInOrder(const typename FoldableContainer<Data>::FoldFunctor function, const void* par, void* acc, const Node* node) const{
|
||||||
if(node != nullptr){
|
if(node != nullptr){
|
||||||
if(node->HasLeftChild()){
|
if(node->HasLeftChild()){
|
||||||
FoldInOrder(function, par, acc, node->LeftChild());
|
FoldInOrder(function, par, acc, &(node->LeftChild()));
|
||||||
}
|
}
|
||||||
function(node->Element(), par, acc);
|
function(node->Element(), par, acc);
|
||||||
if(node->HasRightChild()){
|
if(node->HasRightChild()){
|
||||||
FoldPreOrder(function, par, acc, node->RightChild());
|
FoldPreOrder(function, par, acc, &(node->RightChild()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
void BinaryTree<Data>::MapBreadth(const MapFunctor function, void* par, Node* node){
|
void BinaryTree<Data>::MapBreadth(const typename MappableContainer<Data>::MapFunctor function, void* par, Node* node){
|
||||||
QueueLst<struct Node*> toVisit;
|
QueueLst<struct Node*> toVisit;
|
||||||
if(node != nullptr){
|
if(node != nullptr){
|
||||||
toVisit.Enqueue(node);
|
toVisit.Enqueue(node);
|
||||||
while(!toVisit.Empty()){
|
while(!toVisit.Empty()){
|
||||||
func(toVisit.Head()->Element(), par);
|
function(toVisit.Head()->Element(), par);
|
||||||
|
|
||||||
if(toVisit.Head()->HasLeftChild()){
|
if(toVisit.Head()->HasLeftChild()){
|
||||||
toVisit.Enqueue(&(toVisit.Head()->LeftChild()));
|
toVisit.Enqueue(&(toVisit.Head()->LeftChild()));
|
||||||
|
@ -197,12 +198,12 @@ void BinaryTree<Data>::MapBreadth(const MapFunctor function, void* par, Node* no
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
void BinaryTree<Data>::FoldBreadth(const MapFunctor function, const void* par, void* acc, const Node* node){
|
void BinaryTree<Data>::FoldBreadth(const typename FoldableContainer<Data>::FoldFunctor function, const void* par, void* acc, Node* node) const{
|
||||||
QueueLst<struct Node*> toVisit;
|
QueueLst<BinaryTree<Data>::Node*> toVisit;
|
||||||
if(node != nullptr){
|
if(node != nullptr){
|
||||||
toVisit.Enqueue(node);
|
toVisit.Enqueue(node);
|
||||||
while(!toVisit.Empty()){
|
while(!toVisit.Empty()){
|
||||||
func(toVisit.Head()->Element(), par, acc);
|
function(toVisit.Head()->Element(), par, acc);
|
||||||
|
|
||||||
if(toVisit.Head()->HasLeftChild()){
|
if(toVisit.Head()->HasLeftChild()){
|
||||||
toVisit.Enqueue(&(toVisit.Head()->LeftChild()));
|
toVisit.Enqueue(&(toVisit.Head()->LeftChild()));
|
||||||
|
@ -240,7 +241,7 @@ BTPreOrderIterator<Data>::~BTPreOrderIterator(){
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
BTPreOrderIterator& BTPreOrderIterator<Data>::operator=(const BTPreOrderIterator& itr){
|
BTPreOrderIterator<Data>& BTPreOrderIterator<Data>::operator=(const BTPreOrderIterator& itr){
|
||||||
//curr = &(*itr);
|
//curr = &(*itr);
|
||||||
curr = itr.curr;
|
curr = itr.curr;
|
||||||
stack = itr.stack;
|
stack = itr.stack;
|
||||||
|
@ -248,7 +249,7 @@ BTPreOrderIterator& BTPreOrderIterator<Data>::operator=(const BTPreOrderIterator
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
BTPreOrderIterator& BTPreOrderIterator<Data>::operator=(BTPreOrderIterator&& itr) noexcept{
|
BTPreOrderIterator<Data>& BTPreOrderIterator<Data>::operator=(BTPreOrderIterator&& itr) noexcept{
|
||||||
std::swap(curr, itr.curr);
|
std::swap(curr, itr.curr);
|
||||||
std::swap(stack, itr.stack);
|
std::swap(stack, itr.stack);
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -265,31 +266,31 @@ bool BTPreOrderIterator<Data>::operator!=(const BTPreOrderIterator& itr) const n
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
struct BinaryTree<Data>::Node BTPreOrderIterator<Data>::operator*() const{
|
Data& BTPreOrderIterator<Data>::operator*() const{
|
||||||
return *curr;
|
return curr->Element();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
bool BTPreOrderIterator<Data>::Terminated() noexcept{
|
bool BTPreOrderIterator<Data>::Terminated() const noexcept{
|
||||||
return curr==nullptr;
|
return (curr==nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
void BTPreOrderIterator<Data>::operator++(){
|
void BTPreOrderIterator<Data>::operator++(){
|
||||||
if(Terminated()) throw std::out_of_range("Iterator is terminated!");
|
if(Terminated()) throw std::out_of_range("Iterator is terminated!");
|
||||||
|
|
||||||
if( (curr->HasLeftChild() ){
|
if(curr->HasLeftChild()){
|
||||||
curr = &(curr->LeftChild());
|
curr = &(curr->LeftChild());
|
||||||
|
|
||||||
if( (curr->HasRightChild() )
|
if( curr->HasRightChild() )
|
||||||
stack.Push(&curr->RightChild());
|
stack.Push(&curr->RightChild());
|
||||||
|
|
||||||
}else if( (curr->HasRightChild() ){
|
}else if(curr->HasRightChild()){
|
||||||
curr = &curr->RightChild();
|
curr = &curr->RightChild();
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
try{
|
try{
|
||||||
curr = &stack.TopNPop();
|
curr = stack.TopNPop();
|
||||||
}catch(std:: length_error exc){
|
}catch(std:: length_error exc){
|
||||||
curr = nullptr;
|
curr = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -300,11 +301,11 @@ template <typename Data>
|
||||||
struct BinaryTree<Data>::Node* BTPostOrderIterator<Data>::DeepestLeftLeaf(struct BinaryTree<Data>::Node* node){
|
struct BinaryTree<Data>::Node* BTPostOrderIterator<Data>::DeepestLeftLeaf(struct BinaryTree<Data>::Node* node){
|
||||||
if(node->HasLeftChild()){
|
if(node->HasLeftChild()){
|
||||||
stack.Push(node);
|
stack.Push(node);
|
||||||
MostLeftLeaf(node->LeftChild());
|
DeepestLeftLeaf(&(node->LeftChild()));
|
||||||
}
|
}
|
||||||
else if(node->HasRightChild()){
|
else if(node->HasRightChild()){
|
||||||
stack.Push(node);
|
stack.Push(node);
|
||||||
MostLeftLeaf(node->RightChild());
|
DeepestLeftLeaf(&(node->RightChild()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return node;
|
return node;
|
||||||
|
@ -312,7 +313,7 @@ struct BinaryTree<Data>::Node* BTPostOrderIterator<Data>::DeepestLeftLeaf(struct
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
BTPostOrderIterator<Data>::BTPostOrderIterator(const BinaryTree<Data>& tree){
|
BTPostOrderIterator<Data>::BTPostOrderIterator(const BinaryTree<Data>& tree){
|
||||||
curr = DeepestLeftLeaf(&tree.Root())
|
curr = DeepestLeftLeaf(&tree.Root());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
|
@ -334,14 +335,14 @@ BTPostOrderIterator<Data>::~BTPostOrderIterator(){
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
BTPostOrderIterator& BTPostOrderIterator<Data>::operator=(const BTPostOrderIterator& itr){
|
BTPostOrderIterator<Data>& BTPostOrderIterator<Data>::operator=(const BTPostOrderIterator& itr){
|
||||||
curr = itr.curr;
|
curr = itr.curr;
|
||||||
stack = itr.stack;
|
stack = itr.stack;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
BTPostOrderIterator& BTPostOrderIterator<Data>::operator=(BTPostOrderIterator&& itr){
|
BTPostOrderIterator<Data>& BTPostOrderIterator<Data>::operator=(BTPostOrderIterator&& itr) noexcept{
|
||||||
std::swap(curr, itr.curr);
|
std::swap(curr, itr.curr);
|
||||||
std::swap(stack, itr.stack);
|
std::swap(stack, itr.stack);
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -358,27 +359,27 @@ bool BTPostOrderIterator<Data>::operator!=(const BTPostOrderIterator& itr) const
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
struct BinaryTree<Data>::Node BTPostOrderIterator<Data>::operator*() const{
|
Data& BTPostOrderIterator<Data>::operator*() const{
|
||||||
return *curr;
|
return curr->Element();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
bool BTPostOrderIterator<Data>::Terminated() noexcept{
|
bool BTPostOrderIterator<Data>::Terminated() const noexcept{
|
||||||
return (curr == nullptr)
|
return (curr == nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
void BTPostOrderIterator<Data>::operator++(){
|
void BTPostOrderIterator<Data>::operator++(){
|
||||||
if(Terminated()) throw std::out_of_range("Iterator is terminated!");
|
if(Terminated()) throw std::out_of_range("Iterator is terminated!");
|
||||||
try{
|
try{
|
||||||
if(curr == &stack.Top().LeftChild()){
|
if( curr == &((stack.Top())->LeftChild()) ){
|
||||||
if(stack.Top().HasRightChild()){
|
if( (stack.Top())->HasRightChild() ){
|
||||||
curr = DeepestLeftLeaf(&stack.Top().RightChild());
|
curr = DeepestLeftLeaf(&((stack.Top())->RightChild()));
|
||||||
}else{
|
}else{
|
||||||
curr = &stack.TopNPop();
|
curr = stack.TopNPop();
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
curr = &stack.TopNPop();
|
curr = stack.TopNPop();
|
||||||
}
|
}
|
||||||
}catch(std::length_error exc){
|
}catch(std::length_error exc){
|
||||||
curr = nullptr;
|
curr = nullptr;
|
||||||
|
@ -386,81 +387,81 @@ void BTPostOrderIterator<Data>::operator++(){
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
struct BinaryTree<Data>::Node* BTInOrdertOrderIterator<Data>::MostLeftNode(struct BinaryTree<Data>::Node* root){
|
struct BinaryTree<Data>::Node* BTInOrderIterator<Data>::MostLeftNode(struct BinaryTree<Data>::Node& root){
|
||||||
if(root->HasLeftChild()){
|
if(root.HasLeftChild()){
|
||||||
stack.Push(root);
|
stack.Push(&root);
|
||||||
MostLeftNode(root->LeftChild());
|
MostLeftNode(root.LeftChild());
|
||||||
}else{
|
}else{
|
||||||
return root;
|
return &root;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
BTInOrdertOrderIterator<Data>::BTInOrderIterator(const BinaryTree<Data>& tree){
|
BTInOrderIterator<Data>::BTInOrderIterator(const BinaryTree<Data>& tree){
|
||||||
curr = MostLeftNode(tree.Root());
|
curr = MostLeftNode(tree.Root());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
BTInOrdertOrderIterator<Data>::BTInOrderIterator(const BTInOrderIterator& itr){
|
BTInOrderIterator<Data>::BTInOrderIterator(const BTInOrderIterator& itr){
|
||||||
curr = itr.curr;
|
curr = itr.curr;
|
||||||
stack = itr.stack;
|
stack = itr.stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
BTInOrdertOrderIterator<Data>::BTInOrderIterator(BTInOrderIterator&& toMove) noexcept{
|
BTInOrderIterator<Data>::BTInOrderIterator(BTInOrderIterator&& toMove) noexcept{
|
||||||
std::move(curr, toMove.curr);
|
std::move(curr, toMove.curr);
|
||||||
std::move(stack, toMove.stack);
|
std::move(stack, toMove.stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
BTInOrdertOrderIterator<Data>::~BTInOrderIterator(){
|
BTInOrderIterator<Data>::~BTInOrderIterator(){
|
||||||
stack.Clear();
|
stack.Clear();
|
||||||
curr = nullptr;
|
curr = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
BTInOrdertOrderIterator<Data>::BTInOrderIterator& operator=(const BTInOrderIterator& itr){
|
BTInOrderIterator<Data>& BTInOrderIterator<Data>::operator=(const BTInOrderIterator& itr){
|
||||||
curr = itr.curr;
|
curr = itr.curr;
|
||||||
stack = itr.stack;
|
stack = itr.stack;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
BTInOrdertOrderIterator<Data>::BTInOrderIterator& operator=(BTInOrderIterator&& itr){
|
BTInOrderIterator<Data>& BTInOrderIterator<Data>::operator=(BTInOrderIterator&& toMove) noexcept{
|
||||||
std::move(curr, toMove.curr);
|
std::move(curr, toMove.curr);
|
||||||
std::move(stack, toMove.stack);
|
std::move(stack, toMove.stack);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
bool BTInOrdertOrderIterator<Data>::operator==(const BTInOrderIterator& itr) const noexcept{
|
bool BTInOrderIterator<Data>::operator==(const BTInOrderIterator& itr) const noexcept{
|
||||||
return (curr == itr.curr && stack == itr.stack );
|
return (curr == itr.curr && stack == itr.stack );
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
bool BTInOrdertOrderIterator<Data>::operator!=(const BTInOrderIterator& itr) const noexcept{
|
bool BTInOrderIterator<Data>::operator!=(const BTInOrderIterator& itr) const noexcept{
|
||||||
return !(*this == itr);
|
return !(*this == itr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
struct BinaryTree<Data>::Node BTInOrdertOrderIterator<Data>::operator*() const{
|
Data& BTInOrderIterator<Data>::operator*() const{
|
||||||
return *curr;
|
return curr->Element();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
bool BTInOrdertOrderIterator<Data>::Terminated() noexcept{
|
bool BTInOrderIterator<Data>::Terminated() const noexcept{
|
||||||
return (curr == nullptr);
|
return (curr == nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
void BTInOrdertOrderIterator<Data>::operator++(){
|
void BTInOrderIterator<Data>::operator++(){
|
||||||
if(Terminated()) throw std::out_of_range("Iterator is terminated!");
|
if(Terminated()) throw std::out_of_range("Iterator is terminated!");
|
||||||
|
|
||||||
if(curr->HasRightChild()){
|
if(curr->HasRightChild()){
|
||||||
curr = MostLeftNode(curr->RightChild());
|
curr = MostLeftNode(curr->RightChild());
|
||||||
}else{
|
}else{
|
||||||
try{
|
try{
|
||||||
curr = &(stack.TopNPop());
|
curr = stack.TopNPop();
|
||||||
}catch(std::length_error exc){
|
}catch(std::length_error exc){
|
||||||
curr = nullptr;
|
curr = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -491,14 +492,14 @@ BTBreadthIterator<Data>::~BTBreadthIterator(){
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
BTBreadthIterator& BTBreadthIterator<Data>::operator=(const BTBreadthIterator& itr){
|
BTBreadthIterator<Data>& BTBreadthIterator<Data>::operator=(const BTBreadthIterator& itr){
|
||||||
curr = itr.curr;
|
curr = itr.curr;
|
||||||
queue = itr.queue;
|
queue = itr.queue;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
BTBreadthIterator& BTBreadthIterator<Data>::operator=(BTBreadthIterator&& itr) noexcept{
|
BTBreadthIterator<Data>& BTBreadthIterator<Data>::operator=(BTBreadthIterator&& itr) noexcept{
|
||||||
std::swap(curr, itr.curr);
|
std::swap(curr, itr.curr);
|
||||||
std::swap(queue, itr.queue);
|
std::swap(queue, itr.queue);
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -515,12 +516,12 @@ bool BTBreadthIterator<Data>::operator!=(const BTBreadthIterator& itr) const noe
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
struct BinaryTree<Data>::Node BTBreadthIterator<Data>::operator*() const{
|
Data& BTBreadthIterator<Data>::operator*() const{
|
||||||
return *curr;
|
return curr->Element();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
bool BTBreadthIterator<Data>::Terminated() noexcept{
|
bool BTBreadthIterator<Data>::Terminated() const noexcept{
|
||||||
return curr == nullptr;
|
return curr == nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ public:
|
||||||
bool operator==(const Node&) const noexcept; // Comparison of abstract types is possible, but should not be visible.
|
bool operator==(const Node&) const noexcept; // Comparison of abstract types is possible, but should not be visible.
|
||||||
bool operator!=(const Node&) const noexcept; // Comparison of abstract types is possible, but should not be visible.
|
bool operator!=(const Node&) const noexcept; // Comparison of abstract types is possible, but should not be visible.
|
||||||
|
|
||||||
bool EqualNodes(Node*, Node*);
|
bool EqualNodes(const Node&, const Node&) const;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -95,33 +95,30 @@ public:
|
||||||
|
|
||||||
/* ----- Map and fold functions ----- */
|
/* ----- Map and fold functions ----- */
|
||||||
|
|
||||||
using typename MappableContainer<Data>::MapFunctor;
|
virtual void MapPreOrder(const typename MappableContainer<Data>::MapFunctor, void*) override; // Override MappableContainer member
|
||||||
using typename FoldableContainer<Data>::FoldFunctor;
|
virtual void MapPostOrder(const typename MappableContainer<Data>::MapFunctor, void*) override; // Override MappableContainer member
|
||||||
|
virtual void MapInOrder(const typename MappableContainer<Data>::MapFunctor, void*) override; // Override InOrderMappableContainer member
|
||||||
|
virtual void MapBreadth(const typename MappableContainer<Data>::MapFunctor, void*) override; // Override BreadthMappableContainer member
|
||||||
|
|
||||||
void MapPreOrder(const MapFunctor, void*) override; // Override MappableContainer member
|
virtual void FoldPreOrder(const typename FoldableContainer<Data>::FoldFunctor, const void*, void*) const override; // Override FoldableContainer member
|
||||||
void MapPostOrder(const MapFunctor, void*) override; // Override MappableContainer member
|
virtual void FoldPostOrder(const typename FoldableContainer<Data>::FoldFunctor, const void*, void*) const override; // Override FoldableContainer member
|
||||||
void MapInOrder(const MapFunctor, void*) override; // Override InOrderMappableContainer member
|
virtual void FoldInOrder(const typename FoldableContainer<Data>::FoldFunctor, const void*, void*) const override; // Override InOrderFoldableContainer member
|
||||||
void MapBreadth(const MapFunctor, void*) override; // Override BreadthMappableContainer member
|
virtual void FoldBreadth(const typename FoldableContainer<Data>::FoldFunctor, const void*, void*) const override; // Override BreadthFoldableContainer member
|
||||||
|
|
||||||
void FoldPreOrder(const FoldFunctor, const void*, void*) const override; // Override FoldableContainer member
|
|
||||||
void FoldPostOrder(const FoldFunctor, const void*, void*) const override; // Override FoldableContainer member
|
|
||||||
void FoldInOrder(const FoldFunctor, const void*, void*) const override; // Override InOrderFoldableContainer member
|
|
||||||
void FoldBreadth(const FoldFunctor, const void*, void*) const override; // Override BreadthFoldableContainer member
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/* ----- Auxiliary map and fold functions ----- */
|
/* ----- Auxiliary map and fold functions ----- */
|
||||||
|
|
||||||
void MapPreOrder(const MapFunctor, void*, Node*) override; // Accessory function executing from one node of the tree
|
void MapPreOrder(const typename MappableContainer<Data>::MapFunctor, void*, Node*); // Accessory function executing from one node of the tree
|
||||||
void MapPostOrder(const MapFunctor, void*, Node*) override; // Accessory function executing from one node of the tree
|
void MapPostOrder(const typename MappableContainer<Data>::MapFunctor, void*, Node*); // Accessory function executing from one node of the tree
|
||||||
void MapInOrder(const MapFunctor, void*, Node*) override; // Accessory function executing from one node of the tree
|
void MapInOrder(const typename MappableContainer<Data>::MapFunctor, void*, Node*); // Accessory function executing from one node of the tree
|
||||||
void MapBreadth(const MapFunctor, void*, Node*) override; // Accessory function executing from one node of the tree
|
void MapBreadth(const typename MappableContainer<Data>::MapFunctor, void*, Node*); // Accessory function executing from one node of the tree
|
||||||
|
|
||||||
void FoldPreOrder(const FoldFunctor, const void*, void*, const Node*) const override; // Accessory function executing from one node of the tree
|
void FoldPreOrder(const typename FoldableContainer<Data>::FoldFunctor, const void*, void*, const Node*) const; // Accessory function executing from one node of the tree
|
||||||
void FoldPostOrder(const FoldFunctor, const void*, void*, const Node*) const override; // Accessory function executing from one node of the tree
|
void FoldPostOrder(const typename FoldableContainer<Data>::FoldFunctor, const void*, void*, const Node*) const; // Accessory function executing from one node of the tree
|
||||||
void FoldInOrder(const FoldFunctor, const void*, void*, const Node*) const override; // Accessory function executing from one node of the tree
|
void FoldInOrder(const typename FoldableContainer<Data>::FoldFunctor, const void*, void*, const Node*) const; // Accessory function executing from one node of the tree
|
||||||
void FoldBreadth(const FoldFunctor, const void*, void*, const Node*) const override; // Accessory function executing from one node of the tree
|
void FoldBreadth(const typename FoldableContainer<Data>::FoldFunctor, const void*, void*, Node*) const; // Accessory function executing from one node of the tree
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
@ -133,7 +130,7 @@ private:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct BinaryTree<Data>::Node* curr;
|
struct BinaryTree<Data>::Node* curr;
|
||||||
StackLst<BinaryTree<Data>::Node*> stack(); // default constructor for stacklst
|
StackLst<struct BinaryTree<Data>::Node*> stack;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -171,9 +168,9 @@ public:
|
||||||
|
|
||||||
// Specific member functions (inherited from Iterator)
|
// Specific member functions (inherited from Iterator)
|
||||||
|
|
||||||
struct BinaryTree<Data>::Node operator*() const; // (throw std::out_of_range when terminated)
|
Data& operator*() const; // (throw std::out_of_range when terminated)
|
||||||
|
|
||||||
bool Terminated() noexcept; // (should not throw exceptions)
|
bool Terminated() const noexcept; // (should not throw exceptions)
|
||||||
|
|
||||||
/* ************************************************************************ */
|
/* ************************************************************************ */
|
||||||
|
|
||||||
|
@ -192,7 +189,7 @@ private:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct BinaryTree<Data>::Node* curr;
|
struct BinaryTree<Data>::Node* curr;
|
||||||
StackLst<BinaryTree<Data>::Node*> stack;
|
StackLst<struct BinaryTree<Data>::Node*> stack;
|
||||||
struct BinaryTree<Data>::Node* DeepestLeftLeaf(struct BinaryTree<Data>::Node*);
|
struct BinaryTree<Data>::Node* DeepestLeftLeaf(struct BinaryTree<Data>::Node*);
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -230,9 +227,9 @@ public:
|
||||||
|
|
||||||
// Specific member functions (inherited from Iterator)
|
// Specific member functions (inherited from Iterator)
|
||||||
|
|
||||||
struct BinaryTree<Data>::Node operator*() const; // (throw std::out_of_range when terminated)
|
Data& operator*() const; // (throw std::out_of_range when terminated)
|
||||||
|
|
||||||
bool Terminated() noexcept; // (should not throw exceptions)
|
bool Terminated() const noexcept; // (should not throw exceptions)
|
||||||
|
|
||||||
/* ************************************************************************ */
|
/* ************************************************************************ */
|
||||||
|
|
||||||
|
@ -251,8 +248,8 @@ private:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct BinaryTree<Data>::Node* curr;
|
struct BinaryTree<Data>::Node* curr;
|
||||||
StackLst<BinaryTree<Data>::Node*> stack;
|
StackLst<struct BinaryTree<Data>::Node*> stack;
|
||||||
struct BinaryTree<Data>::Node* MostLeftNode(struct BinaryTree<Data>::Node*);
|
struct BinaryTree<Data>::Node* MostLeftNode(struct BinaryTree<Data>::Node&);
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Specific constructors
|
// Specific constructors
|
||||||
|
@ -289,9 +286,9 @@ public:
|
||||||
|
|
||||||
// Specific member functions (inherited from Iterator)
|
// Specific member functions (inherited from Iterator)
|
||||||
|
|
||||||
struct BinaryTree<Data>::Node operator*() const; // (throw std::out_of_range when terminated)
|
Data& operator*() const; // (throw std::out_of_range when terminated)
|
||||||
|
|
||||||
bool Terminated() noexcept; // (should not throw exceptions)
|
bool Terminated() const noexcept; // (should not throw exceptions)
|
||||||
|
|
||||||
/* ************************************************************************ */
|
/* ************************************************************************ */
|
||||||
|
|
||||||
|
@ -311,7 +308,7 @@ private:
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
struct BinaryTree<Data>::Node* curr;
|
struct BinaryTree<Data>::Node* curr;
|
||||||
QueueVec<BinaryTree<Data>::Node*> queue;
|
QueueVec<struct BinaryTree<Data>::Node*> queue;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -349,9 +346,9 @@ public:
|
||||||
|
|
||||||
// Specific member functions (inherited from Iterator)
|
// Specific member functions (inherited from Iterator)
|
||||||
|
|
||||||
struct BinaryTree<Data>::Node operator*() const; // (throw std::out_of_range when terminated)
|
Data& operator*() const; // (throw std::out_of_range when terminated)
|
||||||
|
|
||||||
bool Terminated() noexcept; // (should not throw exceptions)
|
bool Terminated() const noexcept; // (should not throw exceptions)
|
||||||
|
|
||||||
/* ************************************************************************ */
|
/* ************************************************************************ */
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ namespace lasd {
|
||||||
|
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
struct BinaryTreeLnk<Data>::NodeLnk& BinaryTreeLnk<Data>::NodeLnk::operator=(const NodeLnk& node){
|
struct BinaryTreeLnk<Data>::NodeLnk& BinaryTreeLnk<Data>::NodeLnk::operator=(const BinaryTreeLnk<Data>::NodeLnk& node){
|
||||||
data = node.data;
|
data = node.data;
|
||||||
left = node.left;
|
left = node.left;
|
||||||
right = node.right;
|
right = node.right;
|
||||||
|
@ -34,12 +34,12 @@ bool BinaryTreeLnk<Data>::NodeLnk::HasRightChild() const noexcept{
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
Node& BinaryTreeLnk<Data>::NodeLnk::LeftChild() const{
|
struct BinaryTree<Data>::Node& BinaryTreeLnk<Data>::NodeLnk::LeftChild() const{
|
||||||
return *left;
|
return *left;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
Node& BinaryTreeLnk<Data>::NodeLnk::RightChild() const{
|
struct BinaryTree<Data>::Node& BinaryTreeLnk<Data>::NodeLnk::RightChild() const{
|
||||||
return *right;
|
return *right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +50,8 @@ BinaryTreeLnk<Data>::BinaryTreeLnk(const LinearContainer<Data>& lc){
|
||||||
size = lc.Size();
|
size = lc.Size();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BinaryTreeLnk<Data>::NodeLnk* CreateTreeFromLinearContainerInBreadth(const LinearContainer<Data>& lc, ulong position){
|
template <typename Data>
|
||||||
|
struct BinaryTreeLnk<Data>::NodeLnk* BinaryTreeLnk<Data>::CreateTreeFromLinearContainerInBreadth(const LinearContainer<Data>& lc, ulong position){
|
||||||
if(position >= lc.Size()) return nullptr;
|
if(position >= lc.Size()) return nullptr;
|
||||||
|
|
||||||
struct BinaryTreeLnk<Data>::NodeLnk* tmp = CreateNode(lc[position]);
|
struct BinaryTreeLnk<Data>::NodeLnk* tmp = CreateNode(lc[position]);
|
||||||
|
@ -64,7 +65,7 @@ struct BinaryTreeLnk<Data>::NodeLnk* CreateTreeFromLinearContainerInBreadth(cons
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
struct BinaryTreeLnk<Data>::NodeLnk* CreateNode(const Data& data){
|
struct BinaryTreeLnk<Data>::NodeLnk* BinaryTreeLnk<Data>::CreateNode(const Data& data){
|
||||||
struct BinaryTreeLnk<Data>::NodeLnk* newNode = new struct BinaryTreeLnk<Data>::NodeLnk();
|
struct BinaryTreeLnk<Data>::NodeLnk* newNode = new struct BinaryTreeLnk<Data>::NodeLnk();
|
||||||
newNode->data = data;
|
newNode->data = data;
|
||||||
newNode->left = nullptr;
|
newNode->left = nullptr;
|
||||||
|
@ -79,18 +80,19 @@ BinaryTreeLnk<Data>::BinaryTreeLnk(const BinaryTreeLnk<Data>& tree){
|
||||||
root = CopyTree(&tree.Root());
|
root = CopyTree(&tree.Root());
|
||||||
}
|
}
|
||||||
|
|
||||||
BinaryTreeLnk<Data>::NodeLnk* BinaryTreeLnk<Data>::CopyTree(struct BinaryTreeLnk<Data>::NodeLnk* nodeToCopy){
|
template <typename Data>
|
||||||
|
struct BinaryTreeLnk<Data>::NodeLnk* BinaryTreeLnk<Data>::CopyTree(struct BinaryTreeLnk<Data>::Node* nodeToCopy){
|
||||||
if(nodeToCopy==nullptr) return nullptr;
|
if(nodeToCopy==nullptr) return nullptr;
|
||||||
|
|
||||||
struct BinaryTreeLnk<Data>::NodeLnk* tmp = CreateNode(nodeToCopy.Element());
|
struct BinaryTreeLnk<Data>::NodeLnk* tmp = CreateNode(nodeToCopy->Element());
|
||||||
|
|
||||||
if(nodeToCopy.HasLeftChild())
|
if(nodeToCopy->HasLeftChild())
|
||||||
tmp->left = copyTree(&(nodeToCopy.LeftChild()));
|
tmp->left = CopyTree(&(nodeToCopy->LeftChild()));
|
||||||
else
|
else
|
||||||
tmp->left = nullptr;
|
tmp->left = nullptr;
|
||||||
|
|
||||||
if(nodeToCopy.HasRightChild())
|
if(nodeToCopy->HasRightChild())
|
||||||
tmp->right = copyTree(&(nodeToCopy.RightChild()));
|
tmp->right = CopyTree(&(nodeToCopy->RightChild()));
|
||||||
else
|
else
|
||||||
tmp->right = nullptr;
|
tmp->right = nullptr;
|
||||||
|
|
||||||
|
@ -144,12 +146,12 @@ bool BinaryTreeLnk<Data>::operator!=(const BinaryTreeLnk<Data>& tree) const noex
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
struct NodeLnk& Root() override{
|
struct BinaryTree<Data>::Node& BinaryTreeLnk<Data>::Root() const{
|
||||||
return *root;
|
return *root;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
void Clear() override{
|
void BinaryTreeLnk<Data>::Clear(){
|
||||||
DeleteTree(root);
|
DeleteTree(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,16 +13,14 @@ namespace lasd {
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
class BinaryTreeLnk : virtual protected BinaryTree<Data>{ // Must extend BinaryTree<Data>
|
class BinaryTreeLnk : virtual public BinaryTree<Data>{ // Must extend BinaryTree<Data>
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
using BinaryTree<Data>::size;
|
using BinaryTree<Data>::size;
|
||||||
struct NodeLnk* root = nullptr;
|
|
||||||
|
|
||||||
// Node
|
|
||||||
struct NodeLnk : virtual protected BinaryTree<Data>::Node { // Must extend Node
|
struct NodeLnk : virtual protected BinaryTree<Data>::Node { // Must extend Node
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -34,19 +32,22 @@ protected:
|
||||||
struct NodeLnk* right;
|
struct NodeLnk* right;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Node& operator=(const NodeLnk&); // Copy assignment of abstract types should not be possible.
|
struct NodeLnk& operator=(const NodeLnk&); // Copy assignment of abstract types should not be possible.
|
||||||
Node& operator=(NodeLnk&&) noexcept override; // Move assignment of abstract types should not be possible.
|
struct NodeLnk& operator=(NodeLnk&&) noexcept; // Move assignment of abstract types should not be possible.
|
||||||
bool IsLeaf() const noexcept override; // (concrete function should not throw exceptions)
|
bool IsLeaf() const noexcept override; // (concrete function should not throw exceptions)
|
||||||
bool HasLeftChild() const noexcept override; // (concrete function should not throw exceptions)
|
bool HasLeftChild() const noexcept override; // (concrete function should not throw exceptions)
|
||||||
bool HasRightChild() const noexcept override; // (concrete function should not throw exceptions)
|
bool HasRightChild() const noexcept override; // (concrete function should not throw exceptions)
|
||||||
|
|
||||||
Node& LeftChild() const override; // (concrete function must throw std::out_of_range when not existent)
|
struct BinaryTree<Data>::Node& LeftChild() const override; // (concrete function must throw std::out_of_range when not existent)
|
||||||
Node& RightChild() const override; // (concrete function must throw std::out_of_range when not existent)
|
struct BinaryTree<Data>::Node& RightChild() const override; // (concrete function must throw std::out_of_range when not existent)
|
||||||
|
|
||||||
struct BinaryTreeLnk<Data>::NodeLnk* CreateNode(const Data& data);
|
friend class BinaryTreeLnk<Data>;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
struct BinaryTreeLnk<Data>::NodeLnk* root = nullptr;
|
||||||
|
struct BinaryTreeLnk<Data>::NodeLnk* CreateNode(const Data& data);
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Default constructor
|
// Default constructor
|
||||||
|
@ -88,7 +89,7 @@ public:
|
||||||
|
|
||||||
// Specific member functions (inherited from BinaryTree)
|
// Specific member functions (inherited from BinaryTree)
|
||||||
|
|
||||||
struct NodeLnk& Root() override; // Override BinaryTree member (throw std::length_error when empty)
|
struct BinaryTree<Data>::Node& Root() const override; // Override BinaryTree member (throw std::length_error when empty)
|
||||||
|
|
||||||
/* ************************************************************************ */
|
/* ************************************************************************ */
|
||||||
|
|
||||||
|
@ -97,8 +98,8 @@ public:
|
||||||
void Clear() override; // Override Container member
|
void Clear() override; // Override Container member
|
||||||
|
|
||||||
struct BinaryTreeLnk<Data>::NodeLnk* CreateTreeFromLinearContainerInBreadth(const LinearContainer<Data>&,ulong);
|
struct BinaryTreeLnk<Data>::NodeLnk* CreateTreeFromLinearContainerInBreadth(const LinearContainer<Data>&,ulong);
|
||||||
struct BinaryTreeLnk<Data>::NodeLnk* CopyTree(struct BinaryTreeLnk<Data>::NodeLnk*);
|
struct BinaryTreeLnk<Data>::NodeLnk* CopyTree(struct BinaryTreeLnk<Data>::Node*);
|
||||||
void DeleteTree(BinaryTreeLnk<Data>::NodeLnk* node)
|
void DeleteTree(BinaryTreeLnk<Data>::NodeLnk* node);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
|
@ -2,9 +2,15 @@
|
||||||
namespace lasd {
|
namespace lasd {
|
||||||
|
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
template <typename Data>
|
||||||
|
BinaryTreeVec<Data>::NodeVec::NodeVec(Data& dat, ulong idx, BinaryTreeVec<Data>* ref){
|
||||||
|
data = dat;
|
||||||
|
index = idx;
|
||||||
|
ReferenceToTree = ref;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
struct BinaryTree<Data>:Node& BinaryTreeVec<Data>::NodeVec::operator=(const BinaryTreeVec<Data>::NodeVec& node){
|
struct BinaryTreeVec<Data>::NodeVec& BinaryTreeVec<Data>::NodeVec::operator=(const BinaryTreeVec<Data>::NodeVec& node){
|
||||||
ReferenceToTree = node.ReferenceToTree;
|
ReferenceToTree = node.ReferenceToTree;
|
||||||
data = node.data;
|
data = node.data;
|
||||||
index = node.index;
|
index = node.index;
|
||||||
|
@ -12,7 +18,7 @@ struct BinaryTree<Data>:Node& BinaryTreeVec<Data>::NodeVec::operator=(const Bina
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
struct BinaryTree<Data>:Node& BinaryTreeVec<Data>::NodeVec::operator=(BinaryTreeVec<Data>::NodeVec&& node) noexcept{
|
struct BinaryTreeVec<Data>::NodeVec& BinaryTreeVec<Data>::NodeVec::operator=(BinaryTreeVec<Data>::NodeVec&& node) noexcept{
|
||||||
std::swap(data, node.data);
|
std::swap(data, node.data);
|
||||||
std::swap(index, node.index);
|
std::swap(index, node.index);
|
||||||
std::swap(ReferenceToTree, node.ReferenceToTree);
|
std::swap(ReferenceToTree, node.ReferenceToTree);
|
||||||
|
@ -63,10 +69,7 @@ BinaryTreeVec<Data>::BinaryTreeVec(const LinearContainer<Data>& lc){
|
||||||
tree.Resize(lc.Size());
|
tree.Resize(lc.Size());
|
||||||
size = lc.Size();
|
size = lc.Size();
|
||||||
for(ulong i=0 ; i<size ; ++i){
|
for(ulong i=0 ; i<size ; ++i){
|
||||||
struct NodeVec* tmp = new BinaryTreeVec<Data>::NodeVec;
|
struct BinaryTreeVec<Data>::NodeVec* tmp = new BinaryTreeVec<Data>::NodeVec(lc[i], i, this);
|
||||||
tmp->data = lc[i];
|
|
||||||
tmp->index = i;
|
|
||||||
tmp->ReferenceToTree = this;
|
|
||||||
tree[i] = tmp;
|
tree[i] = tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,10 +79,7 @@ BinaryTreeVec<Data>::BinaryTreeVec(const BinaryTreeVec<Data>& bt){
|
||||||
size = bt.size;
|
size = bt.size;
|
||||||
tree.Resize(size);
|
tree.Resize(size);
|
||||||
for(ulong i=0 ; i<size ; ++i){
|
for(ulong i=0 ; i<size ; ++i){
|
||||||
struct NodeVec* tmp = new BinaryTreeVec<Data>::NodeVec;
|
struct BinaryTreeVec<Data>::NodeVec* tmp = new BinaryTreeVec<Data>::NodeVec( (bt.tree[i])->data , i, this);
|
||||||
tmp->data = bt[i];
|
|
||||||
tmp->index = i;
|
|
||||||
tmp->ReferenceToTree = this;
|
|
||||||
tree[i] = tmp;
|
tree[i] = tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,6 +88,9 @@ template <typename Data>
|
||||||
BinaryTreeVec<Data>::BinaryTreeVec(BinaryTreeVec<Data>&& bt) noexcept{
|
BinaryTreeVec<Data>::BinaryTreeVec(BinaryTreeVec<Data>&& bt) noexcept{
|
||||||
std::swap(size,bt.size);
|
std::swap(size,bt.size);
|
||||||
std::swap(tree,bt.tree);
|
std::swap(tree,bt.tree);
|
||||||
|
for(ulong i=0 ; i<size ; ++i){
|
||||||
|
tree[i]->ReferenceToTree = this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
|
@ -96,23 +99,23 @@ BinaryTreeVec<Data>::~BinaryTreeVec(){
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
bool BinaryTreeVec<Data>::operator=(const BinaryTreeVec<Data>& bt){
|
BinaryTreeVec<Data>& BinaryTreeVec<Data>::operator=(const BinaryTreeVec<Data>& bt){
|
||||||
size = bt.size;
|
size = bt.size;
|
||||||
tree.Resize(size);
|
tree.Resize(size);
|
||||||
for(ulong i=0 ; i<size ; ++i){
|
for(ulong i=0 ; i<size ; ++i){
|
||||||
struct NodeVec* tmp = new BinaryTreeVec<Data>::NodeVec;
|
struct NodeVec* tmp = new BinaryTreeVec<Data>::NodeVec((bt.tree[i])->data,i,this);
|
||||||
tmp->data = bt[i];
|
|
||||||
tmp->index = i;
|
|
||||||
tmp->ReferenceToTree = this;
|
|
||||||
tree[i] = tmp;
|
tree[i] = tmp;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
bool BinaryTreeVec<Data>::operator=(BinaryTreeVec<Data>&& bt) noexcept{
|
BinaryTreeVec<Data>& BinaryTreeVec<Data>::operator=(BinaryTreeVec<Data>&& bt) noexcept{
|
||||||
std::swap(size, bt.size);
|
std::swap(size, bt.size);
|
||||||
std::swap(tree, bt.tree);
|
std::swap(tree, bt.tree);
|
||||||
|
for(ulong i=0 ; i<size ; ++i){
|
||||||
|
tree[i]->ReferenceToTree = this;
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +123,7 @@ template <typename Data>
|
||||||
bool BinaryTreeVec<Data>::operator==(const BinaryTreeVec& bt) const noexcept{
|
bool BinaryTreeVec<Data>::operator==(const BinaryTreeVec& bt) const noexcept{
|
||||||
if(size==bt.size){
|
if(size==bt.size){
|
||||||
for(ulong i=0 ; i<size ; ++i){
|
for(ulong i=0 ; i<size ; ++i){
|
||||||
if((tree[i])->data != ((bt.tree)[i])->data ) return false;
|
if( tree[i]->data != (bt.tree[i])->data ) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -133,7 +136,7 @@ bool BinaryTreeVec<Data>::operator!=(const BinaryTreeVec& bt) const noexcept{
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
struct BinaryTreeVec<Data>::Node& BinaryTreeVec<Data>::Root(){
|
struct BinaryTree<Data>::Node& BinaryTreeVec<Data>::Root() const{
|
||||||
return *(tree.Front());
|
return *(tree.Front());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,22 +144,22 @@ template <typename Data>
|
||||||
void BinaryTreeVec<Data>::Clear(){
|
void BinaryTreeVec<Data>::Clear(){
|
||||||
for(ulong i=0 ; i<size ; ++i){
|
for(ulong i=0 ; i<size ; ++i){
|
||||||
delete tree[i];
|
delete tree[i];
|
||||||
tree[i] = nullptr
|
tree[i] = nullptr;
|
||||||
}
|
}
|
||||||
size = 0;
|
size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
void BinaryTreeVec<Data>::MapBreadth(const MapFunctor func, void* par) override{
|
void BinaryTreeVec<Data>::MapBreadth(const MapFunctor func, void* par){
|
||||||
for(ulong i=0 ; i<size ; ++i){
|
for(ulong i=0 ; i<size ; ++i){
|
||||||
func( *(tree[i]), par);
|
func( (tree[i])->data, par);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data>
|
template <typename Data>
|
||||||
void BinaryTreeVec<Data>::FoldBreadth(const MapFunctor func, const void* par, void* acc) override{
|
void BinaryTreeVec<Data>::FoldBreadth(const FoldFunctor func, const void* par, void* acc) const{
|
||||||
for(ulong i=0 ; i<size ; ++i){
|
for(ulong i=0 ; i<size ; ++i){
|
||||||
func( *(tree[i]), par, acc);
|
func( (tree[i])->data, par, acc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ protected:
|
||||||
|
|
||||||
using BinaryTree<Data>::size;
|
using BinaryTree<Data>::size;
|
||||||
// using BinaryTree<Data>::Node;
|
// using BinaryTree<Data>::Node;
|
||||||
Vector<struct NodeVec*> tree;
|
|
||||||
|
|
||||||
struct NodeVec : virtual protected BinaryTree<Data>::Node { // Must extend Node
|
struct NodeVec : virtual protected BinaryTree<Data>::Node { // Must extend Node
|
||||||
|
|
||||||
|
@ -34,17 +33,24 @@ protected:
|
||||||
BinaryTreeVec<Data>* ReferenceToTree = nullptr;
|
BinaryTreeVec<Data>* ReferenceToTree = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct BinaryTree<Data>::Node& operator=(const NodeVec&) override; // Copy assignment of abstract types should not be possible.
|
NodeVec(Data&, ulong, BinaryTreeVec<Data>*);
|
||||||
struct BinaryTree<Data>::Node& operator=(NodeVec&&) noexcept override; // Move assignment of abstract types should not be possible.
|
struct NodeVec& operator=(const NodeVec&); // Copy assignment of abstract types should not be possible.
|
||||||
|
struct NodeVec& operator=(NodeVec&&) noexcept; // Move assignment of abstract types should not be possible.
|
||||||
bool IsLeaf() const noexcept override; // (concrete function should not throw exceptions)
|
bool IsLeaf() const noexcept override; // (concrete function should not throw exceptions)
|
||||||
bool HasLeftChild() const noexcept override; // (concrete function should not throw exceptions)
|
bool HasLeftChild() const noexcept override; // (concrete function should not throw exceptions)
|
||||||
bool HasRightChild() const noexcept override; // (concrete function should not throw exceptions)
|
bool HasRightChild() const noexcept override; // (concrete function should not throw exceptions)
|
||||||
struct BinaryTree<Data>::Node& LeftChild() const override; // (concrete function must throw std::out_of_range when not existent)
|
struct BinaryTree<Data>::Node& LeftChild() const override; // (concrete function must throw std::out_of_range when not existent)
|
||||||
struct BinaryTree<Data>::Node& RightChild() const override; // (concrete function must throw std::out_of_range when not existent)
|
struct BinaryTree<Data>::Node& RightChild() const override; // (concrete function must throw std::out_of_range when not existent)
|
||||||
|
|
||||||
|
friend class BinaryTreeVec<Data>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Vector<struct BinaryTreeVec<Data>::NodeVec*> tree;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
// Default constructor
|
// Default constructor
|
||||||
BinaryTreeVec() = default;
|
BinaryTreeVec() = default;
|
||||||
|
|
||||||
|
@ -84,7 +90,7 @@ public:
|
||||||
|
|
||||||
// Specific member functions (inherited from BinaryTree)
|
// Specific member functions (inherited from BinaryTree)
|
||||||
|
|
||||||
struct BinaryTreeVec<Data>::NodeVec& Root() override; // Override BinaryTree member (throw std::length_error when empty)
|
struct BinaryTree<Data>::Node& Root() const override; // Override BinaryTree member (throw std::length_error when empty)
|
||||||
|
|
||||||
/* ************************************************************************ */
|
/* ************************************************************************ */
|
||||||
|
|
||||||
|
|
|
@ -203,10 +203,7 @@ public:
|
||||||
/* ************************************************************************ */
|
/* ************************************************************************ */
|
||||||
|
|
||||||
// Specific member functions
|
// Specific member functions
|
||||||
|
virtual void MapInOrder(const typename MappableContainer<Data>::MapFunctor, void*) = 0;
|
||||||
using typename MappableContainer<Data>::MapFunctor;
|
|
||||||
|
|
||||||
virtual void MapInOrder(const MapFunctor, void*) = 0;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -230,7 +227,7 @@ public:
|
||||||
InOrderFoldableContainer& operator=(const InOrderFoldableContainer&) = delete; // Copy assignment of abstract types should not be possible.
|
InOrderFoldableContainer& operator=(const InOrderFoldableContainer&) = delete; // Copy assignment of abstract types should not be possible.
|
||||||
|
|
||||||
// Move assignment
|
// Move assignment
|
||||||
InOrderFoldableContainer operator=(InOrderFoldableContainer&&) noexcept = delete; // Move assignment of abstract types should not be possible.
|
InOrderFoldableContainer& operator=(InOrderFoldableContainer&&) noexcept = delete; // Move assignment of abstract types should not be possible.
|
||||||
|
|
||||||
/* ************************************************************************ */
|
/* ************************************************************************ */
|
||||||
|
|
||||||
|
@ -242,9 +239,7 @@ public:
|
||||||
|
|
||||||
// Specific member functions
|
// Specific member functions
|
||||||
|
|
||||||
using typename MappableContainer<Data>::MapFunctor;
|
virtual void FoldInOrder(const typename FoldableContainer<Data>::FoldFunctor, const void*, void*) const = 0;
|
||||||
|
|
||||||
virtual void FoldInOrder(const MapFunctor, const void*, void*) const = 0;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -280,9 +275,7 @@ public:
|
||||||
|
|
||||||
// Specific member functions
|
// Specific member functions
|
||||||
|
|
||||||
using typename MappableContainer<Data>::MapFunctor;
|
virtual void MapBreadth(const typename MappableContainer<Data>::MapFunctor, void*) = 0;
|
||||||
|
|
||||||
void MapBreadth(const MapFunctor, void*) = 0;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -38,9 +38,9 @@ public:
|
||||||
|
|
||||||
// Specific member functions
|
// Specific member functions
|
||||||
|
|
||||||
virtual Data& operator*() = 0; // (concrete function must throw std::out_of_range when terminated)
|
virtual Data& operator*() const = 0; // (concrete function must throw std::out_of_range when terminated)
|
||||||
|
|
||||||
virtual bool Terminated() noexcept = 0; // (concrete function should not throw exceptions)
|
virtual bool Terminated() const noexcept = 0; // (concrete function should not throw exceptions)
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ public:
|
||||||
|
|
||||||
// Specific member functions
|
// Specific member functions
|
||||||
|
|
||||||
virtual ForwardIterator& operator++() = 0; // (concrete function must throw std::out_of_range when terminated)
|
virtual void operator++() = 0; // (concrete function must throw std::out_of_range when terminated)
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue