0% found this document useful (0 votes)
35 views

Chapter 4. Linked List - Notes

The document discusses data structures, specifically static and dynamic types, with a focus on linked lists as a dynamic data structure that allows for efficient insertion and deletion of nodes. It explains the structure of a linked list, how to define it in C++, and the processes for adding nodes, displaying the list, and searching for nodes. The document emphasizes the advantages of dynamic data structures over static ones, particularly in terms of memory utilization and flexibility.

Uploaded by

abdu ayehu
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
35 views

Chapter 4. Linked List - Notes

The document discusses data structures, specifically static and dynamic types, with a focus on linked lists as a dynamic data structure that allows for efficient insertion and deletion of nodes. It explains the structure of a linked list, how to define it in C++, and the processes for adding nodes, displaying the list, and searching for nodes. The document emphasizes the advantages of dynamic data structures over static ones, particularly in terms of memory utilization and flexibility.

Uploaded by

abdu ayehu
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 25

4.

Data Structures

Data structures can be divided into two types: static data structures and dynamic data
structures. Static data structures cannot change their form during program execution. A C++
array is an example of a static data structure. Arrays (and static data structures in general)
have at least two limitations: their size has to be known at compile-time (This has its own
drawbacks. If you construct an array with space for n, tomorrow you may need n+1.); and the
data in the array are stored in a continuous block of computer memory (as shown in the figure
bellow) , which means that inserting, and deeting an item in the middle of the array requires
shifting other data in the array.

These limitations can be overcome by using dynamic data structures. A dynamic data
structure can change its form during program execution. Dynamic data structures, when used
well, can be an extremely powerful tool for the programmer, especially when solving
complex problems. Linked lists are one example of a dynamic data structures. There are two
types of linked lists singly linked lists and doubly linked lists. Each of them are discussed in
section 3.2 and 3.3 respectively.

Despite the diversity of ADTs that are defined to solve a problem, a large class of computing
applications involve generic manipulation of data objects (whatever the objects are) using
operations like insertion, deletion, searching. Therefore, we usually discuss ADTs that store
data objects (we are not being specific to what type of data they store) and allow certain
operations like inserting at the end or deleting at the beginning. These types of ADTs are
called standard ADTs. In this chapter we will consider Stack, Queue, Graph, Tree ADTs.
These standard ADTs are very common in computer science and have a wide variety of
applications.

4.2. Linked Lists

1
In order to avoid the linear cost of insertion and deletion, we need to ensure that the list is not
stored contiguously, since otherwise entire parts of the list will need to be moved. Figure 1
shows the general idea of a linked list.

The linked list consists of a series of structures, which are not necessarily adjacent in
memory. Each structure contains the element and a pointer to (containing the address of) a
structure containing its successor. We call this the next pointer. The last cell's next pointer
points to NULL (meaning nothing after this)

Figure 1. A Linked List

Recall that a pointer variable is just a variable that contains the address where some other
data is stored. Thus, if p is declared to be a pointer to a structure, then the value stored in p is
interpreted as the location, in main memory, where a structure can be found. Figure 2 shows
the actual representation of the list in Figure 1. The list contains for structures, which happen
to reside in memory locations 1000, 800, 600, and 315 respectively. The next pointer in the
first structure has the value 800, which provides the indication of where the second structure
is. The other structures each have a pointer that serves a similar purpose. Of course, in order
to access this list, we need to know where the first cell can be found. A pointer variable can
be used for this purpose (We usually call this start or start_ptr). It is important to remember
that a pointer is just a number. For the rest of this chapter, we will draw pointers with arrows,
because they are more illustrative.

Figure 2 Linked list with actual pointer values

Because the node contains a link to the next element in the list, nodes can be located
anywhere in memory, inserting and deleting nodes in the middle of the list is easy. The delete
command can be executed in one pointer change. Figure 3 shows the result of deleting the
third element in the original list. The insert command requires obtaining a new node from the
system and then executing two pointer maneuvers. The general idea is shown in Figure 4.
The dashed line represents the old pointer.

2
Figure 3 Deletion from a linked list

Figure 4 Insertion into a linked list

Also, there is flexible space use by dynamically allocating using new operator whenever
space for each node as needed (See later sections for detail). This implies that one need not
know the size of the list in advance. Therefore, Memory is efficiently utilized.

4.2.1. Defining the data structure for a linked list

How can we code a singly linked list in C++? The key part of a linked list is a self referential
structure, which holds the data for each node (In this case; the name, address, age or whatever
for the items in the list), and, most importantly, a pointer to the next node. Each node in the
linked list shown in Figure 1 is a variable of the following structure definition:

