0% found this document useful (0 votes)
29 views72 pages

Chapter 4

This chapter discusses linked lists and pointers. It begins with an overview of pointers and how they allow elements in a linked list to be placed anywhere in memory by storing the address of the next node. It then covers singly linked lists, describing how they are drawn as a sequence of nodes connected by links and how this allows arbitrary insertion and deletion by changing the pointer links rather than shifting elements. Examples are provided of creating a two-node linked list and inserting a new node into an existing list.

Uploaded by

tanjuner01
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)
29 views72 pages

Chapter 4

This chapter discusses linked lists and pointers. It begins with an overview of pointers and how they allow elements in a linked list to be placed anywhere in memory by storing the address of the next node. It then covers singly linked lists, describing how they are drawn as a sequence of nodes connected by links and how this allows arbitrary insertion and deletion by changing the pointer links rather than shifting elements. Examples are provided of creating a two-node linked list and inserting a new node into an existing list.

Uploaded by

tanjuner01
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/ 72

Chapter 4

Linked Lists
Yi-Fen Liu
Department of IECS, FCU

References:
- E. Horowitz, S. Sahni and S. Anderson-Freed, Fundamentals of Data Structures (2nd Edition)
- Slides are credited from Prof. Chung, NTHU
Outline
• Pointers
• Singly Linked Lists
• Dynamically Linked Stacks and Queues
• Polynomials
• Chain
• Circularly Linked Lists
• Equivalence Relations
• Doubly Linked Lists
Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 2
POINTERS
Pointers (1)
• Consider the following alphabetized list
– (bat, cat, sat, vat)
• If we store this list in an array
– Add the word mat to this list
• move sat and vat one position to the right before we insert mat.
– Remove the word cat from the list
• move sat and vat one position to the left
• Problems of a sequence representation (ordered list)
– Arbitrary insertion and deletion from arrays can be very time-
consuming
– Waste storage

Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 4


Pointers (2)
0 1 2 3 4 5 6 7 8 9
list: 10 20 30 40 50
move= 5
Insert 25

0 1 2 3 4 5 6 7 8 9
list: 10 20 30
25 40
30 50
40 50
move= 4
Delete 20
0 1 2 3 4 5 6 7 8 9
list: 10 20
25 25
30 30
40 40
50 50

move = 5
Pointers (3)
• An elegant solution: using linked representation
– Items may be placed anywhere in memory
• Store the address, or location, of the next element in that list
for accessing elements in the correct order with each element
– The list element is a node which contains both a data component and
a pointer to the next item in the list
– The pointers are often called links

Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 6


Pointers (4)
• C provides extensive supports for pointers
• Two most important operators used with the pointer type
– & the address operator
– * the dereferencing (or indirection) operator
• Example
– int i, *pi;
• then i is an integer variable and pi is a pointer to an integer
– If we say “pi = &i;”
• then &i returns the address of i and assigns it as the value of pi
– To assign a value to i we can say
• i = 10; or *pi = 10;

Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 7


Pointers (5)
• Pointers can be dangerous
– It is a wise practice to set all pointers to NULL when they are not actually
pointing to an object
– Using explicit type cast when converting between pointer types
– Example
• pi = (int *) malloc(sizeof(int));
/*assign to pi a pointer to int*/
• pf = (float *)pi;
/*casts int pointer to float pointer*/
– In many systems, pointers have the same size as type int
• Since int is the default type specifier, some programmers omit the
return type when defining a function
• The return type defaults to int which can later be interpreted as a
pointer

Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 8


Pointers (6)
• Using dynamically allocated storage
– When programming, you may not know how much space you will
need, nor do you wish to allocate some vary large area that may
never be required
• C provides heap, for allocating storage at run-time
• You may call a function, malloc, and request the amount of
memory you need
• When you no longer need an area of memory, you may free it by
calling another function, free, and return the area of memory to
the system

Data Structures (Ch4) - 9 9


SINGLY LINKED LIST
Singly Linked Lists (1)
• Linked lists are drawn as an order sequence of
nodes with links represented as arrows
– The name of the pointer to the first node in the list
is the name of the list

Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 11


Singly Linked Lists (2)
• The nodes do not resident in sequential locations
• The locations of the nodes may change on different
runs
ptr

