0% found this document useful (0 votes)
20 views60 pages

4a. Linked Lists

Uploaded by

Mạnh Hậu Cao
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)
20 views60 pages

4a. Linked Lists

Uploaded by

Mạnh Hậu Cao
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/ 60

Nhân bản – Phụng sự – Khai phóng

Linked Lists
Data Structures & Algorithms
CONTENT

• Linked List Basics


• Singly linked lists
• Circularly linked list
• Doubly linked lists
• Applications
• Polynomial representation
• Equivalence relations
• Sparse matrices

Data Structures & Algorithms 2


CONTENT

• Linked List Basics


• Singly linked lists
• Circularly linked list
• Doubly linked lists
• Applications
• Polynomial representation
• Equivalence relations
• Sparse matrices

Data Structures & Algorithms 3


Linked List Basics
• Linked lists & arrays are similar - Both store collections of data.

• Array: allocating sequentially its elements.

• Linked lists: allocating memory for each element separately and only when
necessary.

• Linked lists are used to store a collection of information (like arrays)

• A linked list is made of nodes that are pointing to each other

• We only know the address of the first node (head)


• Other nodes are reached by following the “next” pointers

• The last node points to NULL


Data Structures & Algorithms 4
…Linked List Basics

• Linked List vs. Array


• Elements of array are contiguous
• In a linked list, nodes are not necessarily contiguous in memory

Array

head Linked List


NULL

Data Structures & Algorithms 5


…Linked List Basics

• Linked List vs. Array


Array: Linked List:

• Advantages: • Advantages:
– Easy to use – Arbitrary size
– A good choice for a small list
– No shift required
– O(1) access time

• Disadvantages: • Disadvantages:
– Fixed size – Necessity to allocate next
– Memory wasting – O(N) access time
– Still space and time wasting in
dynamic array
Data Structures & Algorithms 6
…Linked List Basics

• We use linked lists if…


• The number of elements that will be stored cannot be predicted at
compiling time
• Elements may be inserted in the middle or deleted from the middle
• We are less likely to make random access into the data structure
(because random access is expensive for linked lists)

head Linked List


NULL

Data Structures & Algorithms 7


…Linked List Basics
• Operations on Linked List
• Generic methods: size(), isEmpty()
• Query methods: isFirst(p), isLast(p)
• Accessor methods: first(), last()
before(p), after(p)
• Update methods: insertFirst(e), insertLast(e)
insertBefore(p,e), insertAfter(p,e)
removeAfter(p)
invert(p)
replaceElement(p,e)
swapElements(p,q),

Data Structures & Algorithms 8


CONTENT

• Linked List Basics


• Singly linked lists
• Circularly linked list
• Doubly linked lists
• Applications
• Polynomial representation
• Equivalence relations
• Sparse matrices

Data Structures & Algorithms 9


Singly linked lists
• Linked Lists
head

next next next next

a b c d

First node Last node


• Each node has (at least) 2 fields:
• Data
data ptr
• Pointer to the next node

• Empty linked list head


head = NULL;
Data Structures & Algorithms 10
…Singly linked lists
• Insert mat between cat & sat
1. Get a node that is currently unused; let its address be paddr.
2. Set the data field of this node to mat.
3. Set paddr’s link field to point to the address found in the link field of the node
containing sat.
4. Set the link field of the node containing cat to point to paddr.

bat Ÿ cat Ÿ sat Ÿ vat NULL

mat Ÿ

Data Structures & Algorithms 11


…Singly linked lists

• Delete mat from the list


• Find the element that immediately precedes mat, which is cat, and set its link
field to point to mat’s link field

bat Ÿ cat Ÿ mat Ÿ sat Ÿ vat NULL

Data Structures & Algorithms 12


…Singly linked lists

• Implementation
–Declaration –Traverse a list
typedef struct node *pnode; void traverseList(pnode ptr){
typedef struct node {
char data [4]; pnode p = ptr;
pnode next; printf(“The list contains: “);
}; for ( ; p ; p = p->next)
–Creation printf(“%s\n”, p->data);
pnode ptr =NULL; }
–Testing
#define IS_EMPTY(ptr) (!(ptr))
#define IS_FULL(ptr) (!(ptr))

