I'm trying to implement a Fibonacci heap of pointers of a class called Node using Boost.
typedef boost::heap::fibonacci_heap<Node*> FibonacciHeap;
typedef FibonacciHeap::handle_type HeapHandle;
So far, so good. But I also want to store handles for the heap elements in the Node class. Boost specifically mentions that "handles can be stored inside the value_type". Boost
However, I can't define a comparison operator inside the class, because the heap never uses it and only compares the pointer values.
But defining a comparison struct which is passed as a template parameter to fibonacci_heap introduces a cyclic dependency:
struct CompareNode : public std::binary_function<Node*, Node*, bool>
{
bool operator()(Node* lhs, Node* rhs) const {
return lhs->getFScore() > rhs->getFScore();
}
};
typedef boost::heap::fibonacci_heap<
Node*,
boost::heap::compare<CompareNode> > FibonacciHeap;
Node depends on HeapHandle and HeapHandle depends on Node.
Try forwarding declaring Node and then defining the operator not inline
// In Node.h
class Node;
struct CompareNode : public std::binary_function<Node*, Node*, bool>
{
bool operator()(Node* lhs, Node* rhs) const;
};
typedef boost::heap::fibonacci_heap<
Node*,
boost::heap::compare<CompareNode> > FibonacciHeap;
typedef FibonacciHeap::handle_type HeapHandle;
class Node{
HeapHandle handle_;
int getFScore();
};
// In Node.cpp
#include "Node.h"
bool CompareNode::operator()(Node* lhs, Node* rhs) const {
return lhs->getFScore() > rhs->getFScore();
}
Related
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've implemented a balanced binary search tree (Red-black tree) for practice purposes. here is the header of data-structure of underlying nodes and methods I've implemented so far:
#ifndef BST_H
#define BST_H
template <typename T>
class treeNode {
public:
treeNode *left;
treeNode *right;
T key;
treeNode(T key)
: key(key)
, left(nullptr)
, right(nullptr) {
}
};
template <typename T>
class BST {
public:
BST() {
root = nullptr;
nodes = 0;
}
BST(BST const& rhs);
BST& operator = (BST rhs) {
this->swap(rhs);
}
BST& operator = (BST&& rhs) {
this->swap(rhs);
}
~BST() {
clear(root);
}
void swap(BST& other) {
std::swap(root, other.root);
std::swap(nodes, other.nodes);
}
void clear(treeNode<T>* node) {
if(node) {
if(node->left) clear(node->left);
if(node->right) clear(node->right);
delete node;
}
}
bool isEmpty() const {
return root == nullptr;
}
void inorder(treeNode<T>*);
void traverseInorder();
void preorder(treeNode<T>*);
void traversePreorder();
void postorder(treeNode<T>*);
void traversePostorder();
void insert(T const& );
void remove(T const& );
treeNode<T>* search(const T &);
treeNode<T>* minHelper(treeNode<T>*);
treeNode<T>* min();
treeNode<T>* maxHelper(treeNode<T>*);
treeNode<T>* max();
size_t size() const;
void sort();
treeNode<T>* inOrderSuccessor(treeNode<T>*);
bool isBST(treeNode<T>*) const;
bool isBST() const;
private:
treeNode<T> *root;
size_t nodes;
};
#endif
I intend to implement C++ STL map (I've already implemented STL unordered_map using Hashtable) for which the underlying data-structure is Red-Black Tree AFAIK. How I can extend my tree to a key-value generic type map?
No need of any sort of source code. Some intuition will suffice. Thanks :)
With intuition: T will probably be pair<const key_type,mapped_type>. I'm Assuming that currently you use node.key < another_node.key for comparisons. That will not do, because a map should be only using the first part of the pair for that. You could add a Compare functor as a template parameter (in similar manner as you'll have to for your map class) to your tree to make it useful for implementing a stl compatible map.
You may choose to design your tree so that key and value classes are separate rather than combined. Here's example code for the template definition:
template<class Key, class Value, class Comp=std::less<Key>>
class BST {
Compare comp;
public:
BST(const Comp& comp = Comp()): comp(comp)
//...
// usage
if(comp(node.key, another_node.key)) {
// node is considered to be strictly before another_node
You can use std::less as a sensible default parameter for other users of the tree, but the map implementation should forward the comparator which was given for the map.
A fully stl compatible container should support custom allocators too and to make that possible, so must the internal tree structure.
I have this class called "Node". I've been considering renaming it "Tree", but either name makes about as much sense. This class implements a generic tree container. Each node can have any number of children. The basic header definition of the class is as follows:
template<class Elem>
class Node
{
public:
Node();
~Node();
Node(const Elem& value);
Node(const Node& rNode);
const Elem& operator*() const;
Elem& operator*();
Elem* operator->();
void operator=(const Elem& rhs);
Node* addChild(const Elem& value);
Node* addChild(Node childNode);
Node* addChild(Node* pChildNode);
HRESULT removeNode(DFSIterator<Node>& iter);
template <class Node, class List, class Iter> friend class DFSIterator;
private:
bool hasChild() const;
Node* m_pParentNode;
Elem m_value;
std::vector<Node*> m_childList;
static std::set<Node*> sNodeSet;
};
The header definition of my DFSIterator is:
template<class Item,
class List = std::vector<Item*>,
class Iter = typename std::vector<Item*>::iterator>
class DFSIterator
{
public:
DFSIterator(Item& rRootNode);
~DFSIterator();
DFSIterator* begin();
DFSIterator* operator++();
Item& operator*() const;
Item* operator->() const;
bool operator!=(const DFSIterator& rhs) const;
bool isDone() const;
operator bool() const {return !isDone();}
private:
template <class Node> friend class Node;
void initChildListIterator(Item* currentNode);
bool m_bIsDone;
Item* m_pRootNode;
Item* m_pCurrentNode;
ChildListIterator<Item>* m_pCurrentListIter;
std::map<Item*, ChildListIterator<Item, List, Iter>*> m_listMap;
};
Item is the iterator's alias for Node<Elem>.
The problem I am having is that I want to define iterators for this tree that the user can declare in a similar way to STL containers. I was thinking that putting typedef statements like typedef DFSIterator<Node<Elem>> dfs_iterator; would work fine. But whenever I add those statements into the header, I get the following error error C2512<Item>: no appropriate default constructor available. Wherever I try to go and use it.
So right now, to declare an iterator I have to do something like DFSIterator<Node<DataMap>> dfsIter = rRootNode.begin(); or DFSIterator<Node<DataMap>> dfsIter(rNode); if I don't want to start at the root node of the tree. What I want to be able to do is something more like Node<DataMap>::dfs_iterator it = rRootNode.begin(). Is there a way to do this that I am missing?
Note: I do want to change a few other things about this implementation. I don't really want the user to be passing a node element to the addChild() method. I'd rather have the user pass an iterator that is pointing to a node.
If you define dfs_iterator inside Node, then you can use it basically like you describe:
template<class Elem>
class Node
{
public:
typedef Node<Elem> Item;
template<
class List = std::vector<Item*>,
class Iter = typename std::vector<Item*>::iterator
> class dfs_iterator;
.
.
.
};
template<class Elem>
template<class List, class Iter>
class Node<Elem>::dfs_iterator
{
public:
.
.
.
};
and use
Node<DataMap>::dfs_iterator<> it = rRootNode.begin();
The only difference is that since dfs_iterator is a template, you have to specify the template parameters, even though they both can be defaulted.
Let's say we have a priority_queue that holds a bunch of ListNode objects declared as below:
class ListNode {
int val;
ListNode *next;
public:
explicit ListNode(int v) : val(v), next(NULL) {}
inline bool operator<(const ListNode& rhs) const {
return val < rhs.val;
}
};
std::priority_queue<ListNode> pq;
By overriding operator< method or providing a sorting functor we can have the priority_queue hold the ListNode objects in val's ascending order.
My question is if the priority_queue holds the pointers to ListNode class instead can I have the pointers sorted so that the val's pointed are in ascending order. How do I do that?
std::priority_queue<ListNode *> pq1;
Thanks!
As you said, std::priority_queue accepts as third template parameter a comparison functor that it has to use to perform the comparisons.
Just write your own that dereferences the items before comparing them:
template<typename T>
struct PtrLess
{
bool operator()(const T* left, const T* right)
{
return *left < *right;
}
};
std::priority_queue<ListNode *, std::vector< ListNode * >, PtrLess< ListNode > > pq1;
A pointer to ListNode is like an everyday pointer. You cannot overload an operator between two pointers.
However, you can override the comparison operator for the purpose of the priority_queue. It would go something like this:
struct ListNodePtrLess {
bool operator()(const ListNode* a, const ListNode* b) {
return a->val < b->val;
}
};
typedef std::priority_queue<ListNode*, std::vector<ListNode*>, ListNodePtrLess> MyPriorityQueue;
(also: you will need to make ListNodePtrLess a friend of ListNode, or let it access the val field in some different way)
I have a Node class with the members
int weight;
Node *left;
Node *right;
I want to create a heap by using the STL functions
make_heap(Iterator , Iterator, comp)
pop_heap(Iterator, Iterator, comp)
to apply on a vector of Node pointers. How can I create a comparison object (or comparison function) for those functions?
struct node_comparison : public std::binary_function< const Node*, const Node*, bool >
{
bool operator()( const Node* const a, const Node* const b ) const
{
return a->weight < b->weight;
}
};
Note that this comparsion object compares only the weights, but I assume this is desired behaviour.
If you provide strict weak ordering via a operator< for your object you can call the overload of make_heap, pop_heap, etc which don't even need the third argument. comp is so you can provide a custom comparison if you choose.
class Node
{
int weight;
Node *left;
Node *right;
public:
bool operator<(const Node& rhs) const { return weight < rhs.weight; }
};