... Null
Link Field
Node
Data Field

chain
Data Structures (Ch4) - 12
Singly Linked Lists (3)
• Why it is easier to make arbitrary insertions
and deletions using a linked list?
– To insert the word mat between cat can sat, we
must
• Get a node that is currently unused; let its address be paddr
• Set the data field of this node to mat
• Set paddr’s link field to point to the address found in the link field
of the node containing sat
• Set the link field of the node containing cat to point to paddr

bat cat sat vat NULL

paddr mat
Data Structures (Ch4) - 13
Singly Linked Lists (4)
• Delete mat from the list
– We only need to find the element that immediately precedes mat,
which is cat, and set its link field to point to sat’s link
– We have not moved any data, and although the link field of mat
still points to sat, mat is no longer in the list

Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 14


Singly Linked Lists (5)
• We need the following capabilities to make linked
representations possible
– Defining a node’s structure, that is, the fields it contains.
We use self-referential structures, discussed in Chapter 2
to do this
– Create new nodes when we need them (malloc)
– Remove nodes that we no longer need (free)

Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 15


Singly Linked Lists (6)
• Self-Referential Structures
– One or more of its components is a pointer to itself
– typedef struct list {
char data;
list *link;
}
– list item1, item2, item3; Construct a list with three nodes
item1.data=‘a’; item1.link=&item2;
item2.data=‘b’; item2.link=&item3;
item3.data=‘c’; malloc: obtain a node (memory)
item1.link=&item2;
item2.link=&item3; free: release memory
item3.link=NULL;
a b c
Data Structures (Ch4) - 16
Singly Linked Lists (7)
• Example: List of words
typedef struct listNode *listPointer;
typedef struct listNode {
char data [4];
listPointer link;
};
– Creation
• listPointer ptr = NULL;
– Testing
• #define IS_EMPTY(ptr) (!(ptr))
– Allocation
• ptr = (listPointer) malloc (sizeof(listNode));
– Return the spaces
• free(ptr);

Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 17


Singly Linked Lists (8)
• Example: Two-node linked list
typedef struct listNode *listPointer;
typedef struct listNode {
int data;
listPointer link; #define IS_FULL(ptr) (!(ptr))
};
listPointer ptr =NULL; When returns NULL if there is no more memory.
• Program : Create a two-node list
listPointer create2( )
{
/* create a linked list with two nodes */
listPointer first, second;
first = (listPointer) malloc(sizeof(listNode));
second = (listPointer) malloc(sizeof(listNode));
second -> link = NULL;
second -> data = 20;
first -> data = 10;
first ->link = second;
return first;
} 10 20 NULL

first second
Singly Linked Lists (9)
• Insertion
– Observation
• insert a new node with data = 50 into the list ptr
after node
ptr 10 20 NULL
node

50

temp
Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 19
Singly Linked Lists (10)
• Implement Insertion
void insert(listPointer *ptr, listPointer node)
{
/* insert a new node with data = 50 into the list
ptr after node */
listPointer temp;
temp=(listPointer)malloc(sizeof(listNode));
if(IS_FULL(temp)){
fprintf(stderr, “The memory is full\n”);
exit(1);
}
temp->data=50; temp 50
Singly Linked Lists (11)
if(*ptr){ //nonempty list
temp->link = node->link;
node->link = temp;
}
else{ //empty list
temp->link = NULL;
*ptr = temp;
}
ptr
} 10 20 NULL
node

50

temp
Singly Linked Lists (12)
• Deletion
– Observation: delete node from the list

ptr trail node

10 50 20 NULL

ptr trail node

10 50 20 NULL

ptr

10 20 NULL
Singly Linked Lists (13)
• Implement Deletion:
void delete(listPointer *ptr, listPointer trail,
listPointer node)
{
/* delete node from the list, trail is the preceding node
ptr is the head of the list */
if(trail)
trail->link = node->link;
else
*ptr = (*ptr)->link;
ptr trail node
free(node);
}
10 50 20 NULL

Data Structures (Ch4) - 23


Singly Linked Lists (14)
• Print out a list (traverse a list)
– Program: Printing a list
void print_list(listPointer ptr)
{
printf(“The list contains: “);
for ( ; ptr; ptr = ptr->link)
printf(“%4d”, ptr->data);
printf(“\n”);
}

Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 24