Data Structures & Algorithms 13


…Singly linked lists
• Implementation - Insert after a specific position
void insertAfter(pnode node, char* data){
/* insert a new node with data into the list ptr after node */
pnode temp;
temp = (pnode) malloc(sizeof(node));
if (IS_FULL(temp)){
fprintf(stderr, “The memory is full\n”);
exit (1);
}
strcpy(temp->data, data);
if (node) { //noempty list
temp->next=node->next;
node->next= temp;
}else { //empty list
temp->next= NULL;
node =temp;
}
}
Data Structures & Algorithms 14
…Singly linked lists

• Implementation - Delete a node after a specific position

void removeAfter(pnode node){


/* delete what follows after node in the list */
pnode tmp;
if (node) {
tmp = node -> next;
node->next = node->next->next;
free(tmp);
}
}

Data Structures & Algorithms 15


…Singly linked lists

• Implementation - Inverting a list


pnode invertList(pnode lead){
/* invert the chain pointed to by lead */
pnode middle, trail;
middle = NULL;
while (lead) {
trail = middle;
middle = lead;
lead = lead->next;
middle->next = trail
}
return middle;
}

Data Structures & Algorithms 16


CONTENT

• Linked List Basics


• Singly linked lists
• Circularly linked list
• Doubly linked lists
• Applications
• Polynomial representation
• Equivalence relations
• Sparse matrices

Data Structures & Algorithms 17


Circularly linked list

• Circularly linked list

• The link field of the last node points to the first node in the list

a x1 x2 x3

• It is more convenient when insert a new node if the name of the


circular list points to the last node

x1 x2 x3 a

Data Structures & Algorithms 18


…Circularly linked list
• Insert a node
void insertFront (pnode* ptr, pnode node){ typedef struct node *pnode;
/* insert a node in the list with head (*ptr)->next */ typedef struct node {
if (IS_EMPTY(*ptr)){ char data;
*ptr= node; pnode next;
node->next = node; /* circular link */ };
}
else {
node->next = (*ptr)->next; (1)
(*ptr)->next = node; (2)
}
}

X1 Ÿ X2 Ÿ X3 Ÿ ptr
(2)
(1)
Data Structures & Algorithms 19
…Circularly linked list

• List length • Print list


void printList(pnode start, pnode ptr){
int length(pnode ptr){
if (ptr) printf(“%c ”, ptr->data);
pnode temp;
if (start == ptr) return;
int count = 0;
printList(start, ptr->next);
if (ptr) {
}
temp = ptr;
ðUse: printList(start, start->next);
do {
count++;
temp = temp->next;
• Other operations
} while (temp!=ptr);
–Create a node (with data)
}
–Delete a node (with data)
return count;
}
–Find a node
Data Structures & Algorithms 20
CONTENT

• Linked List Basics


• Singly linked lists
• Circularly linked list
• Doubly linked lists
• Applications
• Polynomial representation
• Equivalence relations
• Sparse matrices

Data Structures & Algorithms 21


Doubly linked lists
• Singly linked lists
• Some operations are expensive
• insertLast, removeAfter
• Why? ð need for traversing the list
ðSolution: add previous link to elements

• Doubly linked list has at least three fields:


• a left link field (llink) • Declarations
typedef struct node *node_pointer;
• a data field (item) typedef struct node {
node_pointer llink;
• a right link field (rlink)
element item;
node_pointer rlink;
}
Data Structures & Algorithms 22
…Doubly linked lists
• Different uses
• Doubly linked list with a head node and a tail node
head node tail node

X X

• Doubly linked list with a head node points to the first node in the list
and to the last node in the list

head node

Data Structures & Algorithms 23


…Doubly linked lists
• Different uses
• Doubly linked circular list with head node
head node

• Empty doubly linked circular list with head node

ptr

Data Structures & Algorithms 24


…Doubly linked lists

• Different uses
• Doubly linked circular list with head node
• Insertion into an empty doubly linked circular list

node node

Ÿ Ÿ

newnode

Data Structures & Algorithms 25


…Doubly linked lists