struct node

char name[20]; // Name of up to 20 letters

int age;

float height; // In metres – 1.8 to mean 1.8 meter

node *nxt; //Pointer to next node

};

In the previous structure definition defines the data that every node holds is the name,
address, age, height of a person, and the nxt member is used to link together nodes to form
the linked list. Note that nxt is defined to point to a node because the next member in the
linked list is a node of the same type.

The first problem that we face is how to add a node to the list. Whenever we want to use a
new node, we need to reserve memory for it. This is done using the new statement as
follows:

3
node * temp = new node;

The above line of code uses the new operator to reserve memory for a node and to return the
address of this node in memory and puts it in pointer temp. Now, once a list node is created,
how do we refer to the information it comprises—its name, age, height and its nxt? We have
already seen the basic operations that we need for this task in section 3.1.1: We simply
dereference the pointer as *temp, then use the structure member names—the name in the
node referenced by pointer temp is (*temp).name and the nxt is (*temp).nxt. When the fields
of this structure are referred to, brackets should be put round the *temp part, as otherwise the
compiler will think we are trying to refer to the fields of the pointer. Alternatively, we can
use the arrow pointer notation as temp->name and temp->nxt, which are equivalent to
(*temp).name and (*temp).nxt. We will use the arrow notation, since it provides a simpler
mechanism, in the rest of this course.

Having declared the node, we fill in the details of the person, i.e. the name, age, address or
whatever:

strcpy(temp->name, “Fred”);

temp->age = 23;

temp->height = 1.7;

The second problem that we face is how to create the list. To tackle this; we declare a
pointer called start_ptr that 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.

node *start_ptr = NULL;

4
Having set up the information, we have to decide what to do with the pointers (links).
Of course, since the list is empty to start with, there's no problem - just set the Start
pointer (start_ptr) to point to this node (i.e. set it to the same value as temp):

start_ptr = temp;

temp->nxt = NULL;

The second line sets the pointer from this node to the next to NULL, indicating that this node,
when it is inserted in the list, will be the last node.
start_ptr
temp

How can we use this definition to create the list in Figure 5?

Figure 5. A two node list

One way is to first generate the ‘Fred’ node, and then the ‘Sue’ node. We have defined a
single structure (node), but we will have many instances of this structure (‘Fred’ node, and
finally the ‘Sue’ node), one for each node that we want to use. We therefore create two nodes
in the same manner as we did for temp previously.

node * temp = new node; //points to Fred node

node * temp2 = new node; //points to Sue node

//Then we fill them with data

strcpy(temp->name, “Fred”);

temp->age = 23;

temp->height = 1.7;

strcpy(temp2->name, “Sue”);

temp2->age = 27;

temp2->height = 1.2;

5
We first declare a pointer called start_ptr that will permanently point to the start of the list as
we did in the previous section.

struct node *start_ptr = NULL;

start_ptr
temp

start_ptr

Then we have to decide what to do with the pointers (links). temp, which points to Fred node,
need to be added at first (meaning, make the start_ptr point to temp) as:

start_ptr = temp;

start_ptr start_ptr
temp temp

Then temp2, which points to Sue node, need to be temp’s (Fred node’s next node). This can
be done as follows:

temp->nxt = temp2;

temp2nxt = NULL;

The first line sets the pointer from temp’s next to temp2, indicating that this node, when it is
inserted in the list, will be point to another node (temp2). The second line sets the pointer
from temp2’s next to to NULL, indicating that this node, when it is inserted in the list, will be
the last node.

6
3.2.3. Adding a node to the list

The first problem that we face is how to add a node to the list. For simplicity's sake, we will
assume that it has to be added to the end of the list, although it could be added anywhere in
the list (a problem we will deal with later on).

We have defined a single structure (node), but we will have many instances of this structure,
one for each node that we want to use. Memory allocation is a central consideration in the
effective use of linked lists. Whenever we want to use a new node, we need to reserve
memory for it. This is done using the new statement as follows:

node * temp = new node;

The above line of code uses the new operator to reserve memory for a node and to return the
address of this node in memory and puts it in pointer temp. Now, once a list node is created,
how do we refer to the information it comprises—its name, age, height and its nxt? We have
already seen the basic operations that we need for this task in section 3.1.1: We simply
dereference the pointer as *temp, then use the structure member names—the name in the
node referenced by pointer temp is (*temp).name and the nxt is (*temp).nxt. When the fields
of this structure are referred to, brackets should be put round the *temp part, as otherwise the
compiler will think we are trying to refer to the fields of the pointer. Alternatively, we can
use the arrow pointer notation as temp->name and temp->nxt, which are equivalent to
(*temp).name and (*temp).nxt. We will use the arrow notation, since it provides a simpler
mechanism, in the rest of this course.

