Download presentation
Presentation is loading. Please wait.
Published byDelilah Grant Modified over 6 years ago
1
EEE2108: Programming for Engineers Chapter 4. Linked Lists
2
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)
3
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
4
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
6
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
7
4.2 Representing Chains in C
Operations on list: A mechanism for defining a node's structure, self-referential 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 listNode *listPointer; typedef struct listNode { char data[4]; listPointer link; }; listPointer first = NULL;
8
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 = (listNode*) malloc(sizeof(struct listNode)); 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
9
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 listNode *listPointer; typedef struct listNode { int data; listPointer link; };
10
Creating a two-node list [Program 4.1]
listPointer create2() { /* create a linked list with two nodes */ listPointer first, second; MALLOC(first, sizeof(*first)); MALLOC(second, sizeof(*second)); second->link = NULL; second->data = 20; first->data = 10; first->link = second; return first; }
11
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 listPointer temp
12
[Program 4.2] Simple insert into list
void insert(listPointer *first, listPointer x) { /* insert a new node with data=50 into the list */ listPointer temp; MALLOC(temp, sizeof(*temp)); temp->data=50; if (*first) { temp->link = x->link; x->link = temp; } else { temp->link = NULL; *first = temp;
13
[Example] List deletion Deletion depends on the location of the node.
trail is the preceding node of x
14
[Program 4.3] Deletion from a list
void delete(listPointer *first, listPointer trail, listPointer 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); }
15
[Program 4.4] Printing a list
Printing out a list [Program 4.4] Printing a list void printList(listPointer first) { printf("The list contains: "); for ( ; first; first = first->link) printf("%4d", first->data); printf("\n"); }
16
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
17
Stack Declarations : If we wish to represent n <= MAX_STACKS stacks simultaneously, we begin with the declarations: Push/Pop operations #define MAX_STACKS 10 /* maximum number of stacks */ typedef struct { int key; /* other fields */ } element; typedef struct stack *stackPointer; typedef struct stack { element data; stackPointer link; }; stackPointer top[MAX_STACKS];
18
[Programs 4.5, 4.6] Add to/Delete from a linked stack
void push(int i, element item) { /* add item to the ith stack */ stackPointer 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 */ stackPointer temp = top[i]; element item; if (!temp) return stackEmpty(); item = temp->data; top[i] = temp->link; free (temp) ; return item; }
19
Queue Declarations Initial condition Boundary condition
#define MAX_QUEUES 10 /* maximum number of queues */ typedef struct { int key; /* other fields */ } element; typedef struct queue *queuePointer; typedef struct queue { element item; queuePointer link; }; queuePointer front[MAX_QUEUES], rear[MAX_QUEUES]; front[i] = NULL, 0 <= i <= MAX_QUEUES top[i] = NULL if ith queue is empty
20
[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 */ queuePointer 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; }
21
[Program 4.8] Delete from the front of a linked queue
element deleteq(int i) { /* delete an element from queue i */ queuePointer temp = front[i]; element item; if (!temp) return queueEmpty(); item = temp->data; front[i]= temp->link; free(temp) ; return item; }
22
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 > > e1 > e0 ≥ 0 Declarations typedef struct polyNode *polyPointer; typedef struct polyNode { float coef; int expon; polyPointer link; }; polyPointer a, b;
23
Representation 4.4.2 Adding Polynomials
25
Suppose we wish to compute e(x) = a(x) * b(x) + d(x):
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);
26
[Program 4.11] Erasing a polynomial
void erase(polyPointer *ptr) { /* erase the polynomial pointed by ptr */ polyPointer temp; while (*ptr) { temp = *ptr; *ptr = (*ptr)->link; free(temp); }
27
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: 3x14 + 2x8 + 1
28
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 polyPointer 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 getNode (Program 4.12) and retNode (Program 4.13).
29
[Programs 4.12, 4.13] getNode and retNode functions
polyPointer getNode(void) { /* provide a node for use */ polyPointer node; if (avail) { node = avail; avail = avail->link; } else MALLOC(node, sizeof(*node)); return node; void retNode(polyPointer node) { /* return a node to the available list */ node->link = avail; avail = node; }
30
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(polyPointer *ptr) { /* erase the circular list pointed to by ptr */ polyPointer temp; if (*ptr) { temp = (*ptr)->link; (*ptr)->link = avail; avail = temp; *ptr = NULL; }
31
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
32
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
33
4.5 Additional Operations
Operations for Chains We use the following declarations : Inverting a chain : We can do it "in place" if we use three pointers typedef struct listNode *listPointer; typedef struct listNode { char data; listPointer link; };
34
[Program 4.16] Inverting a singly linked list
listPointer invert(listPointer lead) { /* invert the list pointed to by lead */ listPointer middle, trail; middle = NULL; while (lead) { trail = middle; middle = lead; lead = lead->link; middle->link = trail; } return middle;
35
Concatenating two chains
[Program 4.17] Concatenating singly linked lists listPointer concatenate(listPointer ptr1, listPointer ptr2) { /* produce a new list that contains the list ptr1 followed by ptr2. The list pointed to by ptr1 is changed permanently */ listPointer temp; /* check for empty lists */ if (!ptr1) return ptr2; if (!ptr2) return ptr1; /* neither list is empty, find end of first list */ for (temp = ptr1; temp->link; temp = temp->link) /* link end of first to start of second */ temp->link = ptr2; }
36
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
37
[Program 4.18] Inserting at the front of a list
void insertFront(listPointer *last, listPointer 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
38
Finding the length of a circular list
[Program 4.19] Finding the length of a circular list int length(listPointer last) { /* find the length of the circular list last */ listPointer temp; int count = 0; if (last) { temp = last; do { count++; temp = temp->link; } while (temp != last); } return count;
39
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
40
Linked representation
41
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 *nodePointer; typedef struct node { nodePointer llink; element item; nodePointer rlink; };
42
Insertion/Deletion [Program 4.26, 4.27]
void dinsert(nodePointer node, nodePointer newnode) { /* insert newnode to the right of node */ newnode->llink = node; newnode->rlink = node->rlink; node->rlink->llink = newnode; node->rlink = newnode; } void delete(nodePointer node, nodePointer 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); }
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.