• Different uses
–Doubly linked circular list with head node
• Insertion into a doubly linked circular list

head node

llink item rlink


(1) (3) (2)
(4)

Data Structures & Algorithms 26


…Doubly linked lists

• Different uses
–Doubly linked circular list with head node
• Deletion from a doubly linked circular list

head node

(1)
llink item rlink

(2)

Data Structures & Algorithms 27


CONTENT

• Linked List Basics


• Singly linked lists
• Stacks and Queues
• Circularly linked list
• Doubly linked lists
• Applications
• Polynomial representation
• Equivalence relations
• Sparse matrices

Data Structures & Algorithms 28


Polynomial representation
• Polynomials representation
• Representing polynomials as singly linked lists
em-1 e m- 2 e0
A( x ) = am-1 x + a m- 2 x +...+ a0 x
ai are nonzero coefficients, ei are nonnegative integer exponents such that
em-1 > em-2 > … > e1 > e0 ≧ 0

• Declarations
• Each term as a node containing typedef struct poly_node *poly_pointer;
coefficient , exponent, as well as typedef struct poly_node {
int coef;
a pointer to the next term int expon;
poly_pointer link;
coef expon link };
poly_pointer a , b, c;
Data Structures & Algorithms 29
Data Structures & Algorithms 29
…Polynomial representation
• Polynomials representation - Example

14 8
a = 3x + 2x +1
a
3 14 2 8 1 0 null

14 10 6
b = 8x - 3x + 10 x
b
8 14 -3 10 10 6 null

Data Structures & Algorithms 30


…Polynomial representation
• Add two polynomials
To add 2 polynomials, we examine their terms starting at the nodes
pointed to by a and b, there is 3 cases:
1. If the exponents of the two terms are equal, we add the two
coefficients and create a new term c for the result
2. If the exponent of the current term in a is less than the exponent of
the current term in b, then we create a duplicate term of b, attach
this term to the result, called c, and advance the pointer to the next
term in b.
3. Take a similar action on a if a->expon > b->expon

Data Structures & Algorithms 31


…Polynomial representation

1. a->expon == b->expon
If the exponents of the two terms are equal, we add the two coefficients and
create a new term c for the result

3 14 2 8 1 0
a

8 14 -3 10 10 6
b
11 14
c
a->expon == b->expon

Data Structures & Algorithms 32


…Polynomial representation

2. a->expon < b->expon


If the exponent of the current term in a is less than the exponent of the current
term in b, then we create a duplicate term of b, attach this term to the result,
called c, and advance the pointer to the next term in b.

3 14 2 8 1 0
a

8 14 -3 10 10 6
b

11 14 -3 10
c

a->expon < b->expon


Data Structures & Algorithms 33
…Polynomial representation

3. a->expon > b->expon


Take a similar action on a if a->expon > b->expon

3 14 2 8 1 0
a

8 14 -3 10 10 6
b
11 14 -3 10 2 8
c

a->expon > b->expon

Data Structures & Algorithms 34


…Polynomial representation
• Function Add two polynomials
poly_pointer addPoly(poly_pointer a, poly_pointer b) {
poly_pointer front, rear, temp;
int sum;
rear =(poly_pointer)malloc(sizeof(poly_node));
if (IS_FULL(rear)) {
fprintf(stderr, “The memory is full\n”);
exit(1);
}
front = rear;
while (a && b) {
switch (COMPARE(a->expon, b->expon)) {

Data Structures & Algorithms 35


…Polynomial representation
• Function Add two polynomials
case -1: /* a->expon < b->expon */
attach(b->coef, b->expon, &rear);
b= b->link;
break;
case 0: /* a->expon == b->expon */
sum = a->coef + b->coef;
if (sum) attach(sum,a->expon,&rear);
a = a->link; b = b->link;
break;
case 1: /* a->expon > b->expon */
attach(a->coef, a->expon, &rear);
a = a->link;
} // end switch
} //end while
Data Structures & Algorithms 36
…Polynomial representation

• Function Add two polynomials

for (; a; a = a->link)
attach(a->coef, a->expon, &rear);
for (; b; b = b->link)
attach(b->coef, b->expon, &rear);
rear->link = NULL;
temp = front;
front = front->link;
free(temp);
Delete extra initial node.
return front;
} // end function

