The Origin Forum
File Exchange
Try Origin for Free
The Origin Forum
Home | Profile | Register | Active Topics | Members | Search | FAQ | Send File to Tech support
 All Forums
 Origin Forum for Programming
 Forum for Origin C
 Find TreeNode Attribute use Array walk whole Tree

Note: You must be registered in order to post a reply.
To register, click here. Registration is FREE!

Screensize:
UserName:
Password:
Anti-Spam Code:
Format Mode:
Format: BoldItalicizedUnderlineStrikethrough Align LeftCenteredAlign Right Horizontal Rule Insert HyperlinkUpload FileInsert Image Insert CodeInsert QuoteInsert List
   
Message:

* HTML is OFF
* Forum Code is ON
Smilies
Smile [:)] Big Smile [:D] Cool [8D] Blush [:I]
Tongue [:P] Evil [):] Wink [;)] Clown [:o)]
Black Eye [B)] Eight Ball [8] Frown [:(] Shy [8)]
Shocked [:0] Angry [:(!] Dead [xx(] Sleepy [|)]
Kisses [:X] Approve [^] Disapprove [V] Question [?]

 
Check here to subscribe to this topic.
   

T O P I C    R E V I E W
TreeNode Posted - 01/19/2011 : 1:14:32 PM
Origin Ver. and Service Release Origin8 SR6
Operating System:Win XP

Hi all,

I want to search in a Tree for TreeNode with special Attribute.
For example the Attribute Label is "myID", and value is 7.

I want to check all TreeNodes in this Tree, if one of them got
this Attribute and the adequate value.

When TreeNode was found, a Reference should be returned, so that I can
manipulate this node.

The reason for my intention is, that I am using GETN macros for User-Interface.
When user change values in GetnBox-Dialog or something like that, event function should react on that.
In the event function I found out, that the parameter: (..., int nRow, ...) points to the
row of GetnBox-Dialog, in which user changed something.

When for example I want to react on user changed value of Drop-Down-List, and this List
is in the 5th row, I can check in event_function: if(nRow == 5) -> do something...

The annoying thing is, when I redesign my dialog, I have to adjust all the numbers I
used for checking in which row the dialog-element is positioned.
So I want to use IDs, that point to special dialog-elements (TreeNodes of the GetNBox-Tree)

The first problem that came up is, that I could not find a function, that checks ALL nodes of
a Tree, or a TreeNode, for example in OriginC Reference -> Global Functions -> Tree
And what is more, I need the function to return a reference to the found TreeNode, so that I can manipulate it.

I dont want to use a recursiv function to walk the tree, cause I got error message from
Origin while runtime: "Error found in pop stack" - but it found the TreeNode.
The code for recursiv function:
TreeNode& find_attr_tree_recursiv(const TreeNode& tr, int nID)
{
	bool bRet;
	int nVal = -1;
	
        // Search in all children of a TreeNode, childrens-childs and so on...
	foreach(TreeNode tn in tr.Children)
	{
		bRet = tn.GetAttribute("myID", nVal);
		if(nVal == nID)
			return tn;
		if(tn.Children.Count() != 0)
			find_attr_tree_recursiv(tn, nID);  // call function itself -> recursion
	}
		
	return tn;
}

void test_recursiv_find_method()
{
	Tree tr;
	TreeNode tn11, tn12, tn13, tn14, tn15,
	         tn21, tn22, tn23, tn24, tn25,
	         tnFound;
	
        // construct example tree
	tn11 = tr.AddTextNode("abcd11", "node11", 1);
	tn12 = tr.AddTextNode("abcd12", "node12", 1);
	tn13 = tr.AddTextNode("abcd13", "node13", 1);
	tn14 = tr.AddTextNode("abcd14", "node14", 1);
	tn15 = tr.AddTextNode("abcd15", "node15", 1);
	
	tn21 = tn11.AddTextNode("abcd21", "node21", 1);
	tn22 = tn12.AddTextNode("abcd22", "node22", 1);
	tn23 = tn13.AddTextNode("abcd23", "node23", 1);
	tn24 = tn14.AddTextNode("abcd24", "node24", 1);
	tn25 = tn15.AddTextNode("abcd25", "node25", 1);
	
        // set special "myID" Attribute to one TreeNode
	tn13.SetAttribute("myID", 7);
	
        // show found TreeNode
	tnFound = find_attr_tree_recursiv(tr, 7);
	out_tree(tnFound);
}


Code for iterativ function, that behaves not as I would expect:
bool walk_tree_iterativ_stack(const TreeNode& tr, int nID)
{
	TreeNode tn, tnTmp;
	Array<TreeNode&> tnArray;
	//tnArray.SetAsOwner(true); --> program crashes if Array set as owner
	
	int nRet, nVal = -1, nIndex = 0, nElements;
	bool bRet;
	
	nRet = tnArray.Add(tr);
	
	// Check all TreeNodes stored in Array, if one of them 
	// has special "myID"-Attribute
	while(nIndex < tnArray.GetSize() )
	{
		// check for "myID"-Attribute
		tnTmp = tnArray.GetAt(nIndex); 
		bRet = tnTmp.GetAttribute("myID", nVal);
		if(nVal == nID)
			return true;  // TreeNode found
		
		// If TreeNode has Childs --> put them into Array
		if(tnArray.GetAt(nIndex).Children.Count() != 0)
		{
			foreach(tn in tnArray.GetAt(nIndex).Children)
			{
				nRet = tnArray.Add(tn);
			}
		}
		nElements = tnArray.GetSize();
		
		// Increment "Stack-Pointer"
		nIndex++;
	}
	return false;  // TreeNode not found
}

void test_walk_tree_iterativ_stack_method()
{
	Tree tr;
	TreeNode tn11, tn12, tn13, tn14, tn15,
	         tn21, tn22, tn23, tn24, tn25,
	         tnFound;
	
	// Construct a example Tree with some nodes...
	tn11 = tr.AddTextNode("abcd11", "node11", 11);
	tn12 = tr.AddTextNode("abcd12", "node12", 12);
	tn13 = tr.AddTextNode("abcd13", "node13", 13);
	tn14 = tr.AddTextNode("abcd14", "node14", 14);
	tn15 = tr.AddTextNode("abcd15", "node15", 15);
	
	tn21 = tn11.AddTextNode("abcd21", "node21", 21);
	tn22 = tn12.AddTextNode("abcd22", "node22", 22);
	tn23 = tn13.AddTextNode("abcd23", "node23", 23);
	tn24 = tn14.AddTextNode("abcd24", "node24", 24);
	tn25 = tn15.AddTextNode("abcd25", "node25", 25);
	
	// Set "myID"-Attribute for one TreeNode
	tn13.SetAttribute("myID", 7);
	
	// search for TreeNode with special "myID"-Attribute
	bool bRet = walk_tree_iterativ_stack(tr, 7);
	
	// check if TreeNode was found
	if(bRet)
		out_str("TreeNode found!");
	else
		out_str("TreeNode NOT found!");
}


Something is wrong with behaviour of Array<TreeNode&>. Adding elements to it seems to work.
But when variable nIndex has value: "2", and gets the Element at this position in Array,
it gets an element, which I not expect at that index.

...pls have a look at it in debug mode.


|-- TreeNode
...|-- a??
...|-- ha!!
2   L A T E S T    R E P L I E S    (Newest First)
TreeNode Posted - 01/20/2011 : 1:12:37 PM
Hi Iris,

I overlooked, that this function returns the TreeNode, that it found.
I am using this fuction for my issue now, and it works fine.

Found also the macros, to add this ID to a TreeNode in GetN-Tree:
GETN_ID and GETN_ID_BRANCH for a branch.

Thank you very much!


|-- TreeNode
...|-- a??
...|-- ha!!
Iris_Bai Posted - 01/19/2011 : 10:50:48 PM
Hi,

Please use "DataID" (STR_DATAID_ATTRIB) as attribute name, then use function tree_get_node_by_dataid to find "DataID = 7" tree node recursively.

TreeNode trN;
bool bRecursive = true;
trN = tree_get_node_by_dataid( tr, 7, bRecursive ); 


Iris

The Origin Forum © 2020 Originlab Corporation Go To Top Of Page
Snitz Forums 2000