Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Detection of a loop in a linked tree (or linked list)

Reply
Thread Tools

Detection of a loop in a linked tree (or linked list)

 
 
mac
Guest
Posts: n/a
 
      05-27-2008
I found that with memory allocating techniques used nowadays
(addresses alignment, eg. on 32bit machines) one can detect loops in a
tree structure very fast, without using extra memory. This is due to a
possibility of storing extra information in unused bits of the tree
pointers (it works for linked lists too). One can say it is dangerous
or obvious, but I haven't seen it anywhere, and maybe it will be
useful for someone.

The procedure of loops detection has two steps:
1. Going through the tree with marking visited nodes (in pointers to
them) and checking if every node was visited only once (visiting node
twice means a loop)
2. Going through the tree once again and fixing tree pointers values,
to get the original tree structure
Below is an example code in C - you need only to add tree creation
function you like.

/*
* BEGINNING OF THE FILE
*/

#include "stdio.h"
#include "ctype.h"
#include "malloc.h"


#define LEAFS 2 //can be any integer >0

typedef struct t { //simple tree structure
int data;
struct t * leafs[LEAFS];
} tree;

/*
* test for cycles in a tree by using pointers reallignment
*/
int TestTreeAl(tree **root)
{
int i=0;
int j;
tree *p;
if (*root==NULL) return 0;
else
{
j=((int)(*root))%2;
if (j!=0) return 1; //if a node is marked with odd pointer - cycle
detected
p=*root; //remember the correct pointer
(int)*root=((int)*root)+1; //mark the node
for (i=0; i<LEAFS; i++) //visit all the leafs
if (TestTreeAl(&(p)->leafs[i])==1) return 1;
}
return 0;
}

/*
* fix allignment of tree pointers
*/
void FixTree(tree **root)
{ int i,j;
if (*root!=NULL)
{
j=(int)(*root)%2;
if (j!=0)
(int)*root=((int)*root)-1; //unmark previously marked node
for (i=0; i<LEAFS; i++)
{
if ((j!=0) && ((*root)->leafs[i]!=NULL))
FixTree(&((*root)->leafs[i]));
}
}
}

/*
* test linked tree for cycles
* returns 1 if any cycles were detectet, otherwise it returns 0
* (almost no additional memory used, only two visits in each tree
element)
*/
int TestTree(tree *root)
{
int i=TestTreeAl(&root); //testing for tree cycles with pointers
reallignment
FixTree(&root);
return i;
}

/*
* print all the data from the tree (sequence is not important)
*/
void print_tree_data(tree *root)
{
int i;
if (root!=NULL)
{
printf("%d\n",root->data);
for (i=0; i<LEAFS; i++)
print_tree_data(root->leafs[i]);
}
}

void main()
{
tree *root;
int i;

printf("* Example of a fast and memory efficient method \n* for
finding cycles in a tree structure (by Maciej Huk)\n\n");

root=NULL; //for NULL tree we will have no cycles
//make_tree(&root); //You need to define this function yourself

print_tree_data(root); //if tree was OK, the print makes no problems

i=TestTree(root);

printf("Before adding the cycles: ");
if (i==0) printf("NO CYCLES \n");
else printf("CYCLES DETECTED!\n");

/*
* try adding cycles to your tree (beware for the initial tree
structure!)
*/
//root->leafs[1]->leafs[0]=root->leafs[0]->leafs[1]; //example of a
cycle to try
//root->leafs[0]->leafs[0]->leafs[0]=root; //...and another one

i=TestTree(root);

printf("\nAfter adding the cycles: ");
if (i==0) printf("NO CYCLES \n");
else printf("CYCLES DETECTED!\n");

if (i==0) print_tree_data(root); //if there is no cycles we can
easily print the tree

printf("\n\nPress any key to exit...");
while (!getch());
}

/*
* END OF THE FILE
*/

Best regards,
Maciej
 
Reply With Quote
 
 
 
 
Jens Thoms Toerring
Guest
Posts: n/a
 
      05-27-2008
mac <(E-Mail Removed)> wrote:
> I found that with memory allocating techniques used nowadays
> (addresses alignment, eg. on 32bit machines) one can detect loops in a
> tree structure very fast, without using extra memory. This is due to a
> possibility of storing extra information in unused bits of the tree
> pointers (it works for linked lists too). One can say it is dangerous
> or obvious, but I haven't seen it anywhere, and maybe it will be
> useful for someone.


The trick to use unused bits to store extra information is
I guess about as old as there are computers - and the prob-
lems resulting from that kind of being clever also. I still
remember the Atari ST, where the CPU had 24 only address
lines but 32 bit wide pointers. So some guys decided to use
those upper "unused" bits for storing some extra information.
Worked all well and nicely until the Atari TT came out which
had 32 bit address lines and where none of these "clever"
programs did work anymore.

The whole thing is based on the assumption that the low order
bit is always 0. This may be the case on your machine but has
a good chance of being invalid on other architecures. And I
don't see why it would help to speed up the program. If you
have a dedicated element in the structure it can easily be
accessed. With your "trick" you have to do several extra
operations just to get at it and in the end you also have
to reset them again to make sure that you get back "legal"
pointers. All you win is a few bytes of memory for each
structure. On the other hand you need a pointer width of
memory in the function for testing the nodes which, if the
tree is rather one-sided could lead to using actually more
memory (probaly on the stack instead of in the heap where
stack memory is often a scarcer resource).

Finally, some lines of your program are invalid C like

> (int)*root=((int)*root)+1; //mark the node


since you can't cast a lvalue. If you insist on doing such
things do them correctly:

*root = ( tree * ) ( ( char * ) *root + 1 );

And an int is not necessarily suitable to store a pointer.
And the usual: main() is a function that returns an int,
not void.

And you probably know that your "test case" doesn't do
anything at all since you never allocate a single struc-
ture...
Regards, Jens
--
\ Jens Thoms Toerring ___ http://www.velocityreviews.com/forums/(E-Mail Removed)
\__________________________ http://toerring.de
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Triple nested loop python (While loop insde of for loop inside ofwhile loop) Isaac Won Python 9 03-04-2013 10:08 AM
Pattern detection and until loop in perl vrushali Software 1 12-15-2010 06:08 PM
infinite loop detection Steven Woody C Programming 10 08-10-2006 12:33 AM
B tree, B+ tree and B* tree Stub C Programming 3 11-12-2003 01:51 PM
Spanning Tree And Per Vlan Spanning Tree Amy L. Cisco 0 07-24-2003 10:01 PM



Advertisments