Data Structures & Algorithms 37


…Polynomial representation
• Attach a term
void attach(float coefficient, int exponent, poly_pointer *ptr){
/* create a new node attaching to the node pointed to
by ptr. ptr is updated to point to this new node. */
poly_pointer temp;
temp = (poly_pointer) malloc(sizeof(poly_node));
if (IS_FULL(temp)) {
fprintf(stderr, “The memory is full\n”);
exit(1);
}
temp->coef = coefficient;
temp->expon = exponent;
(*ptr)->link= temp;
*ptr = temp;
}
Data Structures & Algorithms 38
…Polynomial representation
• Analysis
(1) coefficient additions
0 £ additions £ min(m, n)
where m (n) denotes the number of terms in a (b).
(2) exponent comparisons
extreme case
em-1 > fm-1 > em-2 > fm-2 > … > e0 > f0
m+n-1 comparisons
(3) creation of new nodes
extreme case
m + n new nodes
summary O(m+n)

Data Structures & Algorithms 39


…Polynomial representation

• Erasing polynomials

void erase(poly_pointer *ptr){


/* erase the polynomial pointed to by ptr */
poly_pointer temp;
while (*ptr) {
temp = *ptr;
*ptr = (*ptr)->link;
free(temp);
}
}

Data Structures & Algorithms 40


Equivalence relations

• Equivalence relations
• A relation over a set, S, is said to be an equivalence relation over S iff
it is symmetric, reflexive, and transitive over S.
• Reflexivity: x=x
• Symmetry: if x=y, then y=x
• Transitivity: if x=y and y=z, then x=z

• Example
0=4, 3=1, 6=10, 8=9, 7=4, 6=8, 3=5, 2=11, 11=0
ð three equivalent classes:
{0,2,4,7,11}; {1,3,5}; {6,8,9,10}
Data Structures & Algorithms 41
…Equivalence relations
• Algorithm to find Equivalence Classes
void equivalence() {
initialize data structures;
while (there are more pairs) {
read the next pair <i,j>;
process this pair;
}
initialize the output;
do {
output a new equivalence class;
} while (not done);
}
Data Structures & Algorithms 42
…Equivalence relations
• More detailed Algorithm to find Equivalence Classes
void equivalence() {
initialize seq to NULL and out to TRUE;
while (there are more pairs) {
read the next pair, <i,j>;
put j on the seq[i] list;
put i on the seq[j] list;
}
for (i=0; i<n; i++)
if (out[i]) {
out[i]= FALSE;
output this equivalence class;
compute indirect equivalence using transitivity by using stack;
}
}
Data Structures & Algorithms 43
…Equivalence relations

• Illutration
[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]
0º4 seq
3º1
6 º 10
8º9 data 11 3 11 5 7 3 8 4 6 8 6 0
7º4 link NULL NULL NULL NULL NULL NULL

6º8
3º5
2 º 11 data 4 1 0 10 9 2
11 º 0 link NULL NULL NULL NULL NULL

Example: 0=4, 3=1, 6=10, 8=9, 7=4, 6=8, 3=5, 2=11, 11=0
ð three equivalent classes: {0,2,4,7,11}; {1,3,5}; {6,8,9,10}
Data Structures & Algorithms 44
…Equivalence relations

• Program (1/4)
#include <stdio.h>
#include <alloc.h>
#define MAX_SIZE 24
#define IS_FULL(ptr) (!(ptr))
#define FALSE 0
#define TRUE 1
typedef struct node *node_pointer ;
typedef struct node {
int data;
node_pointer link;
};

Data Structures & Algorithms 45


