4 Link List
4 Link List
Linked List
Linked List
A linked list is a data structure which is built from structures
and pointers.
It forms a chain of "nodes" with pointers representing the
links of the chain and holding the entire thing together.
A linked list can be represented by a diagram as follows:
Start
NULL
This linked list has four nodes in it, each with a link to the
next node in the series.
The last node has a link to the special value NULL, which any
pointer (whatever its type) can point to, to show that it is the
last link in the chain.
There is also another special pointer, called Start, which
points to the first link in the chain so that we can keep track
of it.
Defining the Data Structure for Linked List
The key part of a linked list is a structure, which holds the data for each
node (the name, address, age or whatever for the items in the list), and
most importantly, a pointer to the next node.
Here is the structure of a typical node:
struct node
{
char name[20]; // Name up to 20 chars
int age;
float weight;
node *nxt // Pointer to next node
};
node *start_ptr=NULL;
The important part of the structure is the line before the
closing curly brackets.
node *nxt
This gives a pointer to the next node in the list. This is the
only case in C++ where you are allowed to refer to a data
type (in this case node) before you have even finished
defining it.
A pointer called start_ptr has also been declared which will
permanently point to the start of the list.
To start with, there are no nodes in the list, which is
why start_ptr is set to NULL.
Adding a node to the end of the List
temp
undefined
We can refer to the new node as *temp, i.e. "the
node that temp points to".
if (start_ptr == NULL)
start_ptr = temp;
It is harder if there are already nodes in the list.
In this case, the secret is to declare a second pointer, temp2,
to step through the list until it finds the last node.
temp2 = start_ptr;
while (temp2->nxt != NULL)
{
temp2=temp2->nxt; //move to next node in the list
}
The loop will terminate when temp2 points to the last node
in the chain, and it knows when this happened because
the nxt pointer in that node will point to NULL.
When it has found it, it sets the pointer from that last node
to point to the node we have just declared:
temp2->nxt = temp;
NULL
The link temp2->nxt in this diagram is the link joining the
last two nodes.
The full code for adding a node at the end of the list is shown
below:
void add_node_end ( )
{ node *temp, *temp2; // temporary pointers
// reserve space for new node and fill it with data
temp=new node;
cout<< “Please enter the name of the person:”;
cin>> temp->name;
cout<< “Please enter the age of the person:”;
cin>> temp->age;
cout<< “Please enter the weight of the person:”;
cin>> temp->weight;
temp->nxt= NULL;
// set up link to this node
if (start_ptr == NULL)
start_ptr = temp;
else
{ temp2=start_ptr;
while (temp2->nxt != NULL)
{ temp2 = temp2->nxt; }
temp2->nxt = temp;
}
}
Displaying the list of nodes
Having added one or more nodes, we need to display the
list of nodes on the screen. This is comparatively easy to
do.
Here is the method:
Set a temporary pointer to point to the same thing as the start
pointer
If the pointer points to NULL, display the message "End of list"
and stop
Otherwise, display the details of the node pointed to by the
start pointer
Make the temporary pointer point to the same thing as
the nxt pointer of the node it is currently indicating
Repeat
The temporary pointer moves along the list, displaying
the details of the nodes it comes across
At each stage, it can get hold of the next node in the list
by using the nxt pointer of the node it is currently
pointing to
C++ code is as follows
temp=start_ptr;
do
{ if (temp == NULL)
cout<< “End of list “ << endl;
else
{
cout << “ Name: “ << temp->name << endl;
cout << “ Age: “ << temp ->age << endl;
cout << “ Weight: “ << temp->weight << endl;
temp = temp->nxt;
}
}
while (temp != NULL);
Check through this code, matching it to the method
listed above
It helps if you draw a diagram on paper of a linked list
and work through the code using the diagram
Deleting a Node from the List
When it comes to deleting nodes, we have three choices:
Delete a node from the start of the list
Delete one from the end of the list
Delete one from somewhere in the middle
Deleting a node from the start
We will start with deleting one from the start or from the
end
When a node is deleted, the space that it took up should be
reclaimed
Otherwise the computer will eventually run out of memory
space
This is done with the delete instruction as follows
start_ptr
NULL
temp
Now that the first node has been safely tagged (so that we can
refer to it even when the start pointer has been reassigned),
we can move the start pointer to the next node in the chain:
start_ptr = start_ptr->nxt ;
start_ptr
NULL
temp
delete temp ;
start_ptr
NULL
temp
Here if the function that deletes a node from the start of
the list
void delete_start_node ( )
{
node *temp;
temp = start_ptr;
start_ptr = start_ptr->nxt ;
delete temp;
}
Deleting a node from the end of the list is harder, as the
temporary pointer must find where the end of the list is by
hopping along from the start.
This is done using code that is almost identical to that used to
insert a node at the end of the list. It is necessary to maintain
two temporary pointers, temp1 and temp2.
The pointer temp1 will point to the last node in the list
and temp2 will point to the previous node.
We have to keep track of both as it is necessary to delete the
last node and immediately afterwards, to set the nxt pointer
of the previous node to NULL (it is now the new last node).
Look at the start pointer. If it is NULL, then the list is empty,
1. so
print out a "No nodes to delete" message.
2. Maketemp1 point to whatever the start pointer is pointing to.
3. If thenxtpointer of whattemp1 indicates is NULL, then we've
found the last node of the list, so jump to step 7.
4. Make another pointer,temp2p , oint to the current node in the
list.
5. Maketemp1point to the next item in thelist. Goto step 3.
6.If you get this far, then the temporary pointer, temp1,should
point to the last item in the list and the other temporary
pointer, temp2, should point to the second last item.
7. Delete the node pointed to bytemp1.
8. Mark thenxt pointer of the node pointed to bytemp2 as
NULL - it is the new last node.
Let's try it with a rough drawing.
This is always a good idea when you are trying to understand
an abstract data type.
Suppose we want to delete the last node from this list:
start_ptr
NULL
Firstly, the start pointer doesn't point to NULL, so we don't
have to display a "Empty list" message
Let's get straight on with step2 - set the pointer temp1 to
the same as the start pointer:
start_ptr
NULL
temp1
The nxt pointer from this node isn't NULL, so we haven't
found the end node
Instead, we set the pointer temp2 to the same node
as temp1
start_ptr
NULL
temp2 temp1
and then move temp1 to the next node in the list:
start_ptr
NULL
temp2 temp1
Going back to step 3, we see that temp1 still doesn't point
to the last node in the list, so we make temp2 point to
what temp1 points to
start_ptr
NULL
temp2 temp1
and temp1 is made to point to the next node along:
start_ptr
NULL
temp2 temp1
Eventually, this goes on until temp1 really is pointing to the
last node in the list, with temp2 pointing to the penultimate
node:
start_ptr
NULL
temp2 temp1
Now we have reached step 8. The next thing to do is to
delete the node pointed to by temp1
start_ptr
temp2 temp1
and set the nxt pointer of what temp2 indicates to NULL:
start_ptr
NULL
temp2
void delete_end_node ( )
{ node *temp1, *temp2;
if (start_ptr == NULL)
cout<<“ The list is empty” << endl;
else
{
temp1=start_ptr;
while (temp1->nxt != NULL)
{
temp2=temp1;
temp1=temp1->nxt;
}
delete temp1;
temp2->nxt=NULL;
}
}
Problem with the Code
If the list only contains one node, the code above will not
work properly.
This is because the function goes as far as the temp1 =
start_ptr statement, but never gets as far as setting
up temp2.
The code above has to be adapted so that if the first node
is also the last (has a NULL nxt pointer), then it is
deleted and the start_ptr pointer is assigned to NULL.
In this case, there is no need for the pointer temp2:
void delete_end_node ( )
{ node *temp1, *temp2;
if (start_ptr == NULL)
cout<<“ The list is empty” << endl;
else
{ temp1=start_ptr;
if (temp1->nxt==NULL)
{ delete temp1;
start_ptr=NULL;
}
else
{ while (temp1->nxt != NULL)
{ temp2=temp1;
temp1=temp1->nxt;
}
delete temp1;
temp2->nxt=NULL;
} }
}