EEE 2108 Programming for Engineers Chapter 4 Linked

  • Slides: 42
Download presentation
EEE 2108: Programming for Engineers Chapter 4. Linked Lists

EEE 2108: Programming for Engineers Chapter 4. Linked Lists

4. 1 Singly Linked Lists and Chains Sequential representation : Use arrays § Linked

4. 1 Singly Linked Lists and Chains Sequential representation : Use arrays § Linked representation : Use pointers : Easy to handle insertion/deletion operations § Ex. (BAT, CAT, EAT, FAT, HAT, JAT, LAT, MAT, OAT, PAT, RAT, SAT, VAT, WAT) § Insertion of GAT -> rearrange of the array § Data and link (pointer) expressions § List and Chain § Singly linked list: each node has exactly one pointer field § Chain: a singly linked list that is comprised of zero or more nodes (the last node has a null link) §

Representation § Non-sequential list representation § Using pointers : Usual way to draw a

Representation § Non-sequential list representation § Using pointers : Usual way to draw a linked list : The values in this array are pointers to elements in the data array

§ To insert the data item GAT between FAT and HAT, the following steps

§ To insert the data item GAT between FAT and HAT, the following steps are adequate: (1) Get a node a that is currently unused (2) Set the data field of a to GAT (3) Set the link field of a to point to the node after FAT, which contains HAT (4) Set the link field of the node containing FAT to a

§ § Deleting an element from the list § Find the element that we

§ § Deleting an element from the list § Find the element that we want to delete § Set the link field of the previous element to point to next element § There is no need to move the data around To delete GAT

4. 2 Representing Chains in C § Operations on list: § A mechanism for

4. 2 Representing Chains in C § Operations on list: § A mechanism for defining a node's structure, selfreferential structures § A way to create new nodes when we need them, malloc( ) § A way to remove nodes that we no longer need, free( ) § To create a linked list of words, we first define a node structure for the list typedef struct list. Node *list. Pointer; typedef struct list. Node { char data[4]; list. Pointer link; }; list. Pointer first = NULL;

A macro to test for an empty list : #define IS_EMPTY(first) (!(first)) § Creating

A macro to test for an empty list : #define IS_EMPTY(first) (!(first)) § Creating new nodes : Use the malloc function provided in <alloc. h>. first = (list. Node*) malloc(sizeof(struct list. Node)); MALLOC(first, sizeof(*first)); § Assigning the values to the fields of the node: If e is a pointer to a structure that contains the field name, e->name is a shorthand way of writing the expression (*e). name §

