data structures - 05. linked lists
DESCRIPTION
Slide da cadeira de Estrutura de Dados, ministrado pelo Prof. Dr. Christian Pagot, na Universidade Federal da Paraíba.TRANSCRIPT
Universidade Federal da ParaíbaCentro de Informática
Linked ListsLecture 7
1107186 – Estrutura de Dados – Turma 02
Prof. Christian Azambuja PagotCI / UFPB
2Universidade Federal da ParaíbaCentro de Informática
Arrays
● Are stored as contiguous chunks of memory.● Have fixed size.● Each position is referenced through an
index.
3Universidade Federal da ParaíbaCentro de Informática
The Costs of the Arrays
● Accessing an arbitrary element?– The cost is constant!
● Example:
int v[10];
...
printf(“%i”, v[2]);
...
C code excerpt:
Jumps directly to the memory positionwhere the 3rd array
Item is stored.
4Universidade Federal da ParaíbaCentro de Informática
The Costs of the Arrays
● Inserting a new element?– The cost, in the worst case, may be n (where n
is the length of the array)!
● Example:
char v[5]={'a','b','c','d',' '};
C code excerpt:
5Universidade Federal da ParaíbaCentro de Informática
The Costs of the Arrays
● Example:
Addr.
Physical memory.
i i+1 i+2 i+3 i+4 i+5a b c d
. . . . . .
v[0]We want to
insert 'e' here:
Addr.
Physical memory.
i i+1 i+2 i+3 i+4 i+5a
. . . . . .
v[0]
dcbe
6Universidade Federal da ParaíbaCentro de Informática
An Array-based List Implementation
struct ArrayList{
int* array;int arraysize;int lastpos;
};
...
struct ArrayList a;
a.arraysize = 10;a.array = (int*) malloc(a>arraysize * sizeof(int));a.lastpos = 1; InsertALElement(&a, 0, 10);
C code excerpt:
Array liststructure.
Array listdeclaration.
Insert elementfunction.
Array listinitialization.
7Universidade Federal da ParaíbaCentro de Informática
InsertALElement(...)
void InsertALElement(struct ArrayList* a, int pos, int val){
...
if (pos < 0){
printf("Invalid position! Exiting...\n");exit(1);
}
...
C code excerpt:
8Universidade Federal da ParaíbaCentro de Informática
InsertALElement(...)
void InsertALElement(struct ArrayList* a, int pos, int val){
...
// pos greater than lastpos+1 //(there will be a gap in the list!): // reset pos to lastpos+1.
if (pos > (a>lastpos + 1))pos = a>lastpos + 1;
...
C code excerpt:
After this step, we can be surethat pos has a valid value!
9Universidade Federal da ParaíbaCentro de Informática
InsertALElement(...)
void InsertALElement(struct ArrayList* a, int pos, int val){
...// the current array is full already: double array sizeif ((a>lastpos + 1) == a>arraysize){
newarray = (int *) malloc(2 * a>arraysize * sizeof(int));
for (i=0; i<a>arraysize; i++)newarray[i] = a>array[i];
free(a>array);a>array = newarray;a>arraysize = 2 * a>arraysize;
}...
C code excerpt:
10Universidade Federal da ParaíbaCentro de Informática
InsertALElement(...)
void InsertALElement(struct ArrayList* a, int pos, int val){
...// shift right elements to make room for the new value.
for (i=a>lastpos; i>=pos; i)a>array[i+1] = a>array[i];
a>array[pos] = val;a>lastpos++;
}
C code excerpt:
11Universidade Federal da ParaíbaCentro de Informática
Linked Lists
● Their elements (nodes) may be (and are likely to be) spread over the memory.
● Nodes are connected to each other through pointers.
● Have varying sizes.● Each position is referenced through a
pointer.
12Universidade Federal da ParaíbaCentro de Informática
The Costs of Linked Lists
● Inserting a new element?– Given that we have the pointer of the previous
element, insertion is constant.
value
next
103 value
next
235 value
next
98
nulln
13Universidade Federal da ParaíbaCentro de Informática
The Costs of Linked Lists
● Inserting a new element?– Given that we have the pointer of the previous
element, insertion is constant.
value
next
103 value
next
235 value
next
98
null
value
next
500
?
n
new
14Universidade Federal da ParaíbaCentro de Informática
The Costs of Linked Lists
● Inserting a new element?– Given that we have the pointer of the previous
element, insertion is constant.
value
next
103 value
next
235 value
next
98
null
value
next
500
n
new
15Universidade Federal da ParaíbaCentro de Informática
The Costs of Linked Lists
● Inserting a new element?– Given that we have the pointer of the previous
element, insertion is constant.
value
next
103 value
next
235 value
next
98
null
value
next
500
n
new
16Universidade Federal da ParaíbaCentro de Informática
The Costs of Linked Lists
● Accessing an arbitrary element?– The cost, in the worst case, is n (where n is the
length of the list).
● Example: – Which is the value of the 3rd element?
value
next
103 value
next
235 value
next
98
nulln
17Universidade Federal da ParaíbaCentro de Informática
A Linked List Implementation
struct Node{
int value;struct Node* next;
};
...
struct Node* n1;
n1 = (struct Node*) malloc (sizeof(struct Node));n1>value = 1;n1>next = NULL;
InsertAfterSLLElement(n1, 2);
C code excerpt: List nodestructure.
Pointer to a node.
Initializationof the 1st. node.
Insert elementafter node n1.
18Universidade Federal da ParaíbaCentro de Informática
InsertAfterSLLElement(...)
void InsertAfterSLLElement(struct Node* n, int val){
struct Node* new_n;
new_n = (struct Node*) malloc (sizeof(struct Node));new_n>value = val;new_n>next = n>next;n>next = new_n;
}
C code excerpt:
19Universidade Federal da ParaíbaCentro de Informática
A More General Insert Function
● Suppose that we want a function to insert nodes in a linked list that receives the value and the insertion position as parameters:
void InsertSLLElement(struct Node** n, int pos, int val){
...}
C code excerpt:
20Universidade Federal da ParaíbaCentro de Informática
InsertSLLElement(...)
void InsertSLLElement(struct Node** n, int pos, int val){
...
if (pos < 0){
printf("Invalid position! Exiting...\n");exit(1);
}
...
C code excerpt:
21Universidade Federal da ParaíbaCentro de Informática
InsertSLLElement(...)
void InsertSLLElement(struct Node** n, int pos, int val){
...
if (((*n) == NULL) || (pos == 0)){
tmp_node_ptr1 = (*n);
(*n) = (struct Node*) malloc (sizeof(struct Node));(*n)>value = val;(*n)>next = tmp_node_ptr1;
}else
...
C code excerpt:
Else block: list has at least one element, and insertion
is not at the beginning.
22Universidade Federal da ParaíbaCentro de Informática
InsertSLLElement(...)
void InsertSLLElement(struct Node** n, int pos, int val){
...else{
tmp_node_ptr1 = (*n);
while ((i < pos) && (tmp_node_ptr1>next != NULL)){
tmp_node_ptr1 = tmp_node_ptr1>next;i++;
}
if (i < pos) {...} else {...}}
}
C code excerpt:
Insert at the end
Insert in themiddle.
23Universidade Federal da ParaíbaCentro de Informática
InsertSLLElement(...)
void InsertSLLElement(struct Node** n, int pos, int val){
...if (i < pos){
tmp_node_ptr1>next = (struct Node*) malloc (sizeof(struct Node));tmp_node_ptr1>next>value = val;tmp_node_ptr1>next>next = NULL;
}else{
tmp_node_ptr2 = (*n);
while (tmp_node_ptr2>next != tmp_node_ptr1)tmp_node_ptr2 = tmp_node_ptr2>next;
tmp_node_ptr2>next = (struct Node*) malloc (sizeof(struct Node));tmp_node_ptr2>next>value = val;tmp_node_ptr2>next>next = tmp_node_ptr1;
}...
C code excerpt:
This is bad!It can be greatly
Improved!
24Universidade Federal da ParaíbaCentro de Informática
An Issue Related to Our Implementation
int main(void){
struct Node* n1 = NULL;struct Node* n2 = NULL;
InsertSLLElement(&n1, 0, 0);InsertSLLElement(&n1, 1, 10);InsertSLLElement(&n1, 2, 20);InsertSLLElement(&n1, 3, 30);InsertSLLElement(&n1, 4, 40);
n2 = n1;
InsertSLLElement(&n1, 0, 666);
PrintSLLInfo(n1);
PrintSLLInfo(n2);...
C code excerpt:
list[0] : 666 list[1] : 0 list[2] : 10 list[3] : 20 list[4] : 30 List[5] : 40
list[0] : 0 list[1] : 10 list[2] : 20 list[3] : 30 List[4] : 40
That'sbad!
25Universidade Federal da ParaíbaCentro de Informática
An Issue Related to Our Implementation
● What happened?
value
next
0 value
next
10 value
next
20
null
n1
n2
value
next
666
?new
26Universidade Federal da ParaíbaCentro de Informática
An Issue Related to Our Implementation
● What happened?
value
next
0 value
next
10 value
next
20
null
n1
n2
value
next
666
new
27Universidade Federal da ParaíbaCentro de Informática
An Issue Related to Our Implementation
● What happened?
value
next
0 value
next
10 value
next
20
null
n1
n2
value
next
666
new
n1 and n2 do not point to the same node
anymore!
28Universidade Federal da ParaíbaCentro de Informática
One Possible Solution
struct SLList{
struct Node* head;int size;
};
struct Node{
int value;struct Node* next;
};
C code excerpt:
● We create a new structure that contains a pointer to the head of the linked list:
It can also contain important information about the list,
such as the length.
29Universidade Federal da ParaíbaCentro de Informática
One Possible Solution
● We create a new structure that contains a pointer to the head of the linked list:
value
next
0 value
next
10 value
next
20
null
size
head
3l1
l2Type: SLList
Type: Node Type: Node Type: Node
Insert functionsmust be rewritten!
30Universidade Federal da ParaíbaCentro de Informática
Discussion
● Considering the presented implementation:– What are the differences between the two
presented linked lists with respect to initialization?
– Which is the 'best' approach: array-based or linked list based list?
– Could you make an experiment to test the several aspects related to efficiency of these two types of lists?
Think about it !!!