DYNAMICALLY LINKED STACKS AND
QUEUES
Dynamically Linked Stacks and
Queues
• Both stack and the queue are easy insertion and
deletion of nodes by using link list
– Easily add or delete a node form the top of the stack
– Easily add a node to the rear of the queue and add or delete a
node at the front of a queue
Dynamically Linked Stacks (1)
 Represent n stacks Stack

top item link

link

...
NULL

Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 27


Dynamically Linked Stacks (2)
• Push in the linked stack
void add(stack_pointer *top, element item){
/* add an element to the top of the stack */
stack_pointer temp = (stack_pointer) malloc
(sizeof (stack));
if (IS_FULL(temp)) {
fprintf(stderr, “ The memory is full\n”);
exit(1);
} temp item link
temp->item = item;
temp->link = *top; top link
*top= temp;
} link

...
NULL
Data Structures (Ch4) - 28
Dynamically Linked Stacks (3)
• Pop from the linked stack
element delete(stack_pointer *top) {
/* delete an element from the stack */
stack_pointer temp = *top;
element item;
if (IS_EMPTY(temp)) {
fprintf(stderr, “The stack temp
is empty\n”);
exit(1); top item link
}
item = temp->item; link
*top = temp->link;
free(temp); link
return item;

...
}
NULL

Data Structures (Ch4) - 29


Dynamically Linked Queues (1)
• Represent n queues

Queue
front item link
Delete from
link

...
Add to
rear NULL
Data Structures (Ch4) - 30
Dynamically Linked Queues (2)
• enqueue in the linked queue

front link
link

...
rear NULL

temp item NULL


Dynamically Linked Queues (3)
• dequeue from the linked queue (similar to push)

temp
front item link

link
link

...
rear NULL
Dynamically Linked Stacks and
Queues
• The solution presented above to the n-stack,
m-queue problem is both computationally and
conceptually simple
– We no longer need to shift stacks or queues to
make space
– Computation can proceed as long as there is
memory available

Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 33


POLYNOMIALS
Polynomials (1)
• Representing polynomials as singly linked lists
– In general, we want to represent the polynomial
A( x )  am 1 x em 1      a0 x e0
• Where the ai are nonzero coefficients and the ei are
nonnegative integer exponents such that
em-1 > em-2 > … > e1 > e0 ≧ 0
– We will represent each term as a node containing
coefficient and exponent fields, as well as a
pointer to the next term

Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 35


Polynomials (2)
• Assuming that the coefficients are integers, the type
declarations are
typedef struct poly_node *poly_pointer;
typedef struct poly_node {
int coef;
int expon; a  3 x 14
 2 x8
1
poly_pointer link;
};
poly_pointer a,b,d; b  8x14  3x10  10x 6
• Draw poly_nodes as
coef expon link

Data Structures (Ch4) - 36


Polynomials (3)
• Adding Polynomials
– To add two polynomials, we examine their terms
starting at the nodes pointed to by a and b
• If the exponents of the two terms are equal
– add the two coefficients
– create a new term for the result
• If the exponent of the current term in a is less than b
– create a duplicate term of b
– attach this term to the result, called d
– advance the pointer to the next term in b.
• We take a similar action on a if a->expon > b->expon

Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 37


Polynomials (4)
Generating the first three terms of d = a+b
Polynomials (5)

Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 39


Polynomials
(6)
Polynomials (7)
• Attach a node to the end of a list
void attach(float coefficient, int exponent, poly_pointer *ptr){
/* create a new node with coef = coefficient and expon = exponent,
attach it 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));
/* create new node */
if (IS_FULL(temp)) {
fprintf(stderr, “The memory is full\n”);
exit(1);
}
temp->coef = coefficient; /* copy item to the new node */
temp->expon = exponent;
(*ptr)->link = temp; /* attach */
*ptr = temp; /* move ptr to the end of the list */
}

Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 41


Polynomials (8)
• Analysis of padd
A( x )(  am 1 x em 1      a0 x e0 )  B( x )(  bn 1 x f n 1    b0 x f 0 )
– coefficient additions
0  additions  min(m, n)
where m (n) denotes the number of terms in A (B).
– exponent comparisons
extreme case:
em-1 > fm-1 > em-2 > fm-2 > … > e1 > f1 > e0 > f0
m+n-1 comparisons
– creation of new nodes
extreme case:
maximum number of terms in d is m+n (m + n new nodes)
summary: O(m+n)

Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 42


