Double ended linked list remove node

Jan 7, 2011 at 7:42pm
I'm attempting to add a Remove(Class position); function to my double ended linked list, however I'm struggling. Could anyone provide any tips or code to get me started? It's my last function before finishing and it's doing my head in!
Jan 7, 2011 at 8:24pm
[A] <-> [B] <-> [C]
[A] <-> [C]  [B]
Suppose that you got a pointer to the cell you want to delete (by instance B).
You need to adjust the links, from the previous and next cell.
1
2
3
4
A = p->prev;
C = p->next;
A->next = C;
C->prev = A;
Jan 7, 2011 at 8:38pm
...
Last edited on Jan 7, 2011 at 10:56pm
Jan 7, 2011 at 10:08pm
Sort of, but remove line 4 and use position instead of temp. You might also want to keep track of a size variable.

Also, when is this ever equal to NULL?
Jan 7, 2011 at 10:43pm
...
Last edited on Jan 7, 2011 at 10:57pm
Jan 7, 2011 at 10:45pm
If you initialize in the constructor of ListElement the links to the next and previous node with NULL, which is a good idea, then you can apply the following.

1
2
3
4
5
6
7
~ListElement ()
{
	if ( Previous() ) // guarding
		Previous()->mNext = Next();
	if ( Next() ) // guarding
		Next()->mPrev = Previous();
}

EDIT: Copy pasted some of your code and forgot to correct my version for use in class scope.
Then simply:
1
2
3
4
void Remove(ListElement *position)
{
	delete position;
}


No matter how you choose to implement the method Remove, don't forget the guarding conditions or you will end up with seg. faults.

Regards

EDIT: The above is ok, but add the conditions that guard against NULL and skip the position = NULL part. It does nothing, because it only assigns to a local variable. The destructor method IMHO is still somewhat preferable, because it guarantees that a node is unlinked from the list before it is destroyed. It is more robust.
Last edited on Jan 7, 2011 at 10:51pm
Jan 7, 2011 at 10:50pm
What exactly is temp in the destructor and where is it created?
Jan 7, 2011 at 10:53pm
Made a mistake, but apparently corrected it too late.
Jan 7, 2011 at 10:56pm
Thank you simeonz, that was exactly what I was looking for!
Jan 17, 2011 at 6:23pm
Hey everyone, I've finally reached the end of this assignment, and would like one last additional piece of information.

At the moment, I'm using these functions but with different guarding nodes due to runtime errors I get. It's working well, but at the moment I'm need to work on a function to remove my self contained node class from main.

It needs to remove nodes from the entire list then deallocate itself.

At the moment my remove function looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
	void DestroyList()
	{
		ListElement *iter = this;

		for ( ; iter->mNext != NULL; iter = iter->mNext)
		{
			if(mPrev && mNext)
			{
				mPrev->mNext = mNext;
				mNext->mPrev = mPrev;
			}
		}

		for ( ; iter->mPrev != NULL; iter = iter->mPrev)
		{
			if(mPrev && mNext)
			{
				mPrev->mNext = mNext;
				mNext->mPrev = mPrev;
			}
		}
                delete this;
	}


I'm attempting to remove all the nodes on the right, then all the nodes on the left, and then delete the list itself since it was assigned with new in main(). Any hints where I'm going wrong?

Cheers!
Jan 17, 2011 at 6:36pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
	void DestroyList()
	{
		ListElement *iter = this;

		for ( ; iter->mNext != NULL; iter = iter->mNext)
		{
			if(mPrev && mNext) //you never change mPrev or mNext
			{
				mPrev->mNext = mNext;
				mNext->mPrev = mPrev;
			}
		}

		for (/*iter = this*/ ; iter->mPrev != NULL; iter = iter->mPrev) //so you don't go back unnecessary
		{
			if(mPrev && mNext)
			{
				mPrev->mNext = mNext;
				mNext->mPrev = mPrev;
			}
		}
                delete this; //dangerous
	}

You don't delete anything except the caller node (and if it was not dynamic allocated, crash).

Stop erasing your posts. Others could learn from that.

Edit: it is the last statement, but I don't know if it is safe to explicit destroy you.
Last edited on Jan 17, 2011 at 6:41pm
Jan 17, 2011 at 7:08pm
It does unfortunately crash. How else will I be able to remove from within the function though? Aside from that, I see when I was editing the function I forgot to add another iterator again, thanks for pointing that out...

As for never changing mPrev or mNext, if I remove the guards, it fails due to either not having a next or prev node...

***EDIT***

I also felt it necessary to include the fact that my destructor already contains:

1
2
3
4
5
6
7
8
9
	~ListElement()
	{
		//Guarding if statement.
		if(mPrev && mNext)
		{
			mPrev->mNext = mNext;
			mNext->mPrev = mPrev;
		}
	}
Last edited on Jan 17, 2011 at 7:49pm
Jan 18, 2011 at 3:46am
ne555 wrote
Stop erasing your posts. Others could learn from that.


Agreed, it also makes it easier to help when I can see more code as I'm only 2 semesters into c++.

I dont understand why you delete one half then the other, doesnt seem tree structured. I'd
just set a "current" pointer to the first node and iterate through deleting.

My destructor
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//destructor
//delete all Nodes
template <class T>
DoublyLinkedList<T>::~DoublyLinkedList()
{
	GoFirst();
	while(current->next != last)
	{
		current = current->next;
		DeleteCurrent();
	}

	delete first;
	delete last;
}

//sets current to the previous node
//then deletes the current node
template <class T>
void DoublyLinkedList<T>::DeleteCurrent()
{
	//error if list is empty and if
	//attempt to delete first or last
	if(first->next == last || current == last)
		throw Error(3);
	else if (current == first)
		throw Error(2);
	else
	{
		//set temp pointers 
		//and set temp as new current
		Node* temp = current->prev;
		temp->next = current->next;
		current->next->prev = temp;
		delete current;
		current = temp;
	}
}

Jan 18, 2011 at 3:49am
Managed to solve my own problem. This is how I destroyed my entire list. Since it's self contained this suits my purposes. I then deleted in main() to get rid of the main pointer since you are unable to delete *this.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
	void DestroyList()
	{
		ListNode *iter = this, *temp;

		while(iter != NULL) //while the list is not empty
		{
			temp = iter; //store the current node.
			iter = iter->next; //visit the next node
			
			if(temp->prev)
				temp->prev = NULL;
			if(temp->next)
				temp->next = NULL;
		}
	}
Jan 18, 2011 at 4:29am
That seems a memory leak. You are making your nodes inaccessible and you are not deleting them.
If you are having a main pointer, from which you handle everything, why don't just make a separate class list?
And if the nodes are encapsulated, you will no have the problem of delete or not delete.
Topic archived. No new replies allowed.