CS162 - 4B TABLE OF CONTENTS Continue with the last lecture Last time with Singly Linked List
we have inserted x
before k
. Now we will do the similar thing using Doubly Linked List
With Singly Linked List we can’t Insert x
before k
with our cur position right at k
but can we do that with Doubly Linked List?
Let’s give it a try!
Problem statements Insert x
before k
in a DLL.void insertB4K ( DNode * & pHead , int x , int k );
Remove the first k
from a DLL.void delete1K ( DNode * & pHead , int k );
Remove all k
’s from a DLL.void deleteAllKs ( DNode * & pHead , int k );
Problem 1 Student’s code 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void insertB4K ( DNode * & pHead , int x , int k ) {
if ( pHead == nullptr )
return ;
if ( pHead -> data == k ){
insertAtBeginning ( pHead , x )
return ;
}
for ( DNode * cur = pHead ; cur != nullptr ; cur = cur -> pNext ){
if ( cur -> data == k ){
DNode * tmp = new DNode ;
tmp -> data = x ;
tmp -> pPrev = cur -> pPrev ;
cur -> pPrev -> pNext = tmp ;
tmp -> pNext = cur ;
cur -> pPrev = tmp ;
break ;
}
}
}
Discussion The code is okay, though some modifications can be made.
If we remove the if statement
at line 4
, is it okay?Yes, but we have to make some modifications at line 13
because in case cur == pHead
and cur
is not pointing to any DNode
(the DLL is empty). Can we remove the if statement
at line 2
?Yes, because if pHead == nullptr
it will not run the for loop
. Does line 12
safe?Yes, it will handle the special case when cur->pPrev == nullptr
which we are concerning. Modified code 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void insertBeforeK ( DNode * & pHead , int x , int k ) {
// if(pHead == nullptr)
// return;
// if(pHead->data == k){
// insertAtBeginning(pHead, x)
// return;
// }
for ( DNode * cur = pHead ; cur != nullptr ; cur = cur -> pNext ){
if ( cur -> data == k ){
DNode * tmp = new DNode ;
tmp -> data = x ;
tmp -> pPrev = cur -> pPrev ;
//-----------------------------------//
if ( cur -> pPrev ) cur -> pPrev -> pNext = tmp ;
else pHead = tmp ;
//-----------------------------------//
tmp -> pNext = cur ;
cur -> pPrev = tmp ;
break ;
}
}
}
Problem 2 Student’s code 1
2
3
4
5
6
7
8
9
10
11
12
13
14
void delete1K ( DNode * & pHead , int k )
{
for ( DNode * cur = pHead ; cur ; cur = cur -> pNext ) {
if ( cur -> data == k ) {
cur -> pNext -> pPrev = cur -> pPrev ;
if ( cur -> pPrev )
cur -> pPrev -> pNext = cur -> pNext ;
else
pHead = cur -> pNext ;
delete cur ;
break ;
}
}
}
Discussion We should change break
to return
. They forget to check the nulity of cur
at line 5
Fixed code 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void delete1K ( DNode * & pHead , int k )
{
for ( DNode * cur = pHead ; cur ; cur = cur -> pNext ) {
if ( cur -> data == k ) {
//-------------------------------//
if ( cur -> pNext )
cur -> pNext -> pPrev = cur -> pPrev ;
//-------------------------------//
if ( cur -> pPrev )
cur -> pPrev -> pNext = cur -> pNext ;
else
pHead = cur -> pNext ;
delete cur ;
break ;
}
}
}
Problem 3 Student’s code 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void DelAllks ( DNode *& pHead , int k ){
insertAtBeginning ( pHead , - 1 );
for ( DNode * cur = pHead -> pNext ; cur ; cur = cur -> pNext ){
if ( cur -> data == k ){
if ( cur -> pNext )
cur -> pNext -> pPrev = cur -> pPrev ;
cur -> pPrev -> pNext = cur -> pNext ;
DNode * tmp = cur ;
cur = cur -> pPrev ;
delete tmp ;
}
}
delete1K ( pHead , - 1 );
}
Discussion The idea of the dummy node -1
is good, but is it necessarilly?No, it’s not necessarilly, notice that the order of deleting is not important, so we can treat the first node as the dummy node we desired. Fixed code 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void DelAllks ( DNode *& pHead , int k ){
//insertAtBeginning(pHead, -1);
for ( DNode * cur = pHead -> pNext ; cur ; cur = cur -> pNext ) {
if ( cur -> data == k ) {
if ( cur -> pNext )
cur -> pNext -> pPrev = cur -> pPrev ;
cur -> pPrev -> pNext = cur -> pNext ;
DNode * tmp = cur ;
cur = cur -> pPrev ;
delete tmp ;
}
}
//delete1K(pHead, -1);
delete1K ( pHead , k );
}
Discussion Oh no! Because the dummy node is deleted, the trying to access into the pHead
in line 3
didn’t check the nulity. They tried to play around with the code in line 17
. But for the efficiency’s sake, when the DLL doesn’t have k
anymore, delete1K()
will iterate through the list for nothing. Fixed code 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void DelAllks ( DNode *& pHead , int k ){
//insertAtBeginning(pHead, -1);
if ( ! pHead ) return ;
for ( DNode * cur = pHead -> pNext ; cur ; cur = cur -> pNext ) {
if ( cur -> data == k ) {
if ( cur -> pNext )
cur -> pNext -> pPrev = cur -> pPrev ;
cur -> pPrev -> pNext = cur -> pNext ;
DNode * tmp = cur ;
cur = cur -> pPrev ;
delete tmp ;
}
}
//delete1K(pHead, -1);
if ( pHead -> data == k )
delete1K ( pHead , k );
}
We are using DLL but the code make it seems like we still code in SLL phylosophy.
Teacher’s code 1
2
3
4
5
6
7
8
9
10
11
12
13
14
void DelAllks ( DNode *& pHead , int k ) {
for ( DNode * cur = pHead ; cur ;)
if ( cur -> data == k ) {
if ( cur -> pNext )
cur -> pNext -> pPrev = cur -> pPrev ;
if ( cur -> pPrev )
cur -> pPrev -> pNext = cur -> pNext ;
else pHead = pHead -> pNext ;
DNode * tmp = cur ;
cur = cur -> pNext ;
delete tmp ;
}
else cur = cur -> pNext ;
}