Polynomials (9)
• A Suite for Polynomials read_poly()
e(x) = a(x) * b(x) + d(x) print_poly()
poly_pointer a, b, d, e; padd()
... psub()
a = read_poly(); pmult()
b = read_poly();
d = read_poly();
temp is used to hold a partial result.
temp = pmult(a, b); By returning the nodes of temp, we
may use it to hold other polynomials
e = padd(temp, d);
print_poly(e);

Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 43


Polynomials (10)
• Erase Polynomials
– erase frees the nodes in temp
void erase (poly_pointer *ptr){
/* erase the polynomial pointed to by ptr */
poly_pointer temp;
while ( *ptr){
temp = *ptr;
*ptr = (*ptr) -> link;
free(temp);
}
}

Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 44


CHAIN
Chain (1)
• Chain
– A singly linked list in which the last node has a null link
• Operations for chains
– Inverting a chain
• For a list of length ≧1 nodes, the while loop is executed length times
and so the computing time is linear or O(length).

... NULL

lead
invert

× ...
NULL

lead
Chain (2)

Two extra pointers

trial

middle
lead middle
lead trial NULL

...

NULL
Chain (3)
• Concatenates two
chains
– Concatenates two chains,
ptr1 and ptr2.
– Assign the list ptr1
followed by the list ptr2.

O(length of list ptr1)

temp

NULL NULL

ptr1 ptr2
CIRCULARLY LINKED LISTS
Circularly Linked Lists
• Circular Linked list
– The link field of the last node points to the first
node in the list
• Example
– Represent a polynomial ptr = 3x14+2x8+1 as a
circularly linked list

ptr 3 14 2 8 1 0

Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 50


Maintain an Available List (1)
• We free nodes that are no longer in use so
that we may reuse these nodes later
• We can obtain an efficient erase algorithm for
circular lists, by maintaining our own list (as a
chain) of nodes that have been “freed”
• Instead of using malloc and free, we now use
get_node and ret_node
avail ... NULL

List of freed nodes


Maintain an Available List (2)
• When we need a new node, we examine this list
– If the list is not empty, then we may use one of its nodes.
– Only when the list is empty we have to use malloc to
create a new node
Maintain an Available List (3)
• Insert ptr to the front of this list
– Let avail be a variable of type poly_pointer that points to the first
node in our list of freed nodes
– Henceforth, we call this list the available space list or avail list
– Initially, we set avail to NULL

Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 53


Maintain
an Available List (4)
• Erase a circular list in a
fixed amount (constant)
of time O(1) independent
of the number of nodes
in the list using cerase

ptr      

temp

avail      NULL

紅色link所連接而成的 chain
Polynomial Representations (1)
• We must handle the zero polynomial as a special case
– To avoid it, we introduce a head node into each polynomial
– Each polynomial, zero or nonzero, contains one additional node
– The expon and coef fields of this node are irrelevant
Polynomial
Representations
/* head node */
(2)
• For fit the circular
list with head node
/*a->expont > -1, b->expont > -1 */
representation
– We may remove
the test for (*ptr)
from cerase (p.168)
– Changes the
original padd to /* link to the first node */
cpadd
Circularly Linked Lists (1)
• Operations for circularly linked lists
– Question
• What happens when we want to insert a new node at
the front of the circular linked list ptr?

ptr x1 x2 x3
– Answer
• move down the entire length of ptr.
– Possible Solution

x1 x2 x3 ptr
Circularly Linked Lists (2)
• Insert a new node at
the front of a circular
list
• To insert node at the
rear, we only need to
add the additional
statement *ptr = node
to the else clause of
insert_front

x1 x2 x3 ptr

node
Circularly Linked Lists (3)
• Finding the length of a circular list

Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 59


