2

I am currently trying to make a tree structure with Nodes having an unknown amount of children but I also have to keep track of parent Nodes. I looked at this question N-ary trees in C and made a structure similar to that advised in the link:

template <class T>
struct treeNode {

public: 

T  * data;
treeNode *parent;
treeNode *kids; //left 
treeNode *siblings; //right


treeNode();
~treeNode();
treeNode(T data);
void treeInsert(T newItem);



};

It says that by making the tree in this way, it makes certain algorithms easier to code. However, I am having a difficult time figuring out how I would create insert() and search() methods for this structure, seeing that I need to keep track of parent nodes. Are there any suggestions as to how I may go about this?

EDIT:

Here is my insert() method:

template<class T>
bool NewTree<T>::insert( T *data, treeNode<T> * parent)
{
if(this->root == NULL)
{
    this->root = new treeNode<T>();
    this->root->data = data;
    this->root->parent = NULL;
    this->root->children = NULL;
}
else
{
    treeNode temp = new treenode<T>();
    temp.data = data;
    temp.parent = parent;
    parent->children->siblings = temp; // add node to siblings of parent's   children
    parent->children = temp; // add node to children of parent

}

}

Does this look correct?

Community
  • 1
  • 1
Alex Alex
  • 101
  • 1
  • 1
  • 8

1 Answers1

1

With any tree structure, searching is going to use relatively the same algorithm (depth-first recursion if unsorted, or simple tree-searching if sorted (like binary search tree)). When you insert, all you need to do is assign the new node's .parent to the parent. Then assign the new node's .parent.child[1] to the new node (thus linking the parent to the child). Then, check the other children of the parent node to assign your new node's siblings (if any).

Okay, so here's some pseudocode (mostly like java -- sorry, it's what i've been writing today) that will implement node creation and the series of assignments to maintain it in a tree structure, using the second example in the link you provided:

(node source):

class Node {
  // generic data store
  public int data;
  public Node parent;
  public Node siblings;
  public Node children;
}

(tree source):

class NewTree {
  // current node
  public Node current;
  // pointer to root node
  public Node root;

  // constructor here
  // create new node
  public boolean insert(int data) {
    // search for the node which is immediately BEFORE where the new node should go
    // remember that with duplicate data values, we can just put the new node in
    // front of the chain of siblings
    Node neighbor = this.search(data);
    // if we've found the node our new node should follow, create it with the 
    // found node as parent, otherwise we are creating the root node
    // so if we're creating the root node, we simply create it and then set its
    // children, siblings, and parent to null
    // i think this is the part you're having trouble with, so look below for a 
    // diagram for visual aid
  }

  public Node search(int target) {
    // basically we just iterate through the chain of siblings and/or children 
    // until this.current.children is null or this.current.siblings is null
    // we need to make certain that we also search the children of 
    // this.index.sibling that may exist (depth-first recursive search)
  }
}

When we find the spot (using search()) where our new node should go, we need to reassign the parent, children, and siblings "links" inside the new node to its new parent, children, and siblings. For example, we take this:

A-|
|
B-C-|
| |
| F-G-|  
| |
| -
|
D-E-|
| |
- H-|
  |
  -

And we will insert a new node (X) where F is. This is just to illustrate how we reassign each of the new node's links. The finer details may be slightly different, but what's important here is the implementation example of the link reassignment:

A-|
|
B-C-|
| |
| X-F-G-|  
| | |
| - -
|
D-E-|
| |
- H-|
  |
  -

What we do is: 1) Create X. 2) Assign x.parent to c. 3) Reassign c.children to x. 4) Assign x.siblings to f. This inserts a new node (be mindful that an insertion is different than a sort and your tree may need resorting if you explicitly require a specific ordering).

L0j1k
  • 12,255
  • 7
  • 53
  • 65
  • Will the insert() method be any different because of how I'm organizing the kid/siblings? My main confusion is because of the representation shown here: http://blog.mozilla.org/nnethercote/2012/03/07/n-ary-trees-in-c/ Where the left node is the child that leads to other siblings-more than 2 – Alex Alex Feb 28 '13 at 03:55
  • It depends on how you're organizing them. However, that link shows the very lower rank of children in a strange way. Typically, you are going to organize them left-to-right (or whatever) until a parent has reached its maximum children, then start assigning the next children to the sibling of that parent. Therefore, in the link, node 2 will have children 5, 6, and 7, and node 3 will have node 8, 9, 10, and node 3 will have one child: 11. You should have a uniform distribution of children (typically)... That being said (continued in next comment) – L0j1k Feb 28 '13 at 04:03
  • It should not really matter how you organize your children. Even if you dictate a strange assignment order (like in the drawing in your link), the process for insertion is the same: `Object x = new node; x.parent = y; y.child = x;` and so on and so forth. I made a mistake up there about assigning the "parent" node to a child: You will have to do this every time you create a node. – L0j1k Feb 28 '13 at 04:05
  • I clarified my answer a lot. But basically, the process of assigning a new child node to a parent is the same no matter where you are in your tree (even in the case of a new node being the root node). You will have to go through the motions *every time* you create a new node of: – L0j1k Feb 28 '13 at 04:08
  • Assigning a new node to a parent, if any. Assigning the new node's siblings to the parent's other children, if any. Assigning the parent.children collection to add your new node. You also have to check during node creation (or before) if the parent can have any more children. If not, you need to iterate to the next node that can accept children, or recurse further down your node list if you need to. – L0j1k Feb 28 '13 at 04:10
  • If you want to wait a little bit, I can edit this answer with some code to show you a blueprint of what you'll have to do in order to insert() no matter what kind of tree you have (and that it's parent-child linked so that each child knows who its parent is). – L0j1k Feb 28 '13 at 04:14
  • (Sorry, it's just that it's dinner time). I'll brb. – L0j1k Feb 28 '13 at 04:24
  • That's perfectly fine, I appreciate your responses – Alex Alex Feb 28 '13 at 04:28
  • 1
    Thank You for the pictures/implementation. I'm going to give it a shot and implement it and I'll ask more questions if i have trouble. Thank You! – Alex Alex Mar 01 '13 at 02:00
  • (Btw if you accept, it please don't upvote it, because I need one more accepted answer with a score of 0 to get a nice gold badge haha) :) – L0j1k Mar 01 '13 at 03:35
  • Why are you running a search on the data being inserted? Won't that always return null? – Alex Alex Mar 01 '13 at 03:46
  • You're searching for the node that you want to place your new node *after*. So you are searching for (in this case) your new node's `data - 1`, so that you can properly place the new node. – L0j1k Mar 01 '13 at 07:03
  • I've edited in my insert() method, Id love to hear your suggestions on it. Instead of searching, I just take in the parent and find its children, and it the new node to the other children. – Alex Alex Mar 01 '13 at 20:59