1240-222 CPT: Lists/15
240-222 Computer Programming Techniques240-222 Computer Programming TechniquesSemester 1, 1998Semester 1, 1998
Objective of these slides:– to describe linked lists in C
15. Lists
2240-222 CPT: Lists/15
OverviewOverview
1. List Data Structures and Operations
2. List Implementations
3. Dynamically Created Lists
4. Converting a String to a List
5. List Functions
3240-222 CPT: Lists/15
1. List Data Structures and Operations1. List Data Structures and Operations
Some possible operations:• create/destroy a list
• test to see if a list is empty
• return the tail of the list
• insert/delete elements
• print a list
• calculate the length of a list
4240-222 CPT: Lists/15
2. List implementations2. List implementations
Version 1:
#define N 1000 /* the size of the list */
typedef char LIST[N];
LIST lt; /* same as char lt[N] */
5240-222 CPT: Lists/15
Version 2Version 2 (Sec. 12.2)(Sec. 12.2)
struct listnode { char data; struct listnode *nextptr;};
typedef struct listnode LISTNODE;
LISTNODE elem;elem
data nextptr
6240-222 CPT: Lists/15
UseUseLISTNODE a, b, c;
a.data = 'a';b.data = 'c';c.data = 'e';
a.nextptr = b.nextptr = c.nextptr = NULL;
continued
a b c
7240-222 CPT: Lists/15
a.nextptr = &b;b.nextptr = &c;
printf("%c", a.nextptr->data);/* 'c' printed */
printf("%c", a.nextptr->nextptr->data);/* 'e' printed */
a b c
NULL‘a’ ‘c’ ‘e’
8240-222 CPT: Lists/15
3. Dynamically Created Lists3. Dynamically Created Lists
/* list implementation as before */typedef LISTNODE *LNP;
LNP head = NULL;head = malloc(sizeof(LISTNODE));head->data = 'n';head->nextptr = NULL;
Function prototype in stdlib.h: void *malloc(size_t size);
head ‘n’ NULL
9240-222 CPT: Lists/15
Add a second elementAdd a second element
head->nextptr = malloc(sizeof(LISTNODE));
head->nextptr->data = 'e';head->nextptr->nextptr = NULL;
head ‘n’ ‘e’ NULL
10240-222 CPT: Lists/15
Add a third elementAdd a third element
head->nextptr->nextptr = malloc(sizeof(LISTNODE));
head->nextptr->nextptr->data = 'w';head->nextptr->nextptr->nextptr = NULL;
head ‘n’ ‘e’ ‘w’ NULL
11240-222 CPT: Lists/15
4. Converting a String to a List4. Converting a String to a List
#include <stdio.h>#include <stdlib.h>/* list type implementation */
LNP string_to_list(char []);
int main(){ LNP h = NULL; h = string_to_list("AB"); return 0;}
/* implementation of string_to_list() */
12240-222 CPT: Lists/15
LNP string_to_list(char s[]){ LNP head = NULL, tail; int i; if (s[0] != '\0') { head = malloc(sizeof(LISTNODE)); head->data = s[0]; tail = head; for (i=1; s[i] != '\0'; i++){ tail->nextptr =
malloc(sizeof(LISTNODE)); tail = tail->nextptr; tail->data = s[i]; } tail->nextptr = NULL; /* list end */ } return head;}
13240-222 CPT: Lists/15
string_to_list("AB")string_to_list("AB")
head = malloc(sizeof(LISTNODE));head->data = s[0];tail = head;
head
‘A’tail
‘?’
14240-222 CPT: Lists/15
tail->nextptr = malloc(sizeof(LISTNODE));
head
‘A’tail
‘?’‘?’
15240-222 CPT: Lists/15
tail = tail->nextptr;tail->data = s[i]; /* i = 1 here */
head
‘A’
tail
‘?’‘B’
16240-222 CPT: Lists/15
s[2] = '\0'/* so end of list is assigned NULL */
head
‘A’
tail
NULL‘B’
17240-222 CPT: Lists/15
5. List Functions5. List Functions
5.1. Empty Lists
5.2. Return the First Element of a List
5.3. Produce the Tail of a List
5.4. Put an Element on the Front of a List
5.5. Insertion
continued
18240-222 CPT: Lists/15
5.6. Deletion
5.7. List Membership
5.8. Print a List
5.9. List Length
5.10. Concatenate Two Lists
19240-222 CPT: Lists/15
5.1. Empty Lists5.1. Empty Lists
Make an empty list:
LNP h1;h1 = NULL;
Test for emptiness:
int isempty(LNP sptr){ return (sptr == NULL);}
20240-222 CPT: Lists/15
5.2. Return the First Element of a List5.2. Return the First Element of a List
char first(LNP cptr){ if (isempty(cptr)) return '\0' else return cptr->data;}
21240-222 CPT: Lists/15
UseUse
LNP head;char c;
head = string_to_list("new");c = first(head);
/* c is 'n'; head is not altered */
22240-222 CPT: Lists/15
5.3. Produce the tail of a list5.3. Produce the tail of a list
void tail(LNP *cptr){ LNP temp; if (isempty(*cptr)) printf("The list is empty.\n\n"); else { temp = *cptr; *cptr = (*cptr)->nextptr; free(temp); }}
cptr is the address of a pointer, so that the pointer can be modified using "call by reference".
23240-222 CPT: Lists/15
UseUse
LNP head;
head = string_to_list("new"); :tail(&head);
/* head is now the list version of “ew” */
24240-222 CPT: Lists/15
5.4. Put an Element on the List Front5.4. Put an Element on the List Front
LNP cons(char c, LNP cptr){ LNP temp; temp = malloc(sizeof(LISTNODE)); temp->data = c; temp->nextptr = cptr; return temp;}
25240-222 CPT: Lists/15
UseUse
LNP h1, h2;h1 = string_to_list("ew");h2 = cons('n', h1);
Before the cons() call:
h1‘e’ ‘w’ NULL
26240-222 CPT: Lists/15
h2‘n’ ‘e’ ‘w’ NULL
After:
h1
27240-222 CPT: Lists/15
5.5. Insertion5.5. Insertion
head‘n’ ‘w’
Before:
previousptr currentptr
NULL
newptr
‘o’ NULL
28240-222 CPT: Lists/15
head‘n’ ‘o’ ‘w’ NULL
After:
29240-222 CPT: Lists/15
Code Fig. 12.3Code Fig. 12.3
void insert(LNP *sptr, char value){ LNP newptr, previousptr, currentptr;
newptr = malloc(sizeof(LISTNODE)); if (newptr) { newptr->data = value; newptr->nextptr = NULL;
previousptr = NULL; currentptr = *sptr;
continued
30240-222 CPT: Lists/15
while ((currentptr != NULL) && (value > currentptr->data)) {
previousptr = currentptr; currentptr = currentptr->nextptr; } if (previousptr == NULL) { newptr->nextptr = *sptr; *sptr = newptr; } else { previousptr->nextptr = newptr; newptr->nextptr = currentptr; } } else printf("No memory available.\n");}
31240-222 CPT: Lists/15
NoteNote
The use of a pointer address (sptr) as an argument to insert() is to allow the head pointer to the list to be altered if the character is inserted as the first node.
32240-222 CPT: Lists/15
UseUse
LNP h1;h1 = string_to_list("nw");insert(&hl, 'o');
Dangers:
LNP h1, h2;h1 = string_to_list("nw");h2 = h1;insert(&hl, 'o');
33240-222 CPT: Lists/15
5.6. Deletion5.6. Deletion
LNP head;head = string_to_list("new");c = delete(&head, 'e');
head‘n’
previousptr currentptr
‘e’ ‘w’ NULL
34240-222 CPT: Lists/15
head‘n’
previousptr currentptr
‘e’ ‘w’ NULL
tempptr
35240-222 CPT: Lists/15
Code Fig. 12.3Code Fig. 12.3
char delete(LNP *sptr, char value){ LNP previousptr, currentptr, tempptr;
if (value == (*sptr)->data) { tempptr = *sptr; *sptr = (*sptr)->nextptr; free(tempptr); return value; } else { previousptr = *sptr; currentptr = (*sptr)->nextptr;
continued
36240-222 CPT: Lists/15
while ((currentptr != NULL) && (currentptr->data != value)) {
previousptr = currentptr; currentptr = currentptr->nextptr; }
if (currentptr) { tempptr = currentptr; previousptr->nextptr =
currentptr->nextptr; free(tempptr); return value; } } return '\0';}
37240-222 CPT: Lists/15
Some CommentsSome Comments
The use of a pointer address (sptr) as an argument to delete() is to allow the head pointer to the list to be altered if the first character in the list is being deleted.
38240-222 CPT: Lists/15
delete() can stop when:– 1. It has found the character.– 2. It has reached the end of the list (the
character isn't there).– 3. It has reached a character lexically bigger
than the one being sought. Not used in this code.
39240-222 CPT: Lists/15
DangersDangersLNP h1, h2;char c;h1 = string_to_list("all");h2 = h1;c = delete(&h1, 'l');
• h2 would be pointing at nothing if the first
node of h1 was deleted
h1‘a’ ‘l’ NULL
h2
40240-222 CPT: Lists/15
5.7. List Membership5.7. List Membership
int member(char c, LNP cptr){ if (isempty(cptr)) return 0; else { if (c == first(cptr)) return 1; else return member(c, cptr->nextptr); }}
41240-222 CPT: Lists/15
5.8. Print a List (iteratively) Fig. 12.35.8. Print a List (iteratively) Fig. 12.3
void printList(LNP cptr){ if (!cptr) printf("List is empty.\n\n"); else { printf("The list is:\n"); while (cptr) { printf("%c --> ", cptr->data); cptr = cptr->nextptr; } printf("NULL\n\n"); }}
42240-222 CPT: Lists/15
UseUse
LNP head;head = string_to_list("old");printList(head);
The list is:o --> l --> d --> NULL
43240-222 CPT: Lists/15
Print a List (recursively)Print a List (recursively)
void printList(LNP cptr){ if (isempty(cptr)) printf("NULL"); else { printf("%c --> ", first(cptr)); printList(cptr->nextptr); }}
44240-222 CPT: Lists/15
5.9. List Length5.9. List Length
int length(LNP cptr){ if (isempty(cptr)) return 0; else return (1 + length(cptr->nextptr));}
45240-222 CPT: Lists/15
5.10. Concatenate Two Lists5.10. Concatenate Two Lists
void concat(LNP a, LNP b){ if (a->nextptr == NULL) a->nextptr = b; else concat(a->nextptr, b);}
46240-222 CPT: Lists/15
UseUse
LNP h1, h2;
h1 = string_to_list("new");h2 = string_to_list("ton");
concat(h1, h2); /* h1 altered */print_list(h1);
The list is:n --> e --> w --> t --> o --> n --> NULL
47240-222 CPT: Lists/15
DangersDangersLNP h1, h2;
h1 = string_to_list("ab");h2 = string_to_list("cd");
concat(h1, h2); /* h1 is list "abcd" */
h2->data = 'o';
h1‘a’ ‘o’ ‘d’ NULL‘b’
h2
Top Related