Having declared the node, we ask the user to fill in the details of the person, i.e. the name,
age, address or whatever:

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 height of the person : ";

cin >> temp->height;

7
temp->nxt = NULL;

The last line sets the pointer from this node to the next to NULL, indicating that this node,
when it is inserted in the list, will be the last node. Having set up the information, we have to
decide what to do with the pointers. Of course, if the list is empty to start with, there's no
problem - just set the Start pointer (start_ptr) to point to this node (i.e. set it to the same value
as temp):

if (start_ptr == NULL)

start_ptr = temp;

Inserting a node to the end 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.

Node * temp2 = start_ptr; // Start from the first element

while (temp2->nxt != NULL)

temp2 = temp2->nxt; // Move to next link in chain

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 nxt pointer of the last node to point to the node we have just declared:

temp2->nxt = temp;

The link temp2->nxt in this diagram is the link joining the last two nodes.

8
The full code for adding a node at the end of the list is shown below, in its own little
function:

void add_node_at_end (node * start_ptr, char [] name, int age, float


height)

node *temp, *temp2; // Temporary pointers

// Reserve space for new node and fill it with data

temp = new node;

strcpy(temp->name, name);

temp->age = age;

temp->height = height;

temp->nxt = NULL;

// Set up link to this node

if (start_ptr == NULL)

start_ptr = temp;

else