§ To place the word BAT into the list : strcpy (first->data, “BAT"); first->link

§ To place the word BAT into the list : strcpy (first->data, “BAT"); first->link = NULL; Declaration [Example] Two-node linked list To create a linked list of integers, the node structure is defined as: § typedef struct list. Node *list. Pointer; typedef struct list. Node { int data; list. Pointer link; };

§ Creating a two-node list [Program 4. 1] list. Pointer create 2() { /*

§ Creating a two-node list [Program 4. 1] list. Pointer create 2() { /* create a linked list with two nodes list. Pointer first, second; MALLOC(first, sizeof(*first)); MALLOC(second, sizeof(*second)); second->link = NULL; second->data = 20; first->data = 10; first->link = second; return first; } */

List insertion [Example] List insertion • To insert a node with data field of

List insertion [Example] List insertion • To insert a node with data field of 50 after some arbitrary node • Note that we use the parameter declaration list. Pointer temp §

[Program 4. 2] Simple insert into list void insert(list. Pointer *first, list. Pointer x)

[Program 4. 2] Simple insert into list void insert(list. Pointer *first, list. Pointer x) { /* insert a new node with data=50 into the list */ list. Pointer temp; MALLOC(temp, sizeof(*temp)); temp->data=50; if (*first) { temp->link = x->link; x->link = temp; } else { temp->link = NULL; *first = temp; } }

List deletion [Example] List deletion • Deletion depends on the location of the node.

List deletion [Example] List deletion • Deletion depends on the location of the node. § • trail is the preceding node of x

[Program 4. 3] Deletion from a list void delete(list. Pointer *first, list. Pointer trail,

[Program 4. 3] Deletion from a list void delete(list. Pointer *first, list. Pointer trail, list. Pointer x) { /* delete node from the list, trail is the preceding node and *first is the front of the list */ if (trail) trail->link = x->link; else *first = (*first)->link; free(x); }

Printing out a list [Program 4. 4] Printing a list § void print. List(list.

Printing out a list [Program 4. 4] Printing a list § void print. List(list. Pointer first) { printf("The list contains: "); for ( ; first = first->link) printf("%4 d", first->data); printf("n"); }

4. 3 Linked Stacks and Queues § § Sequential representation is proved efficient if

4. 3 Linked Stacks and Queues § § Sequential representation is proved efficient if we had only one stack or one queue When several stacks and queues coexist, there is no efficient way to represent them sequentially

§ Stack Declarations : If we wish to represent n <= MAX_STACKS stacks simultaneously,

§ Stack Declarations : If we wish to represent n <= MAX_STACKS stacks simultaneously, we begin with the declarations: #define MAX_STACKS 10 /* maximum number of stacks */ typedef struct { int key; /* other fields */ } element; typedef struct stack *stack. Pointer; typedef struct stack { element data; stack. Pointer link; }; stack. Pointer top[MAX_STACKS]; § Push/Pop operations

[Programs 4. 5, 4. 6] Add to/Delete from a linked stack void push(int i,

[Programs 4. 5, 4. 6] Add to/Delete from a linked stack void push(int i, element item) { /* add item to the ith stack */ stack. Pointer temp; MALLOC(temp, sizeof(*temp)); temp->data = item; temp->link = top[i]; top[i] = temp; } element pop(int i) { /* remove top element from the ith stack */ stack. Pointer temp = top[i]; element item; if (!temp) return stack. Empty(); item = temp->data; top[i] = temp->link; free (temp) ; return item; }

§ Queue Declarations #define MAX_QUEUES 10 /* maximum number of queues */ typedef struct

§ Queue Declarations #define MAX_QUEUES 10 /* maximum number of queues */ typedef struct { int key; /* other fields */ } element; typedef struct queue *queue. Pointer; typedef struct queue { element item; queue. Pointer link; }; queue. Pointer front[MAX_QUEUES], rear[MAX_QUEUES]; § § front[i] = NULL, 0 <= i <= MAX_QUEUES Initial condition Boundary condition top[i] = NULL if ith queue is empty

Add [Program 4. 7] Add to the rear of a linked queue § void

Add [Program 4. 7] Add to the rear of a linked queue § void addq(int i, element item) { /* add item to the rear of queue i */ queue. Pointer temp; MALLOC(temp, sizeof(*temp)); temp->data = item; temp->link = NULL; if (front[i]) rear[i]->link = temp; else front[i] = temp; rear[i] = temp; }

Delete [Program 4. 8] Delete from the front of a linked queue § element

Delete [Program 4. 8] Delete from the front of a linked queue § element deleteq(int i) { /* delete an element from queue i */ queue. Pointer temp = front[i]; element item; if (!temp) return queue. Empty(); item = temp->data; front[i]= temp->link; free(temp) ; return item; }

4. 4 Polynomials 4. 4. 1 Polynomial Representation § We want to represent the

4. 4 Polynomials 4. 4. 1 Polynomial Representation § We want to represent the polynomial: where ai are nonzero coefficients, ei are nonnegative integer exponents em-1 > em-2 >. . . > e 1 > e 0 ≥ 0 § Declarations typedef struct poly. Node *poly. Pointer; typedef struct poly. Node { float coef; int expon; poly. Pointer link; }; poly. Pointer a, b;

§ Representation 4. 4. 2 Adding Polynomials

§ Representation 4. 4. 2 Adding Polynomials

4. 4. 3 Erasing Polynomials § Write a collection of functions for input, addition,

4. 4. 3 Erasing Polynomials § Write a collection of functions for input, addition, subtraction, and multiplication of polynomials using linked list § Suppose we wish to compute e(x) = a(x) * b(x) + d(x): poly_pointer a, b, d, e; • • • a = read_poly(); b = read_poly(); d = read_poly(); temp = pmult(a, b); e = padd(temp, d); print_poly(e);

Erasing [Program 4. 11] Erasing a polynomial § void erase(poly. Pointer *ptr) { /*

Erasing [Program 4. 11] Erasing a polynomial § void erase(poly. Pointer *ptr) { /* erase the polynomial pointed by ptr */ poly. Pointer temp; while (*ptr) { temp = *ptr; *ptr = (*ptr)->link; free(temp); } }

4. 4. 4 Circular List Presentation of Polynomials § To free all the nodes

4. 4. 4 Circular List Presentation of Polynomials § To free all the nodes of a polynomial more efficiently, modify list structure so that the link field of the last node points to the first node in the list : circular list § Chain : a singly linked list in which the last node has a null link § Example: 3 x 14 + 2 x 8 + 1

§ § § For circular lists, we obtain an efficient erase algorithm § Maintain

§ § § For circular lists, we obtain an efficient erase algorithm § Maintain our own list of nodes that have been “freed” § When we need a new node, examine this list. If the list is not empty, then use one of its nodes. Only when the list is empty, use malloc to create a new node Let avail be a variable of type poly. Pointer that points to the first node in list of freed nodes: available space list § Initially, we set avail to NULL Instead of using malloc and free, we now use get. Node (Program 4. 12) and ret. Node (Program 4. 13).

[Programs 4. 12, 4. 13] get. Node and ret. Node functions poly. Pointer get.

[Programs 4. 12, 4. 13] get. Node and ret. Node functions poly. Pointer get. Node(void) { /* provide a node for use */ poly. Pointer node; if (avail) { node = avail; avail = avail->link; } else MALLOC(node, sizeof(*node)); return node; } void ret. Node(poly. Pointer node) { /* return a node to the available list */ node->link = avail; avail = node; }

Erasing a circular list § We may erase a circular list in a fixed

Erasing a circular list § We may erase a circular list in a fixed amount of time independent of the number of nodes in the list as follows: [Program 4. 14] Erasing a circular list § void cerase(poly. Pointer *ptr) { /* erase the circular list pointed to by ptr */ poly. Pointer temp; if (*ptr) { temp = (*ptr)->link; (*ptr)->link = avail; avail = temp; *ptr = NULL; } }

§ § The previous structure creates problems when we implement the other polynomial operations

§ § The previous structure creates problems when we implement the other polynomial operations since we must handle the zero polynomial as a special case To avoid this special case, we introduce a head node into each polynomial

Adding two polynomials § We may further simplify the addition algorithm if we set

Adding two polynomials § We may further simplify the addition algorithm if we set the expon field of the head node to -1 [Program 4. 15] Adding two polynomials represented as circular lists with header nodes §

4. 5 Additional Operations 4. 5. 1 Operations for Chains § We use the

4. 5 Additional Operations 4. 5. 1 Operations for Chains § We use the following declarations : typedef struct list. Node *list. Pointer; typedef struct list. Node { char data; list. Pointer link; }; § Inverting a chain : We can do it "in place" if we use three pointers

[Program 4. 16] Inverting a singly linked list. Pointer invert(list. Pointer lead) { /*

[Program 4. 16] Inverting a singly linked list. Pointer invert(list. Pointer lead) { /* invert the list pointed to by lead */ list. Pointer middle, trail; middle = NULL; while (lead) { trail = middle; middle = lead; lead = lead->link; middle->link = trail; } return middle; }

§ Concatenating two chains [Program 4. 17] Concatenating singly linked lists list. Pointer concatenate(list.

§ Concatenating two chains [Program 4. 17] Concatenating singly linked lists list. Pointer concatenate(list. Pointer ptr 1, list. Pointer ptr 2) { /* produce a new list that contains the list ptr 1 followed by ptr 2. The list pointed to by ptr 1 is changed permanently */ list. Pointer temp; /* check for empty lists */ if (!ptr 1) return ptr 2; if (!ptr 2) return ptr 1; /* neither list is empty, find end of first list */ for (temp = ptr 1; temp->link; temp = temp->link) /* link end of first to start of second */ temp->link = ptr 2; }

4. 5. 2 Operations on Circularly Linked Lists § By keeping a pointer ‘last’

4. 5. 2 Operations on Circularly Linked Lists § By keeping a pointer ‘last’ to the last node in the list, we can insert an element at both the front and end with ease § Inserting at the front of a list

[Program 4. 18] Inserting at the front of a list void insert. Front(list. Pointer

[Program 4. 18] Inserting at the front of a list void insert. Front(list. Pointer *last, list. Pointer node) { /* insert node at the front of the circular list last, where last is the last node in the list. */ if (!(*last)) { /* list is empty, change last to point to new entry */ *last = node; node->link = node; } else { /* list is not empty, add new entry at front */ node->link = (*last)->link; (*last)->link = node; } last } node

Finding the length of a circular list [Program 4. 19] Finding the length of

Finding the length of a circular list [Program 4. 19] Finding the length of a circular list § int length(list. Pointer last) { /* find the length of the circular list last */ list. Pointer temp; int count = 0; if (last) { temp = last; do { count++; temp = temp->link; } while (temp != last); } return count; }

4. 6 Sparse Matrices 4. 7. 1 Sparse Matrix Representation § Save space and

4. 6 Sparse Matrices 4. 7. 1 Sparse Matrix Representation § Save space and computing time by retaining only the nonzero terms of sparse matrices § Header nodes and entry nodes

Linked representation

Linked representation

4. 8 Doubly Linked Lists § § § Singly linked list § The only

4. 8 Doubly Linked Lists § § § Singly linked list § The only way to find the node that precedes p (specific node) is to start at the beginning of the list § The same problem arises when one wishes to delete an arbitrary node from a singly linked list Doubly linked list § Each node has tow link fields, one linking in the forward direction and the other linking in the backward direction Declarations: typedef struct node *node. Pointer; typedef struct node { node. Pointer llink; element item; node. Pointer rlink; };

Insertion/Deletion [Program 4. 26, 4. 27] void dinsert(node. Pointer node, node. Pointer newnode) {

Insertion/Deletion [Program 4. 26, 4. 27] void dinsert(node. Pointer node, node. Pointer newnode) { /* insert newnode to the right of node */ newnode->llink = node; newnode->rlink = node->rlink; node->rlink->llink = newnode; node->rlink = newnode; } void delete(node. Pointer node, node. Pointer deleted) { /* delete from the doubly linked list */ if (node == deleted) printf("Deletion of head node not permitted. n"); else { deleted->llink->rlink = deleted->rlink; deleted->rlink->llink = deleted->llink; free(deleted); } }