Lecture 3 - Data Structures
Lecture 3 - Data Structures
Data Structures
Structures
• Structures are aggregate data types built using elements of primitive data types
• Structure are defined using the struct keyword:
• Example :
struct Time{
int hour;
int minute;
int second; };
• The struct keyword creates a new user defined data type that is used to declare variables of an
aggregate data type
• Structure variables are declared like variables of other types.
struct list{
char name[10];
int count;
struct list *next; // pointer that points to instance of themselves
};
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, it shows last link in the chain.
Start (also called head) pointer , which points to the first link in the chain so that we
can keep track of it.
Defining the data structure for a linked list
• The key part of a linked list is a structure, which holds the data for each node and, most
importantly, a pointer to the next node
struct node {
char name[20]; // Name of up to 20 letters
int age;
float height; // In metres
node *nxt;// Pointer to next node in the list – important part of structure
};
struct node *start_ptr = NULL;
/* permanently point to the start of the list and to start with there is no nodes in
the list , which is why start_ptr is set to NULL */
Adding a node to the list
Step 1:- declare the space for a pointer item and assign a temporary pointer to it.
temp = new node;
• The new node as *temp, i.e. "the node that temp points to".
Step 2 : Fill the node with data , use the arrow pointer notation
In fact, 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;
else
current = current->nxt; // unless move to next nodes
Navigating through the list
Moving back
• 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
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
Navigating through the list
if (current == start_ptr)
cout << "You are at the start of the list" << endl;
else
{ node *previous; // Declare the pointer
previous = start_ptr;
Now that the first node has been safely tagged and move the start pointer to the next node in
the chain:
start_ptr = start_ptr->nxt; // Second node in chain.
Deleting a node from the list
delete temp; // Wipe out original start node
void delete_start_node()
{ node *temp;
temp = start_ptr;
start_ptr = start_ptr->nxt;
delete temp;
}
Deleting a node from the list
Deleting a node from end of list
• 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.
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.
9.Mark the nxt pointer of the node pointed to by temp2 as NULL - it is the new last node.
Deleting a node from the list
• 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:
Deleting a node from the list
• 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
• Now we have reached step 8. The next thing to do is to delete the node pointed to by
temp1
Deleting a node from the list
• and set the nxt pointer of what temp2 indicates to NULL:
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;
}
}
void delete_end_node()
{ node *temp1, *temp2;
Deleting a node from the list if (start_ptr == NULL)
cout << "The list is empty!" << endl;
• If the list only contains one node, the code else
above will malfunction. This is because the { temp1 = start_ptr;
if (temp1->nxt == NULL) // This part
function goes as far as the temp1 =
is new!
start_ptr statement, but never gets as far { delete temp1;
as setting up temp2. start_ptr = NULL;
}
• The code above has to be adapted so that if
else
the first node is also the last (has a NULL { while (temp1->nxt != NULL)
nxt pointer), then it is deleted and the { temp2 = temp1;
start_ptr pointer is assigned to NULL. In this temp1 = temp1->nxt;
case, there is no need for the pointer }
temp2: delete temp1;
temp2->nxt = NULL;
}
}
}
Doubly Linked Lists
• A doubly linked list is one where there are links from each node in both directions:
• Each node in the list has two pointers, one to the next node and one to the previous
one
• 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.
• With the doubly linked list, we can move the current pointer backwards and forwards
at will.