home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!mcsun!sun4nl!and!jos
- From: jos@and.nl (Jos Horsmeier)
- Newsgroups: comp.lang.c
- Subject: Re: To Recurse or NOT to recurse?
- Message-ID: <3842@dozo.and.nl>
- Date: 10 Nov 92 10:34:58 GMT
- References: <1992Nov6.185136.8055@netcom.com> <1992Nov10.003842.19169@asc386>
- Organization: AND Software BV Rotterdam
- Lines: 74
-
- In article <1992Nov10.003842.19169@asc386> mosmith@asc386 (Matt Smith) writes:
- |The question is whether to recusively desend a linked-list or
- |to do it iteraviely( a while loop). My expeience has
- |shown that the while loop is better in the long run.
- |
- |Reason: Recursion uses the stack to store the recusive stuff (hope
- |that's not too techy) which tends to blow up. I prefer the other
- |way
-
- As a rule of thumb, I always use the following reasoning:
-
- `Never use recursion when the size of the stack is
- linear proportional to the size of the problem.'
-
- Traversing a linked list with n elements takes up to n slots on the
- stack (and even a bit more for administration purposes) so I don't
- use recursion here.
-
- Even when recursion is `needed', most of the time one of the recursive
- branches can be eliminated, e.g finding an element in a sorted binary
- tree can (intuitively) be written as:
-
- tree_t *find(tree_t *t, data *d) {
-
- if (!t) /* sentinel */
- return NULL;
- else if (t->d == d) /* node found? */
- return t;
- else if (t->d > d) /* search left */
- return find(t->left, d);
- else /* search right */
- return find(tree->right, d);
-
- }
-
- The tail recursion can be eliminated by:
-
- tree_t *find(tree_t *t, data *d) {
-
- for (; t; t= t->right) /* search right otherwise */
-
- if (t->d == d) /* node found? */
- return t;
- else if (t->d > d) /* search left */
- return find(t->left, d);
-
- return NULL; /* sentinel */
- }
-
- Taking this example a bit further, the recursion can be totally
- eliminated by the following transformation:
-
- tree_t *find(tree_t *t, data *d) {
-
- while (t)
- if (t->d == d) /* node found */
- return t;
- else if (t->d > d) /* search right */
- t= t->left;
- else /* search left */
- t= t->right;
-
- return NULL; /* sentinel */
- }
-
- I'm a bit of an `optimization freak' myself and I always try to eliminate
- as much recursion as possible, because I still believe (and I know I'm
- wrong most of the time) that function calls cause a teensy weensy bit
- more overhead than simple iteration. But when the recursion violates
- my rule of thumb, I don't even think about recursion any further.
-
- kind regards,
-
- Jos aka jos@and.nl
-