I have a method in a static class which tries to convert a binary tree to a list
I'd like to make it recursive but I couldn't
I've implemented some other methods in my class like add(), delete(), find().
Here is the code
class ARB
{
private:
struct BT
{
int data;
BT *l;
BT *r;
};
struct BT *p;
public
ARB();
~ARB();
void del(int n);
void add(int n);
};
void ARB::del(int num)
{
//The code ,don't care about it
};
main()
{
//
BTR T;
T.add(3);
T.add(5);
};
Here is what should we do to transfer the code from binary tree to list.
LLC ARB::changeit()
{ LLC x;
while(this!=NULL)
{
x.add(this->data); //
if(this.l==NULL)
{
x.print(); //To print the elemnts of List
return(x);
}
else
{
x=changeit(this.l);
}
if(this.r!=NULL)
{
x.~LLC();
x=changeit(this.r);
return(x);
}
}
}
The description of the problem is hard to follow but I noticed that you used the keywords this and static, which are generally mutually exclusive.
Any static function pertains to a class, not an object. Static functions can be called using the ARB::myStaticFunction() syntax and do not require an actual ARB object. So, this inside such a function does not refer to any object and is meaningless.
This call is meaningless:
x=changeit(this.l);
Since this refers to the ARB object that has no member called l. The same goes for this code:
this->data
You sometimes do this.data and sometimes this->data so you seem to be confused over the notion of an object pointer. Your ARB has the BT* called p which is the tree root, supposedly. You should start from it.
Also this is obviosly wrong:
x.~LLC();
Don't call the destructor of LLC explicitly!
The general algorithm for recursively placing a binary tree into a list (pseudocode):
tolist(node, list):
if node == NULL:
return
else:
tolist(node.left, list)
list.append_to_end(node.data)
tolist(node.right)
This assumes append_to_end of list is efficient, to make sense (this is achievable with an end pointer in the list). Also, it takes a list as an argument and modifies it. You can easily change it to have an internal recursive method that does that and an external method that creates a list, calls this method, and returns the list.
Related
I have a simple question. I have a LinkList class and root is initiated inside the class.
class LinkList {
struct node {
int data;
shared_ptr<node> next;
};
shared_ptr<node> root;
public:
void insert(int data);
void remove(int data);
void print();
int length();
bool search_recursive(int data);
bool search_recursiveUtil(shared_ptr<node> p, int data);
}
Ideally I wanted to implement a recursive function to search for a node. Now I implemented in the following way:
bool LinkList::search_recursiveUtil(shared_ptr<node> p, int data){
if(p == nullptr){
return false;
}
if(p->data == data){
return true;
}
return search_recursiveUtil(p->next, data);
}
bool LinkList::search_recursive(int data){
shared_ptr<node> p = root;
return search_recursiveUtil(p, data);
}
Now clearly you can see that since I do not want root to reach at the end of the linked list as other functions might use this head pointer to do something, I am taking a shared pointer P and traversing it. Now I want to have p to be pass to the "search_recursive" function but since it doesn't take shared_ptr argument so I had to take support of a "search_recursiveUtil" function.
My question is it is right way to approach? How can i implement this without having util function support?
Beside the consideration on why using a recursive search (the will soon result in a stack overflow as soon as the list becomes big enough) instead of a iterating one, since pointers are passed by value, there is no need of p: just call return search_recursiveUtil(root, data). Your reasoning abut root to reach the end of the list is a misconception.
The use of an xUtil function taking a positional parameter not required when calling the search from outside can be a good idea, just make it private to the class, so that -from outside- your interface will be just the search_recursive function.
Also, declare both the functions const, since they are not supposed to modify the data.
An alternative can be place the "Util" function as a node member, so that you can do
bool LinkList::node::search_recursiveUtil(int src_data){
if(data == src_data)
return true;
if(pnext == nullptr)
return false;
return pnext->search_recursiveUtil(src_data);
}
called as
bool LinkList::search_recursive(int data){
root->search_recursiveUtil(data);
}
In principle, that's exactly the way to go:
You have your interface function with the necessary parameters that calls an internal function with the required parameters. This way you keep your root member variable hidden. You could/should even declare your util member function private.
I am trying to use the C++ "Clipper Library" (http://www.angusj.com/delphi/clipper.php), but when I try to return one of the objects from the clipper library from a function, it seems to become null or is altered somehow
Here is the function I wrote. The only relevant lines should be the last 3.
ClipperLib::PolyTree MeshHandler::trianglesToPolyTreeUnion(std::vector<Triangle> triangles)
{
// Make all of the triangles CW
for (auto& triangle : triangles)
{
triangle.makeClockwise();
}
// Set up the Clipper
ClipperLib::Clipper clipper;
// To take a union, add all the paths as "subject" paths
for (auto& triangle : triangles)
{
ClipperLib::Path triContour(3);
triContour[0] = convertGLMToClipperPoint(triangle.getVertex(0));
triContour[1] = convertGLMToClipperPoint(triangle.getVertex(1));
triContour[2] = convertGLMToClipperPoint(triangle.getVertex(2));
clipper.AddPath(triContour, ClipperLib::PolyType::ptSubject, true);
}
// Now get the PolyTree representing the contours
ClipperLib::PolyTree tree;
clipper.Execute(ClipperLib::ClipType::ctUnion, tree);
return tree;
}
When I call clipper.execute, it writes into the tree structure some contour information. It writes the correct information, and I've tested that it's correct. However, when I return the tree, it doesn't seem to copy anything, and the PolyTree that results from this function is empty.
I'm sure that there's nothing wrong with the library and that I'm just making a beginner c++ mistake here. Hopefully someone has an idea of what it might be.
Thanks!
edit: For reference, here is a documentation page for the polytree (http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Classes/PolyTree/_Body.htm)
edit: I thought the clipper library wasn't open source, but it is. Here is the code
typedef std::vector< IntPoint > Path;
typedef std::vector< Path > Paths;
class PolyNode;
typedef std::vector< PolyNode* > PolyNodes;
class PolyNode
{
public:
PolyNode();
Path Contour;
PolyNodes Childs;
PolyNode* Parent;
PolyNode* GetNext() const;
bool IsHole() const;
bool IsOpen() const;
int ChildCount() const;
private:
unsigned Index; //node index in Parent.Childs
bool m_IsOpen;
JoinType m_jointype;
EndType m_endtype;
PolyNode* GetNextSiblingUp() const;
void AddChild(PolyNode& child);
friend class Clipper; //to access Index
friend class ClipperOffset;
};
class PolyTree: public PolyNode
{
public:
~PolyTree(){Clear();};
PolyNode* GetFirst() const;
void Clear();
int Total() const;
private:
PolyNodes AllNodes;
friend class Clipper; //to access AllNodes
};
Before doing anything, make sure the following program works correctly:
int main()
{
PolyTree p1;
// fill PolyTree with some values that make sense (please add code to do this)
//...
PolyTree p2 = p1;
PolyTree p3;
p3 = p1;
}
That is basically what we want to test. If you can get this code to work (add the relevant headers and initializations necessary), then you can focus back on the function. If the code above doesn't work, then there is your answer.
You need to get the code above to produce the correct copy semantics, and even just important, when main() exits, no memory corruption occurs on the destruction of p1, p2, and p3.
So either you can fix the class to copy safely, or forget about it and live with a class that you have to handle very carefully and in limited situations (i.e. you can't reliably return copies of it as you're doing now).
For the record and combining all the responses in the lengthy discussion to the question.
Problems are:
The value returned is a local variable that goes out of scope. This invokes the PolyTree destructor
The PolyTree contains a vector of PolyNode * pointers. Those are allocated when clipper.Execute() is invoked.
However PolyTree::Clear() does delete the nodes... and Clear() is invoked by the destructor.
So within the function, the content is correct (allocated by Execute()), when passed outside, in the absence of copy constructors and operator=, the destructor of the local variable is invoked an the nodes are cleared, the result received outside of the function is empty.
The code for PolyTree::Clear()
void PolyTree::Clear()
{
for (PolyNodes::size_type i = 0; i < AllNodes.size(); ++i)
delete AllNodes[i];
AllNodes.resize(0);
Childs.resize(0);
}
Probably you should follow the pattern of Execute and define your function as:
void MeshHandler::trianglesToPolyTreeUnion(std::vector<Triangle> triangles,ClipperLib::PolyTree &tree)
Assuming you don't want to modify the (obviously badly designed) Clipper library, you can do it like I suggested in my comment:
// Make sure to have this at the top of your header file:
#include <memory>
std::unique_ptr<ClipperLib::PolyTree> MeshHandler::trianglesToPolyTreeUnion(std::vector<Triangle> triangles)
{
// Rest of your code...
std::unique_ptr<ClipperLib::PolyTree> tree(new ClipperLib::PolyTree);
clipper.Execute(ClipperLib::ClipType::ctUnion, *tree);
return tree;
}
Then, when calling your function:
std::unique_ptr<ClipperLib::PolyTree> tree(yourMeshHandler.trianglesToPolyTreeUnion(/*...*/);
// make use of tree...
Still, I would suggest opening a ticket (if there's a bug tracker) or contacting the library's author about this issue.
Is there already a solution for this problem? I am dealing with the same problem.
Still no luck. The polytree outputs only memory adres.
when using : qDebug()<< "child id " << polynode->Childs;
When we have 2 childs, the output in terminal is :
std::vector(0x55f30d2a91b0, 0x55f30d258480)
I hope someone knows how to solve this..
Your problem is in the third line from the bottom of trianglesToPolyTreeUnion. The tree you are creating is created on the stack and is only in scope within the function.
You should dynamically allocate the memory and return a pointer to the tree or make your tree object a class member so it is still within scope once the function returns.
I want to create a generic linked list in C/C++ (without using templates of C++).
I have written following simple program and it works fine as of now -
typedef struct node
{
void *data;
node *next;
}node;
int main()
{
node *head = new node();
int *intdata = new int();
double *doubledata = new double();
char *str = "a";
*doubledata = 44.55;
*intdata = 10;
head->data = intdata;
node *node2 = new node();
node2->data = doubledata;
head->next = node2;
node *node3 = new node();
node3->data = str;
node3->next = NULL;
node2->next = node3;
node *temp = head;
if(temp != NULL)
{
cout<<*(int *)(temp->data)<<"\t";
temp = temp->next;
}
if(temp != NULL)
{
cout<<*(double *)(temp->data)<<"\t";
temp = temp->next;
}
if(temp != NULL)
{
cout<<*(char *)(temp->data)<<"\t";
temp = temp->next;
}
return 0;
}
My question is -
I need to know the data type of the data I am printing in the code above.
For example - first node is int so i wrote -
*(int *)(temp->data)
second is double and so on...
Instead, is there any generic way of simply displaying the data without worrying about the data type?
I know you can achieve this with templates, but what if I have to do this in C only ?
Thanks,
Kedar
The whole point of a generic list is that you can store anything in it. But you have to be realistic... You still need to know what you are putting in it. So if you are going to put mixed types in the list, then you should look at using a Variant pattern. That is, a type that provides multiple types. Here's a simple variant:
typedef struct Variant
{
enum VariantType
{
t_string,
t_int,
t_double
} type;
union VariantData
{
char* strVal;
int intVal;
double doubleVal;
} data;
} Variant;
You can then tell yourself "I'm storing pointers to Variants in my void* list. This is how you would do it in C. I assume when you say "C/C++" you mean that you're trying to write C code but are using a C++ compiler. Don't forget that C and C++ are two different languages that have some overlap. Try not to put them together in one word as if they're one language.
In C, the only way to achieve generics is using a void*, as you are already doing. Unfortunately, this means that there is no easy way to retrieve the type of an element of your linked list. You simply need to know them.
The way of interpreting data in memory is completely different for different data type.
Say a 32 bit memory block has some data. It will show different values when you typecast it as int or float as both are stored with different protocols. When saving some data in memory pointed by variable of type void*, it does not know how to interpret the data in its memory block. So you need to typecast it to specify the type in which you want to read the data.
This is a little bit like sticking all the cutlery in a drawer, but instead of putting knifes in one slot, forks in another slot, and spoons in a third slot, and teaspoons in the little slot in the middle, we just stick them all in wherever they happen to land when chucking them in, and then wondering why when you just stick your hand in and pick something up, you can't know what you are going to get.
The WHOLE POINT of C++ is that it allows you to declare templates and classes that "do things with arbitrary content". Since the above code uses new, it won't compile as C. So there's no point in making it hold an non-descriptive pointer (or even storing the data as a pointer in the first place).
template<typename T> struct node
{
T data;
node<T> *next;
node() : next(0) {};
};
Unfortunately, it still gets messier if you want to store a set of data that is different types within the same list. If you want to do that, you will need something in the node itself that indicates what it is you have stored.
I have done that in lists a few times since I started working (and probably a couple of times before I got a job) with computers in 1985. Many more times, I've done some sort of "I'll store arbitrary data" in a something like a std::map, where a name is connected to some "content". Every time I've used this sort of feature, it's because I'm writing something similar to a programming language (e.g. a configuration script, Basic interpreter, LisP interpreter, etc), using it to store "variables" that can have different types (int, double, string) or similar. I have seen similar things in other places, such as OpenGL has some places where the data returned is different types depending on what you ask for, and the internal storage has to "know" what the type is.
But 99% of all linked lists, binary trees, hash-tables, etc, that I have worked on contain one thing and one thing only. Storing "arbitrary" things in a single list is usually not that useful.
The answer below is targeting at C++ and not C. C++ allows for what you want, just not in the way that you want to do it. The way I would implement your problem would be using the built-in functionality of the virtual keyword.
Here's a stand-alone code sample that prints out different values no matter the actual derived type:
#include <iostream>
#include <list>
class Base
{
public:
virtual void Print() = 0;
};
class Derived1 : public Base
{
public:
virtual void Print()
{
std::cout << 1 << std::endl; // Integer
}
};
class Derived2 : public Base
{
public:
virtual void Print()
{
std::cout << 2.345 << std::endl; // Double
}
};
class Derived3 : public Base
{
public:
virtual void Print()
{
std::cout << "String" << std::endl; // String
}
};
int main(void)
{
// Make a "generic list" by storing pointers to a base interface
std::list<Base*> GenericList;
GenericList.push_back(new Derived1());
GenericList.push_back(new Derived2());
GenericList.push_back(new Derived3());
std::list<Base*>::iterator Iter = GenericList.begin();
while(Iter != GenericList.end())
{
(*Iter)->Print();
++Iter;
}
// Don't forget to delete the pointers allocated with new above. Omitted in example
return 0;
}
Also notice that this way you don't need to implement your own linked list. The standard list works just fine here. However, if you still want to use your own list, instead of storing a void *data;, store a Base *data;. Of course, this could be templated, but then you'd just end up with the standard again.
Read up on polymorphism to learn more.
I am working on some binary tree algorithms and need a "find node with searchindex..." function. The design for treenodes is basically
class TreeNode {
int index; // some identifier
TreeNode *left;
TreeNode *right;
}
and a tree is defined by a pointer to the root-node.
My implementation for the search function is:
void Tree::searchNode(TreeNode * root, int nodeIndex, TreeNode *resultNode){
/* Recursive search */
if (root->index == nodeIndex) {
resultNode = root;
} else {
/* search children if the current node is not a leaf */
if(!root->isLeaf()) {
this->searchNode(root->left,nodeIndex,resultNode);
this->searchNode(root->right,nodeIndex,resultNode);
}
}
}
Arguments: *root is the root-node of the tree, nodeIndex is the search-index and *resultNode is the pointer to the found (or not) node in the tree.
The function does not return a reference or pointer to the found node but modifies the pointer resultNode so it points to the found node. The idea is to initialize resultNode with NULL, perform the search and modify it if a match occurs. Otherwise it remains NULL and I can easily check if there are search results or not.
Another class with a tree buildingTree as member utilizes the search-function in this way:
TreeNode *resultNodePtr = NULL;
this->buildingTree->searchNode(this->buildingTree->rootPtr,
currentNodeIndex, resultNodePtr);
// do sth. with resultNodePtr if != NULL
I create *resultNodePtr on the stack because I just need it temporarily inside the function. Is this done correctly? However: The function does not work. resultNodePtr is always NULL, even if the tree contains a node with the search-index. I debugged it very carefully step by step, it detects
(root->index == nodeIndex)
correctly but
resultNode = root;
does not work (I want resultNode to point to the same adress root points to).
Debugger says resultNode before assignment is 0x0, root node is some adress, after the assignment resultNode remains 0x0.
Do I have to overload the operator= in this case for the class TreeNode?
I have tried it:
TreeNode & TreeNode::operator=(const TreeNode & oldTreeNode){
*this = oldTreeNode;
return *this;
// ignore childs for now
}
I am not an expert but this operator= seems trivial. Does it affect the assignment of two TreeNode pointers *node1 = *node2 at all?
Maybe you can help me. Thanks for reading, appreciate your help.
If I find a solution myself I will post it here.
Regards,
Mark
Because you pass resultNode into the function as a pointer by value, its original value never changes. Think of TreeNode* as literally nothing more than a number representing a memory address; when you reassign it:
resultNode = root;
This modifies the copy that searchNode has, but not the original pointer in the code which invokes searchNode. Take this simpler example:
void Foo(int x)
{
x = 100;
}
void Bar()
{
int x = 0;
Foo(x);
// at this point, x is still 0
}
resultNode's value doesn't change from NULL for the same reason that x doesn't change from 0 when the function Bar is invoked. To fix this issue, pass the pointer in as a pointer to a pointer, or a pointer by reference:
void Tree::searchNode(TreeNode* root, int nodeIndex, TreeNode*& resultNode)
{
// same code
}
... or:
void Tree::searchNode(TreeNode* root, int nodeIndex, TreeNode** resultNodePtr)
{
// assign to *resultNodePtr instead
}
Your resultNode pointer is being passed by value, not by reference. So when the function call completes the pointer on the calling side does not receive a value.
Your algorithm looks fine :)
Basically I am creating a base class that will be used for classes stored as a linked list, which are traversed and deleted as dictated by a virtual update() function which returns a bool.
I am wondering if this is the most efficient case (I like the fact that it can be a singley linked list in particular):
class Traversable
{
public:
Traversable();
virtual ~Traversable();
void traverse(Traversable** prevNext);
virtual bool update()=0;
protected:
private:
Traversable* next;
};
void Traversable::traverse(Traversable** prevNext)
{
if (!update()) /// Virtual function that returns a death flag
{ /// Death
if (next)
{
Traversable* localNext = next;
delete this;
localNext->traverse(prevNext);
}
else
{
*prevNext = NULL;
delete this;
}
}
else
{ /// This node stays alive, for now
*prevNext = this;
if (next)
{
next->traverse(&next);
}
}
}
Note the linked list is NULL terminated.
I think the careful lack of an assigment operation to a local variable after the next traverse function is called will secure usage of this function using tail calls. Can anyone spot anything I have done wrong, or perhaps suggest a slightly less convoluted approach :p
You're deliberately obfuscating the code in order to "tempt" the compiler into creating a specific result; whether this happens or not is quite probably more dependent on the compiler used, the optimization flags in effect, or even the code compiled that's using the above. The following is more compact code:
void Traversable::traverse(Traversable** prevNext)
{
bool doUpdate = update();
*prevNext = doUpdate ? this : next ? *prevNext : NULL;
Traversable **argNext = doUpdate ? &next : prevNext;
Traversable *localNext = next;
do_the_traversal_action(); // not spec'ed ...
if (!doUpdate)
delete this;
if (localNext)
localNext->traverse(argNext);
}
and still ends the function with a single tail return point. The only reason this uses conditionals is because you're changing prevNext in there.
Edit: what I'm trying to say is that no matter how you code it, in the end it's up to the compiler to decide whether it wants to tail-optimize the function or not. For modern optimizing compilers, there's often switches (-fconserve-stack or -foptimize-sibling-calls in GCC) that have a more immediate effect on this more than the sourcecode itself.
Edit 2: yes if course it's possible to write this function non-recursively; all it is, in the end, is a visitor type pattern. So the actual activity ends up being something like:
static void Traversable::traverse(Traversable *start)
{
Traversable *cur, *next;
for (cur = start; cur; cur = next) {
next = cur->next;
cur->do_the_traversal_action(); // not spec'ed ...
if (cur->update())
continue; // not supposed to remove this
if (next)
next->prevNext = cur->prevNext; // remove cur from list
delete cur;
}
}
Though, when you code it like that, the next obvious question is why one would not implement simple iterator types for Traversable and use std::remove_copy_if() for the visit-and-remove-on-condition task. Or use an STL list to start with.