…Equivalence relations
• Program (2/4)
void main(void) {
short int out[MAX_SIZE];
node_pointer seq[MAX_SIZE];
node_pointer x, y, top;
int i, j, n;
printf(“Enter the size (<= %d) “, MAX_SIZE);
scanf(“%d”, &n);
for (i=0; i<n; i++) {
out[i]= TRUE; seq[i]= NULL;
}
printf(“Enter a pair of numbers (-1 -1 to quit): “);
scanf(“%d%d”, &i, &j);

Data Structures & Algorithms 46


…Equivalence relations
• Program (3/4)
while (i>=0) { //Phase 1: input the equivalence pairs:
x = (node_pointer) malloc(sizeof(node));
if (IS_FULL(x))
fprintf(stderr, “memory is full\n”);
exit(1);
}
x->data= j; x->link= seq[i]; seq[i]= x; //Insert x to the top of lists seq[i]
x = (node_pointer) malloc(sizeof(node));
if (IS_FULL(x))
fprintf(stderr, “memory is full\n”);
exit(1);
}
x->data= i; x->link= seq[j]; seq[j]= x; //Insert x to the top of lists seq[j]
printf(“Enter a pair of numbers (-1 -1 to quit): “);
scanf(“%d%d”, &i, &j);
}
Data Structures & Algorithms 47
…Equivalence relations
•Program (4/4)
for (i=0; i<n; i++) {
if (out[i]) { //Phase 2: output the equivalence classes
printf(“\nNew class: %5d”, i);
out[i]= FALSE; //mark class as output
x = seq[i]; top = NULL; //initialize stack
for (;;) { //find the entire class
while (x) { //process a list
j = x->data;
if (out[j]) { // first time, visit this seq[j]
printf(“%5d”, j);
out[j] = FALSE;
y = x->link; x->link = top; //push the linked number to stack if it links to
top = x; x = y; // number another
} else x = x->link;
}
if (!top) break; //stack empty
x = seq[top->data]; top = top->link; //pop from stack to find the same class number
} //for (;;)
} // for (i=0; i<n; i++)
} //main()
Data Structures & Algorithms 48
Sparse matrices
• Sparse matrices
• Each column of a sparse matrix is represented as a circularly linked list with a
head node
• A similar representation for each row of a sparse matrix
• Each node has a tag field that is used to distinguish between head nodes and
entry nodes
• Each head node has three fields: down, right, and next
• down field: links into a column list
• right field: links into a row list
• next field: links the head nodes together
• The head node for row i is also the head node for column i, and the total number
of head nodes is max {number of rows, number of columns}

Data Structures & Algorithms 49


…Sparse matrices
• Each entry node has 6 fields: tag, row, col, down, right, value.
• down field: links to the next nonzero term in the same column
• right field: links to the next nonzero term in the same row
• tag field: entry
• row field: row index
• col field: column index
• value field: nonzero value
• A num_rows × num_cols matrix with num_terms nonzero terms needs
max{num_rows, num_cols} + num_terms + 1 node
• max{num_rows, num_cols}: number of head nodes
• num_terms: number of nonzero terms
• 1 node: a special head node for the list of row and column head nodes contains the dimensions
of the matrix
• Total storage will be less than num_rows × num_cols when num_terms is
sufficiently small
Data Structures & Algorithms 50
…Sparse matrices

• Sparse matrices

entry #row #col


next
special head node of the list of head nodes
down head right
next
head node
entry i j
ai j
entry of aij

# of head nodes = max{# of rows, # of columns}

Data Structures & Algorithms 51


…Sparse matrices
é0 0 11 0 ù
ê12 5 0 0 ú
ê ú
ê0 -4 0 0 ú
ê ú
ë0 0 0 - 15 û

H1 H2 H3 H4
4• 4

0 2
H1 11

H2 1 0 1 1
12 5

2 1
H3 -4

3 3
H4
-15
Data Structures & Algorithms 52
Data Structures & Algorithms 52
…Sparse matrices
• Program (1) - Declarations
#include <stdio.h> struct MatrixNode {
#include <stdlib.h> MatrixPointer down;
#define MAX_SIZE 25 MatrixPointer right;
typedef enum {head,entry} tagfield; tagfield tag;
typedef struct MatrixNode *MatrixPointer; union {
struct EntryNode { MatrixPointer next;
int row; struct EntryNode entry;
int col; } u;
int value; };
}; MatrixPointer HdNode[MAX_SIZE];

Data Structures & Algorithms 53


