473,395 Members | 1,624 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Recursive delete problems

The following function results in an infinite loop! After 5+ hours of
debugging, I am still unable to decipher what I am incorrectly. Any
assistance is greatly appreciated.

Thanks in advance,
Andrew

==========>Code<==========

//--------------------------------------------------------------------
//
// Recursive cRemove() function implemented in In-lab Exercise 3
//
//--------------------------------------------------------------------

template < class DT >
void List<DT>:: cRemove()

// Recursively removes all occurrences of the character 'c' from a list
// of characters. Moves cursor to the beginning of the list.

{
cRemoveSub(head);
cursor = head;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

template < class DT >
void List<DT>:: cRemoveSub ( ListNode<DT>*& p )

// Recursive partner to the cRemove() function.

{
ListNode<DT>* delete_node;
ListNode<DT>* prior_node;

if ( p == NULL )
{
return;
}
else if ((p->dataItem == 'c' || p->dataItem == 'C') && (p == head))
{
delete_node = p;
head = p = p->next;
delete delete_node;
cRemoveSub(p);
}
else if ((p->dataItem == 'c' || p->dataItem == 'C') && (p->next != 0))
{
delete_node = p;
p = p->next;
prior_node = head;
while(prior_node->next->dataItem != 'c' &&
prior_node->next->dataItem != 'C')
{
prior_node = prior_node->next;
}
delete delete_node;
prior_node->next = p;
cRemoveSub(p);
}
else if (p->next == 0)
{
delete p;
p = 0;
}
else
{
cout << "Else: " << '[' << p->dataItem
<< "]->[" << p->next->dataItem << ']' << endl;
cRemoveSub(p->next);
}
}
Jul 19 '05 #1
8 6168
"Andrew Edwards" <ed*******@spamfreeusa.com> wrote...
The following function results in an infinite loop! After 5+ hours of
debugging, I am still unable to decipher what I am incorrectly. Any
assistance is greatly appreciated.

Thanks in advance,
Andrew

==========>Code<==========

//--------------------------------------------------------------------
//
// Recursive cRemove() function implemented in In-lab Exercise 3
//
//--------------------------------------------------------------------

template < class DT >
void List<DT>:: cRemove()


Well, without seeing what 'List<>' is I wouldn't dare to recommend
anything. However, the usual scheme for deleting a singly-linked
list is:

void deleteListTailFirst(ListNode *plistnode)
{
if (plistnode->next != NULL)
deleteListTailFirst(plistnode->next); // recurse

deleteAllDataIn(plistnode); // non-recursive part
}

I recommend scrapping your solution and rewriting it afresh.

Victor
Jul 19 '05 #2
On Sat, 19 Jul 2003 19:57:00 GMT, "Andrew Edwards" <ed*******@spamfreeusa.com> wrote:
The following function results in an infinite loop! After 5+ hours of
debugging, I am still unable to decipher what I am incorrectly.
The question is then, what exactly are you trying to achieve?

Details do matter.
Any assistance is greatly appreciated.

Thanks in advance,
Andrew

==========>Code<==========

//--------------------------------------------------------------------
//
// Recursive cRemove() function implemented in In-lab Exercise 3
//
//--------------------------------------------------------------------

template < class DT >
void List<DT>:: cRemove()
The name "cRemove" is not very suggestive of what this routine
is intended to achieve.

When you can express something in code instead of comment(s),
preferentially choose to express it in code.

The compiler can't check comments, and they're not apparent where
the routine is used.
// Recursively removes all occurrences of the character 'c' from a list
// of characters. Moves cursor to the beginning of the list.

{
cRemoveSub(head);
cursor = head;
}
Having a cursor (in more general terms, an iterator) built-in in the
list abstraction isn't necessarily a good idea.

In some cases it might make sense, for example if there should never
be more than exactly one iterator.

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

template < class DT >
void List<DT>:: cRemoveSub ( ListNode<DT>*& p )

// Recursive partner to the cRemove() function.

{
ListNode<DT>* delete_node;
ListNode<DT>* prior_node;

if ( p == NULL )
{
return;
}
else if ((p->dataItem == 'c' || p->dataItem == 'C') && (p == head))
Here's the start of your problems. This routine should absolutely
not have to bother with 'head' and other external things. It should
just delete nodes.

In addition, consider using a function that returns the uppercase of
a given character.
{
delete_node = p;
head = p = p->next;
Such multiple assignments are evil.

delete delete_node;
cRemoveSub(p);
}
else if ((p->dataItem == 'c' || p->dataItem == 'C') && (p->next != 0))
{
delete_node = p;
p = p->next;
prior_node = head;
while(prior_node->next->dataItem != 'c' &&
prior_node->next->dataItem != 'C')
{
prior_node = prior_node->next;
}
What's this supposed to accomplish, except an infinite loop?

delete delete_node;
prior_node->next = p;
cRemoveSub(p);
}
else if (p->next == 0)
{
delete p;
And what's the purpose of this?

p = 0;
}
else
{
cout << "Else: " << '[' << p->dataItem
<< "]->[" << p->next->dataItem << ']' << endl;
This looks like debugging/trace output.

cRemoveSub(p->next);
As a general rule, don't manipulate data structures in debugging code.

}
}

Here's one way to recursively delete all nodes containing a given
letter (case-independent) in a singly linked zero-terminated list:
char toUpper( char c )
{
return static_cast<char>(
std::toupper( static_cast<unsigned char>( c ) )
);
}

void deleteNodes( Node*& pHead, char upperCaseCh )
{
"Store pointer to rest of list in local variable pTail"
if( toUpper( pHead->value ) == upperCaseCh )
{
"Delete the head node"
}
"Recursively delete the rest of the list"
}
You should not translate the pseudo-code to more than 4 statements.

In "real" C++ code consider using standard library containers
such as e.g. std::list instead.

Jul 19 '05 #3
"Alf P. Steinbach" <al***@start.no> wrote:
The question is then, what exactly are you trying to achieve?

Details do matter.


I'm trying to remove all occurrences of the character 'c' from list.
Jul 19 '05 #4

"Alf P. Steinbach" <al***@start.no> wrote:
The name "cRemove" is not very suggestive of what this routine
is intended to achieve.

When you can express something in code instead of comment(s),
preferentially choose to express it in code.

The compiler can't check comments, and they're not apparent where
the routine is used.

Quite understandable! The function names and list interface, however, are
not my decision. They cannot be changed because there is test code already
written with these names to which I have no access.

Having a cursor (in more general terms, an iterator) built-in in the
list abstraction isn't necessarily a good idea.

In some cases it might make sense, for example if there should never
be more than exactly one iterator.

Again, the interface is predesigned and cannot be changed.
Here's the start of your problems. This routine should absolutely
not have to bother with 'head' and other external things. It should
just delete nodes.

In addition, consider using a function that returns the uppercase of
a given character.

I'm trying to remove all occurrence of 'c' or 'C' form the list. That, I
thought, requires that I begin at the head of the list.

Such multiple assignments are evil.
Point taken!

What's this supposed to accomplish, except an infinite loop?

It's supposed to remove the character from the "middle" of the list.
And what's the purpose of this?
Delete the character if it's at the end of the list.

This looks like debugging/trace output. <snip> As a general rule, don't manipulate data structures in debugging code.


What is the best way to do debugging? I have a text editor and Borland's C++
Builder commandlinetools v5.5.1. I'm new to programming so my art of
debugging is severely underdeveloped.
Jul 19 '05 #5
"Andrew Edwards" <ed*******@spamfreeusa.com> wrote...

"Victor Bazarov" <v.********@attAbi.com> wrote:
Well, without seeing what 'List<>' is I wouldn't dare to recommend
anything.


Here are the two constructors I use:

template < class DT >
ListNode<DT>:: ListNode ( const DT& initData, ListNode* nextPtr )
: dataItem(initData)
, next(nextPtr)
{
}

template < class DT >
List<DT>:: List(int ignored)
// Constructor. Creates and empty list. The argument is provided
// for call compatability with the array implementation and is
// ignored.
{
cursor = head = NULL;
}

However, the usual scheme for deleting a singly-linked list is:


Note that I'm not trying to delete the list. I can do that. I'm trying to
remove all occurrences of 'c' from the list.


Sorry, I must have misunderstood. Why do you need recursion, then?
Just traverse the list and extract all the 'c' elements. Here is
pseudocode:

void removeFromList(ListNode* p, ListNode* pprev)
{
if (pprev)
pprev->next = p->next;
delete p;
}

void removeFromListAllThatHave(const ValueType& value)
{
while (head && head->getValue() == value) // remove the head
{
ListNode* newhead = head->next;
removeFromList(head, 0);
head = newhead;
}

if (head) // something remains in the list
{
ListNode* p = head;
while (p->next)
{
if (p->next->getValue() == value)
removeFromList(p->next, p);
else
p = p->next;
}
}
}

I think that should do it...

Victor
Jul 19 '05 #6

"Victor Bazarov" <v.********@attAbi.com> wrote:
Sorry, I must have misunderstood. Why do you need recursion, then?


Using iteration over recursion is not an option. This must be done with
recursion.
Jul 19 '05 #7
"Andrew Edwards" <ed*******@spamfreeusa.com> wrote in message
news:go*********************@twister.southeast.rr. com...
The following function results in an infinite loop! After 5+ hours of
debugging, I am still unable to decipher what I am incorrectly. Any
assistance is greatly appreciated.

Thanks in advance,
Andrew

==========>Code<==========

//--------------------------------------------------------------------
//
// Recursive cRemove() function implemented in In-lab Exercise 3
//
//--------------------------------------------------------------------

template < class DT >
void List<DT>:: cRemove()

// Recursively removes all occurrences of the character 'c' from a list
// of characters. Moves cursor to the beginning of the list.

{
cRemoveSub(head);
cursor = head;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

template < class DT >
void List<DT>:: cRemoveSub ( ListNode<DT>*& p )

// Recursive partner to the cRemove() function.

{
ListNode<DT>* delete_node;
ListNode<DT>* prior_node;

if ( p == NULL )
{
return;
}
else if ((p->dataItem == 'c' || p->dataItem == 'C') && (p == head))
{
delete_node = p;
head = p = p->next;
delete delete_node;
cRemoveSub(p);
}
else if ((p->dataItem == 'c' || p->dataItem == 'C') && (p->next != 0))
{
delete_node = p;
p = p->next;
The above line changes either 'head' or the 'next' member of a node, because
'p' is a reference to one of those. This means that you have inadvertently
taken the node with the 'c' out of the list.
prior_node = head;
while(prior_node->next->dataItem != 'c' &&
prior_node->next->dataItem != 'C')
{
prior_node = prior_node->next;
}
The reference problem causes this loop to find the the second node with a
'c'. If there isn't one it will just fly off into space.
delete delete_node;
prior_node->next = p;
cRemoveSub(p);
}
else if (p->next == 0)
{
delete p;
Here you are deleting the tail node whether it has a 'c' or not.
p = 0;
}
else
{
cout << "Else: " << '[' << p->dataItem
<< "]->[" << p->next->dataItem << ']' << endl;
cRemoveSub(p->next);
}
}


DW

Jul 19 '05 #8
Andrew Edwards <ed*******@spamfreeusa.com> wrote in message
news:jn*********************@twister.southeast.rr. com...

"Victor Bazarov" <v.********@attAbi.com> wrote:
Sorry, I must have misunderstood. Why do you need recursion, then?


Using iteration over recursion is not an option. This must be done with
recursion.


void List::remove_node(node *n, node *parent) // private member
function
{
if(parent) parent->next = n->next;
else m_head = n->next;
delete n;
}

void List::remove_all_with_value(const value_type& val) // public member
function
{
remove_all_with_value_recurse(val, m_head, NULL);
}

void List::remove_all_with_value_recurse(const value_type& val, node *n,
node *parent) // private member function
{
assert(n != NULL);
if(n->next) remove_all_with_value_recurse(n->next, n);
if(n->val == val) remove_node(n, parent);
}

I think this works (I haven't got access to a compiler for a couple of days
so checking it is problematic). I've skipped all the usual template stuff to
make it easier to understand.

HTH,

Stuart.
Jul 19 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

19
by: Carlos Ribeiro | last post by:
Hello all, Here I am using some deeply nested, tree-like data structures. In some situations I need to traverse the tree; the old-style way to do it is to write a recursive method on the node...
5
by: betterdie | last post by:
Dear guru I want to delete all file and folder recursivly under php code, can anyone give me commend for this. Thank very much
9
by: Paul | last post by:
I'm trying to make get my app to delete all the files in a specified folder and all the files within the folders of the specified folder. e.g. Folder 1 contains three files (File1, File2, File3)...
5
by: purushneel | last post by:
Hi, I work primarily on Oracle databases. I am trying to convert a recursive stored procedure written in Oracle to DB2. Does DB2 UDB v8.2 (Windows/AIX) supports recursive stored procedures ??...
3
by: Robert Ludig | last post by:
I am fairly new to SQL and I am currently trying to create a SQL table (using Microsoft SQL) that has a recursive relationship, let me try to explain: I have a piece of Data let's call it "Item"...
4
by: AndrewD | last post by:
Hey C++ folks, I created this today, just for fun. You can make object allocation for any class around 6 times faster, simply by doing the following. class MyClass : public...
10
by: AsheeG87 | last post by:
Hello Everyone! I have a linked list and am trying to include a recursive search. However, I am having trouble understanding how I would go about that. I don't quite understand a recursive...
31
by: matthewslyman | last post by:
I have an unusual design and some very unusual issues with my code... I have forced Access to cooperate on everything except one issue - record deletion. My form design involves a recursively...
2
by: presencia | last post by:
Hi everyone, I have written a small program running fine until a Segmentation fault. Using a debugger I have localized the function the fault happens in. The Signal appears during a call to delete...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.