I am trying to create an avl tree then using boost to check if what I created is working. However, in all my boost test cases I don't have a main(which I thought is the issue causing the problem). This is my avl .hpp
I'm somewhat new to c++.
template <typename T>
class avlTreeNode
{
public:
// data in the node
T nodeValue;
// pointers to the left and right children of the node
avlTreeNode<T> *left;
avlTreeNode<T> *right;
int balanceFactor;
// CONSTRUCTOR
avlTreeNode (const T& item, avlTreeNode<T> *lptr = NULL,
avlTreeNode<T> *rptr = NULL, int bal = 0):
nodeValue(item), left(lptr), right(rptr), balanceFactor(bal)
{
}
};
const int leftheavy = -1;
const int balanced = 0;
const int rightheavy = 1;
template <typename T>
class avlTree
{
public:
// CONSTRUCTORS, DESTRUCTOR, ASSIGNMENT
// constructor. initialize root to NULL and size to 0
avlTree();
~avlTree();
typedef T* iterator;
typedef T const* const_iterator;
// constructor. insert n elements from range of T* pointers4
avlTree(T *first, T *last);
// search for item. if found, return an iterator pointing
// at it in the tree; otherwise, return end()
iterator find(const T& item);
// search for item. if found, return an iterator pointing
// at it in the tree; otherwise, return end()
const_iterator find(const T& item) const;
// indicate whether the tree is empty
int empty() const;
// return the number of data items in the tree
int size() const;
// give a vertical display of the tree .
void displayTree(int maxCharacters) const;
// insert item into the tree
//std::pair<iterator, bool> insert(const T& item);
// insert a new node using the basic List operation and format
//std::pair<iterator, bool> insert(const T& item);
// delete all the nodes in the tree
void clear();
// constant versions
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
///////////////////////////////////////////////////////////
//when I created this it started giving me the lnk 1561 error
std::pair<iterator,bool> insert(const T& item)
{
avlTree<T>::iterator iter;
// quietly return if item is already in the tree
if ((iter = find(item)) != end() )
return std::pair<iterator,bool>(iter,false);
// declare AVL tree node pointers.
avlTreeNode<T> *treeNode = root,*newNode;
// flag used by AVLInsert to rebalance nodes
bool reviseBalanceFactor = false;
// get a new AVL tree node with empty pointer fields
newNode = getavlTreeNode(item,NULL,NULL);
// call recursive routine to actually insert the element
avlInsert(treeNode, newNode, reviseBalanceFactor);
// assign new values to data members root, size and current
root = treeNode;
treeSize++;
return std::pair<iterator, bool> (iterator(newNode), true);
}
private:
// pointer to tree root
avlTreeNode<T> *root;
// number of elements in the tree
int treeSize;
// allocate a new tree node and return a pointer to it
avlTreeNode<T> *getavlTreeNode(const T& item,
avlTreeNode<T> *lptr,avlTreeNode<T> *rptr);
// used by copy constructor and assignment operator
avlTreeNode<T> *copyTree(avlTreeNode<T> *t);
// delete the storage occupied by a tree node
void freeavlTreeNode(avlTreeNode<T> *p);
// used by destructor, assignment operator and clear()
void deleteTree(avlTreeNode<T> *t);
// locate a node item and its parent in tree. used by find()
avlTreeNode<T> *findNode(const T& item,
avlTreeNode<T>* & parent) const;
// member functions to insert and erase a node
void singleRotateLeft (avlTreeNode<T>* &p);
void singleRotateRight (avlTreeNode<T>* &p);
void doubleRotateLeft (avlTreeNode<T>* &p);
void doubleRotateRight (avlTreeNode<T>* &p);
void updateLeftTree (avlTreeNode<T>* &tree,
bool &reviseBalanceFactor);
void updateRightTree (avlTreeNode<T>* &tree,
bool &reviseBalanceFactor);
};
On the top of your cpp file, define BOOST_TEST_MAIN. It is used to automatically generate main function by the unit testing library.
For example:
#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>
#include "avl.hpp"
BOOST_AUTO_TEST_CASE( test )
{
// ...
}
Related
This is a function to find the maximum amount of left nodes. I do realize that there is already a thread for that:
Count number of left nodes in BST
but I don't want pointers in my main file. So I am trying to find a slightly different approach.
bst<int>::binTreeIterator it;
int findMax(bst<int>::binTreeIterator it)
{
int l = 0, r;
if (!(it.leftSide() == NULL)) {
l += 1 + findMax(it.leftSide());
}
if (!(it.rightSide() == NULL)) {
r = findMax(it.rightSide());
}
return l;
}
my problem is with the leftSide()/rightSide() function; How do I implement them so that it returns an iterator object that points to the left side/ right side of the iterator "it" object?
template <class Type>
typename bst<Type>::binTreeIterator bst<Type>::binTreeIterator::leftSide()
{
}
Edit:
template <class Type>
class bst
{
struct binTreeNode
{
binTreeNode * left;
binTreeNode * right;
Type item;
};
public:
class binTreeIterator
{
public:
friend class bst;
binTreeIterator();
binTreeIterator(binTreeNode*);
bool operator==(binTreeNode*);
bool operator==(binTreeIterator);
binTreeIterator rightSide();
binTreeIterator leftSide();
private:
binTreeNode * current;
};
bst();
bst(const bst<Type>&);
const bst& operator=(const bst<Type>&);
~bst();
void insert(const Type&);
void display(); // TEST
binTreeIterator begin();
binTreeIterator end();
private:
binTreeNode * insert(binTreeNode*, const Type&);
void inorder(binTreeNode*);
void destroyTree(binTreeNode*);
void cloneTree(binTreeNode*, binTreeNode*);
binTreeNode * root;
};
This very simple snipped of code should do the trick already:
template <class Type>
typename bst<Type>::binTreeIterator bst<Type>::binTreeIterator::leftSide()
{
return current->left;
}
As you did not declare the iterator's constructor explicit, it will get called automatically from the pointer to left/right returned.
i am writing this code a generic list , now in this generic list i did a class for iterator that helds two parameters : one is a pointer to the list he points to .
and the other one points to the element in the list he points to ..
now i need to write an insert function that inserts a new element to a given list , with the following rules :: where i insert a new node to the list, and in this function if the iterator poiints to the end of the list the we add the new node to the end of the list else we insert the node one place before the node that the iterator currently points to , and if the iteratot points to a different node then thats an error .
now i want the iterator to be defoult so in case in the tests someone called the function with one parameter i want the iterator to be equal to the end element of the list.
the function end i wrote it inside of the list.
now in the insert function i did that but i get this error :
cannot call member function "List::iterator List::end()"without object
.
#include <iostream>
#include <assert.h>
#include "Exceptions.h"
template <class T>
class List {
public:
List();
List(const List&);
~List();
List<T>& operator=(const List& list);
template <class E>
class ListNode {
private:
ListNode(const E& t, ListNode<E> *next): data(new E(t)), next(next){}
~ListNode(){delete data;}
E* data;
ListNode<E> *next;
public:
friend class List<E>;
friend class Iterator;
E getData() const{
return *(this->data);
}
ListNode<E>* getNext() const{
return this->next;
}
};
class Iterator {
const List<T>* list;
int index;
ListNode<T>* current;
Iterator(const List<T>* list, int index): list(list),
index(index),current(NULL){
int cnt=index;
while (cnt > 0) {
current = current->next;
cnt--;
}
}
friend class List<T>;
friend class ListNode<T>;
public:
// more functions for iterator
};
Iterator begin() const ;
Iterator end() const;
void insert(const T& data, Iterator iterator=end());//here i get the error
void remove(Iterator iterator);
class Predicate{
private:
T target;
public:
Predicate(T i) : target(i) {}
bool operator()(const T& i) const {
return i == target;
}
};
Iterator find(const Predicate& predicate);
class Compare{
private:
T target;
public:
Compare(T i) : target(i) {}
bool operator()(const T& i) const {
return i < target;
}
};
bool empty() const;
int compareLinkedList(ListNode<T> *node1, ListNode<T> *node2);
private:
ListNode<T> *head;
ListNode<T> *tail;
int size;
};
any help would be amazing ! cause i don't know why such a mistake apears .
//insert function just in case :
template <typename T>
void List<T>::insert(const T& data, Iterator iterator=end()){
if(iterator.list!=this){
throw mtm::ListExceptions::ElementNotFound();
return;
}
ListNode<T> *newNode = new ListNode<T>(data, iterator.current);
if(iterator.index==size){
if (head == NULL) {
head = newNode;
tail=newNode;
}else{
Iterator temp(this,size-1);
temp.current->next=newNode;
}
//newNode->next=this->end().current;
}
else {
if (head == NULL) {
head = newNode;
tail=newNode;
}
else {
Iterator temp1(this,iterator.index-1);
temp1.current->next=newNode;
newNode->next=iterator.current->next;
}
}
size++;
}
void insert(const T& data, Iterator iterator=end());
This is the offending line. A default argument cannot be the result of a member function call. The right tool to achieve what you want is overloading.
void insert(const T& data, Iterator iterator);
void insert(const T& data) { insert(data, end()); }
Here we still defer to the insert function you implemented, but we call end from within the overloads body, where it's allowed.
Don't worry about the indirect call. This is a very small function that's defined inside the class declaration itself. Any decent compiler will inline it completely.
I am required to implement these two methods in this class. Elem& operator*() and Elem* operator->(). The only issue whoever is that the Iterator class is defined within a Map Class. While the Elem is defined in the private section of the parent class. The catch is that I am not allowed to modify the the .h file of the class.
class Iterator{
public:
Iterator(){}
explicit Iterator(Elem *cur):_cur(cur) {}
Elem& operator*();
Elem* operator->();
// Iterator operator++(int);
bool operator==(Iterator it);
bool operator!=(Iterator it);
private:
Elem* _cur;
};
Here is my attempted implemnetation of the function. However does not work as it says the struct is private.
Map::Elem& Map::Iterator::operator*(Iterator it){
//do stuff
}
The class is defined within another class. Which the struct is defined in under the private section. I am not really sure how I am supposed to be returning an Elem& or Elem* from within the Iterator class, if the Elem structure is private. However I suspect it has something to do with the Elem* _cur; defined within the private function of the Iterator class.
Here is the struct defined within the Map class. If that makes sense.. its private...
private:
struct Elem {
KEY_TYPE key;
VALUE_TYPE data;
Elem *left;
Elem *right;
};
Elem *_root; // a dummy root sentinel
int _size;
In case what I included does not work, here is the full class definition. Just wanted to include the examples above to include less code.
#ifndef MAP_H
#define MAP_H
#include <iostream>
#include <string>
using namespace std;
typedef string KEY_TYPE;
typedef string VALUE_TYPE;
class Map{
struct Elem; //declaration of an interal structure needed below...
public:
//---Constructors and destructors---
Map(); // constructs empty Map
Map(const Map &rhs); // copy constructor
~Map(); // destructor
// assignment operator
Map& operator=(const Map &rhs);
// insert an element; return true if successful
bool insert(KEY_TYPE, VALUE_TYPE);
// remove an element; return true if successful
bool erase(KEY_TYPE);
// return size of the Map
int size() const;
// return an iterator pointing to the end if an element is not found,
// otherwise, return an iterator to the element
class Iterator;
Iterator find(KEY_TYPE) const;
// Iterators for accessing beginning and end of collection
Iterator begin() const;
Iterator end() const;
// overloaded subscript operator
VALUE_TYPE& operator[](KEY_TYPE);
// output the undering BST
ostream& dump(ostream& out) const;
// a simple Iterator, won't traverse the collection
class Iterator{
public:
Iterator(){}
explicit Iterator(Elem *cur):_cur(cur) {}
Elem& operator*();
Elem* operator->();
// Iterator operator++(int);
bool operator==(Iterator it);
bool operator!=(Iterator it);
private:
Elem* _cur;
};
private:
struct Elem {
KEY_TYPE key;
VALUE_TYPE data;
Elem *left;
Elem *right;
};
Elem *_root; // a dummy root sentinel
int _size;
// helper method for inserting record into tree.
bool insert(Elem *& root, const KEY_TYPE& key, const VALUE_TYPE& data);
// helper method for print tree
void printTree(ostream& out, int level, Elem *p) const;
// common code for deallocation
void destructCode(Elem *& p);
// common code for copy tree
void copyCode(Elem* &newRoot, Elem* origRoot);
};
ostream& operator<< (ostream&, const Map&);
#endif
Any help would be awesome. Been making the rounds on google with no such luck.
The issues is not that Elm is private. Change
Map::Elem& Map::Iterator::operator*(Iterator it){
//do stuff
}
to
Map::Elem& Map::Iterator::operator*(){
//do stuff
}
because the former does not match the signature declared in the header. That causes the defined operator overload to not be in the scope of the class.
I am trying to define this operator overload function. However, I am getting this error from the compiler:
List.hpp:62:1: error: invalid use of template-name ‘cop4530::List’ without an argument list
List& List<T>::operator=(List&& rhs) // move assingment operator
This is whole class that I am working on it. It is a class that implements a doubly linked list:
template <typename T>
class List {
private:
struct Node {
T data;
Node *prev;
Node *next;
Node(const T & d = T{}, Node *p = nullptr, Node *n = nullptr)
: data{d}, prev{p}, next{n} {}
Node(T && d, Node *p = nullptr, Node *n = nullptr)
: data{std::move(d)}, prev{p}, next{n} {}
};
public:
//nested const_iterator class
class const_iterator {
public:
const_iterator(); // default zero parameter constructor
const T & operator*() const; // operator*() to return element
// increment/decrement operators
const_iterator & operator++();
const_iterator operator++(int);
const_iterator & operator--();
const_iterator operator--(int);
// comparison operators
bool operator==(const const_iterator &rhs) const;
bool operator!=(const const_iterator &rhs) const;
protected:
Node *current; // pointer to node in List
T & retrieve() const; // retrieve the element refers to
const_iterator(Node *p); // protected constructor
friend class List<T>;
};
// nested iterator class
class iterator : public const_iterator {
public:
iterator();
T & operator*();
const T & operator*() const;
// increment/decrement operators
iterator & operator++();
iterator operator++(int);
iterator & operator--();
iterator operator--(int);
protected:
iterator(Node *p);
friend class List<T>;
};
public:
// constructor, desctructor, copy constructor
List(); // default zero parameter constructor
List(const List &rhs); // copy constructor
List(List && rhs); // move constructor
// num elements with value of val
explicit List(int num, const T& val = T{});
// constructs with elements [start, end)
List(const_iterator start, const_iterator end);
// constructs with a copy of each of the elements in the initalizer_list
List (std::initializer_list<T> iList);
~List(); // destructor
// copy assignment operator
const List& operator=(const List &rhs);
// move assignment operator
List & operator=(List && rhs);
// sets list to the elements of the initializer_list
List& operator= (std::initializer_list<T> iList);
// member functions
int size() const; // number of elements
bool empty() const; // check if list is empty
void clear(); // delete all elements
void reverse(); // reverse the order of the elements
T& front(); // reference to the first element
const T& front() const;
T& back(); // reference to the last element
const T& back() const;
void push_front(const T & val); // insert to the beginning
void push_front(T && val); // move version of insert
void push_back(const T & val); // insert to the end
void push_back(T && val); // move version of insert
void pop_front(); // delete first element
void pop_back(); // delete last element
void remove(const T &val); // remove all elements with value = val
template <typename PREDICATE>
void remove_if(PREDICATE pred); // remove all elements for which Predicate pred
// returns true. pred can take in a function object
// print out all elements. ofc is deliminitor
void print(std::ostream& os, char ofc = ' ') const;
iterator begin(); // iterator to first element
const_iterator begin() const;
iterator end(); // end marker iterator
const_iterator end() const;
iterator insert(iterator itr, const T& val); // insert val ahead of itr
iterator insert(iterator itr, T && val); // move version of insert
iterator erase(iterator itr); // erase one element
iterator erase(iterator start, iterator end); // erase [start, end)
private:
int theSize; // number of elements
Node *head; // head node
Node *tail; // tail node
void init(); // initialization
};
The function that I am trying to define is this one:
template < typename T>
List& List<T>::operator=(List&& rhs)
{
std::swap( theSize, rhs.theSize);
std::swap( head, rhs.head);
std::swap( tail, rhs.tail);
return *this;
}
You forgot to add <T>:
template <typenameT>
List<T>& List<T>::operator=(List<T>&& rhs)
// ^^^ ^^^
// ^ this one is optional but I prefer it
{
//...
}
I have the following List class:
typedef int Elem; // list base element type
class NodeList { // node-based list
private:
struct Node { // a node of the list
Elem elem; // element value
Node* prev; // previous in list
Node* next; // next in list
};
public:
class Iterator { // an iterator for the list
public:
Elem& operator*(); // reference to the element
bool operator==(const Iterator& p) const; // compare positions
bool operator!=(const Iterator& p) const;
Iterator& operator++(); // move to next position
Iterator& operator--(); // move to previous position
friend class NodeList; // give NodeList access
private:
Node* v; // pointer to the node
Iterator(Node* u); // create from node
};
public:
NodeList(); // default constructor
int size() const; // list size
bool empty() const; // is the list empty?
Iterator begin() const; // beginning position
Iterator end() const; // (just beyond) last position
void insertFront(const Elem& e); // insert at front
void insertBack(const Elem& e); // insert at rear
void insert(const Iterator& p, const Elem& e); // insert e before p
void eraseFront(); // remove first
void eraseBack(); // remove last
void erase(const Iterator& p); // remove p
private: // data members
int n; // number of items
Node* header; // head-of-list sentinel
Node* trailer; // tail-of-list sentinel
};
My code does not do any checking to determine whether a given position (iterator object) is actually a member of a particular list. For example, if p is a position in list S and I call T.insert(p,e) on a different list T, then I'd actually be adding the element to S just before p. How can I change my NodeList implementation to disallow such a misuse?
It would mean a bit of memory overhead but if you store the head of each list in all nodes you can check if the heads are the same, then it's probably the same list.
Or if you prefer cpu overhead over memory overhead, loop through the prev-links to find the head of both lists and compare them as above.
So it depends on which kind of overhead you prefer.