…Sparse matrices
• Program (2) - Read in a matrix and set up its linked representation
MatrixPointer readM(void){
/* read in a matrix and set up its linked representation.
An auxilliary global array HdNode is used */
int NumRows, NumCols, NumEntries, NumHeads, i;
int row, col, value, CurrentRow;
MatrixPointer temp,last,node;

printf("Enter the number of rows, columns and entries: ");


scanf("%d,%d,%d",&NumRows, &NumCols, &NumEntries);
NumHeads = (NumCols > NumRows) ? NumCols : NumRows;
/* set up head node for the list of head nodes */
node = (MatrixPointer)malloc(sizeof(struct MatrixNode));
node->tag = entry;
node->u.entry.row = NumRows;
node->u.entry.col = NumCols;

Data Structures & Algorithms 54


…Sparse matrices
• Program (3) - Read in a matrix and set up its linked representation
if (!NumHeads) node->right = node; /* when list of head nodes is empty */
else { /* initialize the head nodes */
for (i = 0; i < NumHeads; i++) {
temp = (MatrixPointer)malloc(sizeof(struct MatrixNode));
HdNode[i] = temp;
HdNode[i]->tag = head;
HdNode[i]->right = temp;
HdNode[i]->u.next = temp;
}
CurrentRow = 0;
last = HdNode[0];
for (i = 0; i < NumEntries; i++) {
printf("Enter row, column and value: ");
scanf("%d,%d,%d",&row,&col,&value);
if (row > CurrentRow) {
last->right = HdNode[CurrentRow];
CurrentRow = row;
last = HdNode[row];
}
Data Structures & Algorithms 55
…Sparse matrices
• Program (4) - Read in a matrix and set up its linked representation
temp = (MatrixPointer)malloc(sizeof(struct MatrixNode));
temp->tag = entry; temp->u.entry.value = value;
temp->u.entry.row = row; temp->u.entry.col = col;
last->right = temp; /* link into row list */
last = temp;
HdNode[col]->u.next->down = temp; /* link into column list */
HdNode[col]->u.next = temp;
} // for
last->right = HdNode[CurrentRow];/*close last row */
for (i = 0; i < NumCols; i++) /* close all column lists */
HdNode[i]->u.next->down = HdNode[i];
for (i = 0; i < NumHeads-1; i++) /* link all head nodes together */
HdNode[i]->u.next = HdNode[i+1];
HdNode[NumHeads-1]->u.next = node;
node->right = HdNode[0];
} // if
return node;
}
Data Structures & Algorithms 56
…Sparse matrices
• Program (5) - Print out the matrix in each row
void writeM(MatrixPointer node){ /* print out the matrix in row major form */
int i;
MatrixPointer temp;
printf("\n\nNumRows = %d, NumCols = %d\n",
node->u.entry.row, node->u.entry.col);
printf(" The matrix by row, column, and value: \n\n");
for (i = 0; i < node->u.entry.row; i++) /* print out the entries in each row */
for (temp = HdNode[i]->right; temp != HdNode[i]; temp = temp->right)
printf("%5d%5d%5d\n",temp->u.entry.row,
temp->u.entry.col, temp->u.entry.value);
}

Data Structures & Algorithms 57


…Sparse matrices
• Program (6) - Erase the matrix
void merase(MatrixPointer *node){ /* erase the matrix, return the pointers to the
heap */
MatrixPointer x,y;
int i, NumHeads;
for (i = 0; i < (*node)->u.entry.row; i++) { /* free the entry pointers by row */
y = HdNode[i]->right;
while (y != HdNode[i]) {
x = y;
y = y->right;
free(x);
}
}
/* determine the number of head nodes and free these pointers */
NumHeads = ((*node)->u.entry.row > (*node)->u.entry.col) ?
(*node)->u.entry.row : (*node)->u.entry.col;
for (i = 0; i < NumHeads; i++)
free(HdNode[i]);
*node = NULL;
}
Data Structures & Algorithms 58
SUMMARY

• Linked List Basics

• Singly linked lists

• Circularly linked list

• Doubly linked lists

• Applications

Data Structures & Algorithms 59


Nhân bản – Phụng sự – Khai phóng

Enjoy the Course…!

Data Structures & Algorithms 60

You might also like