EQUIVALENCE RELATIONS
Equivalence Relations (1)
• Reflexive Relation
– For any polygon x, x ≡ x (e.g., x is electrically equivalent to itself)
• Symmetric Relation
– For any two polygons x and y, if x ≡ y, then y ≡ x
• Transitive Relation
– For any three polygons x, y, and z, if x ≡ y and y ≡ z, then x ≡ z
• Definition
– A relation over a set, S, is said to be an equivalence relation over S iff it
is symmetric, reflexive, and transitive over S
• Example
– “equal to” relationship is an equivalence relation

Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 61


Equivalence Relations (2)
• Example
– If we have 12 polygons numbered 0 through 11
0  4, 3  1, 6  10, 8  9, 7  4, 6  8, 3  5, 2  11, 11  0
we can partition the twelve polygons into the following equivalence
classes
{0, 2, 4, 7, 11}, {1, 3, 5}, {6, 8, 9,10}
• Two phases to determine equivalence
– First phase: the equivalence pairs (i, j) are read in and stored
– Second phase:
• We begin at 0 and find all pairs of the form (0, j)
Continue until the entire equivalence class containing 0 has been
found, marked, and printed
– Next find another object not yet output, and repeat the above process

Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 62


Equivalence Relation (3)
• Program to find equivalence classes
#include <stdio.h>
void main(void){ #define MAX_SIZE 24
short int out[MAX_SIZE];
#define IS_FULL(ptr) (!(ptr))
node_pointer seq[MAX_SIZE];
node_pointer x, y, top; #define FALSE 0
int i, j, n; #define TRUE 1
printf(“Enter the size (<=%d) ”, MAX_SIZE);
scanf(“%d”, &n);
for(i=0; i<n; i++){
/*initialize seq and out */
out[i] = TRUE;
seq[i] = NULL;
} typedef struct node *node_pointer;
/* Phase 1 */ typedef struct node {
/* Phase 2 */ int data;
}
node_pointer link;
};
Data Structures (Ch4) - 64
Equivalence Relations (4)
• Phase 1: read in and store the equivalence pairs <i, j>
[0] 11 4 NULL

[1] 3 NULL

[2] 11 NULL
[3] 5 1 NULL

[4] 7 0 NULL
(1) (2)
[5] 3 NULL Insert x to the top of lists seq[i]
[6] 8 10 NULL
[7] 4 NULL

[8] 6 9 NULL

[9] 8 NULL

[10] 6 NULL
Insert x to the top of lists seq[j]
[11] 0 2 NULL

0  4, 3  1, 6  10, 8  9, 7  4, 6  8, 3  5, 2  11, 11  0
Equivalence Relations (5)
• Phase 2
– Begin at 0 and find all pairs of the form <0, j>,
where 0 and j are in the same equivalence class
– By transitivity, all pairs of the form <j, k> imply
that k in the same equivalence class as 0
– Continue this way until we have found, marked,
and printed the entire equivalent class containing
0

Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 65


Equivalence Relations (6)
x
y [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]

 Phase 2 i= 1
0 j= 11
7
2
4
0 out:
top
[0] 11 4 NULL

[1] 3 NULL

[2] 11 NULL
[3] 5 1 NULL

[4] 7 0 NULL

[5] 3 NULL

[6] 8 10 NULL
[7] 4 NULL

[8] 6 9 NULL

[9] 8 NULL

[10] 6 NULL

[11] 0 2 NULL

New class: 0 11 4 7 2
DOUBLY LINKED LISTS
Doubly Linked Lists (1)
• Singly linked lists pose problems because we can
move easily only in the direction of the links
... NULL

? ptr
• Doubly linked list has at least three fields
– left link field (llink), data field (item), right link field (rlink)
– The necessary declarations
typedef struct node *node_pointer;
typedef struct node{
node_pointer llink;
element item;
node_pointer rlink;
};
Data Structures (Ch4) - 68
Doubly Linked Lists (2)
• Sample
– doubly linked circular with head node

Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 69


Doubly Linked Lists (3)
– empty double linked circular list with head node

– suppose that ptr points to any node in a doubly


linked list, then:
• ptr = ptr -> llink -> rlink = ptr -> rlink -> llink

Yi-Fen Liu, FCU IECS Data Structures (Ch4) - 70


Doubly Linked Lists (4)

Insert a node

Head node

node

llink item rlink

New node
Doubly Linked Lists (5)

Delete a node

Head node

llink item rlink


deleted node

You might also like