{ temp2 = start_ptr; //start from the first node

while (temp2->nxt != NULL)

temp2 = temp2->nxt; // Move to next link in chain

temp2->nxt = temp; //attach the new node to the end of the list

3.2.4. Displaying the list of nodes and searching the linked list

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:

1. Set a temporary pointer to point to the same thing as the start pointer.

9
2. If the pointer points to NULL, display the message "End of list" and stop.

3. Otherwise, display the details of the node pointed to by the start pointer.

4. Make the temporary pointer point to the same thing as the nxt pointer of the node it is
currently indicating.

5. Jump back to step 3.

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. Here is the C++ code that does the job:

void display(node * start_ptr, ostream out){

node * temp = start_ptr;

if (temp == NULL)

out << "There is no element in the linked list" << endl;

else

while (temp != NULL){

// Display details for what temp points to

out << "Name : " << temp->name << endl;

out << "Age : " << temp->age << endl;

out << "Height : " << temp->height << endl;

out << endl; // Blank line

// Move to next node (if present)

temp = temp->nxt;

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.

10
Searching scans an existing list to find a node. Searching is similar to displaying the nodes
which we say earlier in this section. The difference is that we display the details of a node
when we find it. Here is how it works.

1. Declare a temporary variable to go through the list starting from the start pointer (i.e
the beginning of the linked list).

2. The name stored in each node is compared to the name being sought, and if the two
are equal the details of the node are displayed and the loop is exited; otherwise temp
is updated to temp->nxt so that the next node can be investigated.

3. After reaching the last node and executing the statement temp = temp -> nxt, temp
becomes null, which is used as an indication that the node with the specified name
does not exist in the list. That is if temp is not null, the search was discontinued
somewhere inside the list because the name was found. Therefore, If temp is null
“Display the node is not found”.

void search(){

char name[20];

cout<<”Enter the name of the person you are looking for: “;

cin>>name;

node * temp = start_ptr;

while(temp != NULL)

If(strcmp(temp->name, name == 0))

// strcmp is used to compare strings. If they are equal it returns 0

{ // Display details for what temp points to

cout << "Name : " << temp->name << endl;

cout << "Age : " << temp->age << endl;

cout << "Height : " << temp->height << endl;

cout << endl; // Blank line

//stop searching since the person is found

break;

11
}

else

temp = temp->nxt; // Move to next node

if (temp == NULL)

cout<<”The node is not found”<<endl;

3.2.5. Navigating through the list

One thing you may need to do is to navigate through the list, with a pointer that moves
backwards and forwards through the list, like an index pointer in an array. This is certainly
necessary when you want to insert or delete a node from somewhere inside the list, as you
will need to specify the position.

We will call the mobile pointer current. First of all, it is declared, and set to the same value
as the start_ptr pointer:

node *current;

current = start_ptr;

Notice that you don't need to set current equal to the address of the start pointer, as they are
both pointers. The statement above makes them both point to the same thing:

It's easy to get the current pointer to point to the next node in the list (i.e. move from left to
right along the list). If you want to move current along one node, use the nxt field of the node
that it is pointing to at the moment:

current = current->nxt;

In fact, we had better check that it isn't pointing to the last item in the list. If it is, then there is
no next node to move to:

if (current->nxt == NULL)

cout << "You are at the end of the list." << endl;

12
else

current = current->nxt;

Moving the current pointer back one step is a little harder. This is because we have no way of
moving back a step automatically from the current node. The only way to find the node
before the current one is to start at the beginning, work our way through and stop when we
find the node before the one we are considering at the moment. We can tell when this
happens, as the nxt pointer from that node will point to exactly the same place in memory as
the current pointer (i.e. the current node).

previous current
Start
Stop
here
NULL

First of all, we had better check to see if the current node is also first the one. If it is, then
there is no "previous" node to point to. If not, check through all the nodes in turn until we
detect that we are just behind the current one (Like a pantomime - "behind you!")

if (current == start_ptr)

cout << "You are at the start of the list" << endl;

else

{ node *previous; // Declare the pointer

previous = start_ptr;

while (previous->nxt != current)

{ previous = previous->nxt;

current = previous;

The else clause translates as follows: Declare a temporary pointer (for use in this else clause
only). Set it equal to the start pointer. All the time that it is not pointing to the node before the
current node, move it along the line. Once the previous node has been found, the current
pointer is set to that node - i.e. it moves back along the list.

13
Now that you have the facility to move back and forth, you need to do something with it.
Firstly, let's see if we can alter the details for that particular node in the list:

cout << "Please enter the new name of the person: ";

cin >> current->name;

cout << "Please enter the new age of the person : ";

cin >> current->age;

cout << "Please enter the new height of the person : ";

cin >> current->height;

The next easiest thing to do is to delete a node from the list directly after the current position.
We have to use a temporary pointer to point to the node to be deleted. Once this node has
been "anchored", the pointers to the remaining nodes can be readjusted before the node on
death row is deleted. Here is the sequence of actions:

1. Firstly, the temporary pointer is assigned to the node after the current one. This is the
node to be deleted:

current temp

NULL

2. Now the pointer from the current node is made to leap-frog the next node and point to
the one after that:
current temp

NULL

3. The last step is to delete the node pointed to by temp.

Here is the code for deleting the node. It includes a test at the start to test whether the current
node is the last one in the list:

if (current->nxt == NULL)

cout << "There is no node after current" << endl;

14
else

{ node *temp;

temp = current->nxt;

current->nxt = temp->nxt; // Could be NULL

delete temp;

Here is the code to add a node after the current one. This is done similarly, but we haven't
illustrated it with diagrams:

if (current->nxt == NULL)

add_node_at_end();

else

{ node *temp = new node;

cout << "Please enter the new name of the person: ";

cin >> current->name;

cout << "Please enter the new age of the person : ";

cin >> current->age;

cout << "Please enter the new height of the person : ";

cin >> current->height;

// Ma**ke the new node point to the same thing as

// the current node

temp->nxt = current->nxt;

// Make the current node point to the new link

// in the chain

current->nxt = temp;

15
We have assumed that the function add_node_at_end() is the routine for adding the node to
the end of the list that we created near the top of this section. This routine is called if the
current pointer is the last one in the list so the new one would be added on to the end.

3.2.6. 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, or delete one from somewhere in the middle. For
simplicity, we shall just deal 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:

delete temp; // Release the memory pointed to by temp

However, we can't just delete the nodes willy-nilly as it would break the chain. We need to
reassign the pointers and then delete the node at the last moment. Here is how we go about
deleting the first node in the linked list:

temp = start_ptr; // Make the temporary pointer

// identical to the start pointer

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; // Second node in chain.

delete temp; // Wipe out original start node

16
Here is the function that deletes a node from the start:

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).

1. Look at the start pointer. If it is NULL, then the list is empty, so print out a "No nodes
to delete" message.

2. Make temp1 point to whatever the start pointer is pointing to.

3. If the nxt pointer of what temp1 indicates is NULL, then we've found the last node of
the list, so jump to step 7.

4. Make another pointer, temp2, point to the current node in the list.

5. Make temp1 point to the next item in the list.

6. Go to step 3.

7. 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 last-but-one item.

8. Delete the node pointed to by temp1.

17
9. Mark the nxt pointer of the node pointed to by temp2 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:

Firstly, the start pointer doesn't point to NULL, so we don't have to display a "Empty list,
wise guy!" message. Let's get straight on with step2 - set the pointer temp1 to the same as the
start pointer:

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

and then move temp1 to the next node in the list:

18
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

temp 2 temp1
and temp1 is made to point to the next node along:

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

temp 2 temp1
Now we have reached step 8. The next thing to do is to delete the node pointed to by temp1

19
and set the nxt pointer of what temp2 indicates to NULL:

We suppose you want some code for all that! All right then ....

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;

20
The code seems a lot shorter than the explanation!

Now, the sharp-witted amongst you will have spotted a problem. If the list only contains one
node, the code above will malfunction. 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) // This part is new!

{ delete temp1;

start_ptr = NULL;

else

{ while (temp1->nxt != NULL)

{ temp2 = temp1;

temp1 = temp1->nxt;

delete temp1;

temp2->nxt = NULL;

21
3.3. Doubly Linked Lists

The delete_end_node() function illustrated a problem with singly linked lists. In the
implementation of this function we wanted to find the predecessor to the node to be deleted
(i.e. the second-last node). In singly linked lists there is no way of finding the predecessor to
a node, only its successor. But the solution is simple. Merely add an extra field to the data
structure, containing a pointer to the previous cell. Therefore, if you need to move to the
previous node, you can automatically do it.

A doubly linked list is one where there are links from each node in both directions.

You will notice that each node in the list has two pointers, one to the next node and one to the
previous one - again, the ends of the list are defined by NULL pointers. Also there is no
pointer to the start of the list. Instead, there is simply a pointer to some position in the list that
can be moved left or right.

The reason we needed a start pointer in the ordinary linked list is because, having moved on
from one node to another, we can't easily move back, so without the start pointer, we would
lose track of all the nodes in the list that we have already passed. With the doubly linked list,
we can move the current pointer backwards and forwards at will.

3.3.1. Creating Doubly Linked Lists

The nodes for a doubly linked list would be defined as follows:

struct node{

char name[20];

node *nxt; // Pointer to next node

node *prv; // Pointer to previous node

};

node *current = NULL;

We have also set the current pointer to show that there are no elements in the list.

22
In the next section will need to define functions to add a node to the start of the list (left-most
position) and the end of the list (right-most position).

3.3.2. Adding a Node to a Doubly Linked List

void add_node_at_start ()

{ // Declare a temporary pointer and move it to the start

node *temp = current;

while (current->prv != NULL)

temp = temp->prv;

// Declare a new node and link it in

node *temp2;

temp2 = new node;

temp2->name = new_name; // Store the new name in the node

temp2->prv = NULL; // This is the new start of the list

temp2->nxt = temp; // Links to current list

temp->prv = temp2;

void add_node_at_end ()

{ // Declare a temporary pointer and move it to the end

node *temp = current;

while (temp->nxt != NULL)

temp = temp->nxt;

// Declare a new node and link it in

node *temp2;

temp2 = new node;

temp2->name = new_name; // Store the new name in the node

temp2->nxt = NULL; // This is the new start of the list

23
temp2->prv = temp; // Links to current list

temp->nxt = temp2;

Here, the new name is passed to the appropriate function as a parameter. We'll go through the
function for adding a node to the right-most end of the list. The method is similar for adding a
node at the other end. Firstly, a temporary pointer is set up and is made to march along the
list until it points to last node in the list.

Start_Ptr

After that, a new node is declared, and the name is copied into it. The nxt pointer of this new
node is set to NULL to indicate that this node will be the new end of the list.

The prv pointer of the new node is linked into the last node of the existing list.

The nxt pointer of the current end of the list is set to the new node.

If you have mastered the skills of manipulating singly linked lists, operations like deleting,
searching, and displaying in a doubly linked list will not be difficult. But we are not going to
discuss them here.

3.3 Circular Lists

In some situations, a linked list is needed that forms a ring, i.e. there are no null pointers to
indicate the end of the list, and each node has a successor node. An example of such a
situation is for an implementation of time-division multiplexing: a number of processes take
turns to use the CPU for a limited time slot, and the order is which they do so is fixed and
circular. In this case, each node in the list would represent a process that is using the CPU.
Such a structure is called a circular linked list.

In terms of the data structure employed, circular linked lists do not differ from non-circular
linked lists: they can be either singly linked or doubly linked, as shown in the following
figure. The difference lies in the implementations of the functions that add node to or delete
nodes from the list. These functions will need to maintain the circular nature of the list when
performing their operations.

24
25

You might also like