Download presentation
Presentation is loading. Please wait.
1
Linked Lists Chapter 10
2
Linked Lists What? Why? How?
A Structured data object (struct) which relies on pointers between elements Why? Alternative to Sorting Ordering on Multiple keys Relatively easy maintenance Dynamic Memory Allocation How? Addition of pointer field: struct namelist { char name[30]; struct namelist * next; }; int main() { struct namelist names[4], *head;
3
Consider the following section of C code:
struct custs { char ssn[10]; char name[14]; float balance; struct custs *next; }; int main () { struct custs customer[5] = {{“ ”,”Chaucer, G.”,342.45,NULL}, {“ ”,”Milton, J.”,0.00,}, {“ ”,”Browning, R.”,-51.25,}, {“ ”,”Eliot, T.S.”, ,}, {“ ”,”Shelley, P.”,32.44.}}, * first; Where the data type struct custs requires: = 32 Bytes of contiguous storage The variable array customer requires: 32 * 5 = 160 Bytes of contiguous storage & pointer first requires 4 Bytes of contiguous storage
4
And * first might be found at
IF the base address of the array customer (== customer[0]) was 9200, then the relevant portion of RAM would appear as: 9200 ‘1’ 9201 ‘2’ 9202 ‘3’ 9203 ‘4’ 9204 ‘5’ 9205 ‘6’ 9206 ‘7’ 9207 ‘8’ 9208 ‘9’ 9209 ‘\0’ 9210 ‘C’ 9211 ‘h’ 9212 ‘a’ 9213 ‘u’ 9214 ‘c’ 9215 ‘e’ 9216 ‘r’ 9217 ‘,’ 9218 9219 ‘G’ 9220 ‘.’ 9221 ‘\0’ 9222 --- 9223 --- 9224 9225 9226 342.45 9227 9228 9230 9229 9231 Continuing through 9328 ‘5’ 9329 ‘6’ 9330 ‘7’ 9331 ‘8’ 9332 ‘9’ 9333 ‘0’ 9334 ‘1’ 9335 ‘2’ 9336 ‘3’ 9337 ‘\0’ 9338 ‘S’ 9339 ‘h’ 9340 ‘e’ 9341 ‘l’ 9342 ‘l’ 9343 ‘e’ 9344 ‘y’ 9345 ‘,’ 9346 ‘ ’ 9347 ‘P’ 9348 ‘.’ 9349 ‘\0’ 9350 --- 9351 --- 9352 9354 32.44 9353 9355 9356 9358 9357 9359 9368 9370 9369 9371 And * first might be found at
5
How is any of this helpful ???
Notice that the array/table (customer) would appear as: Offset\Field: ssn name balance * next “ ” “Chaucer, G.” 342.45 “ ” “Milton, J.” 0.00 --- 1 “ ” “Browning R.” -51.25 --- 2 “ ” “Eliot, T.S.” --- 3 “ ” “Shelley, P.” 32.44 --- 4 Notice that the list is NOT in any order (other than by ssn) What if we wished to sort by, say, name. Could we do it without sorting ??
6
We Need to set up the linkages. First, identify the initial name:
“ ” “Chaucer, G.” 342.45 “ ” “Milton, J.” 0.00 --- “ ” “Browning R.” -51.25 “ ” “Eliot, T.S.” “ ” “Shelley, P.” 32.44 9368 9369 9371 9370 9264 Then store the Base address of the record in location first
7
Next, identify the next name on the list:
“ ” “Chaucer, G.” 342.45 “ ” “Milton, J.” 0.00 --- “ ” “Browning R.” -51.25 “ ” “Eliot, T.S.” “ ” “Shelley, P.” 32.44 9200 Then have the previous record point to it by storing the new record’s address in field next
8
Continue until each record points to the next record:
9200 “ ” “Chaucer, G.” 342.45 “ ” “Milton, J.” 0.00 --- “ ” “Browning R.” -51.25 “ ” “Eliot, T.S.” “ ” “Shelley, P.” 32.44 9296 9328 9232 NULL AND set the last record’s next field point to NULL
9
How do we set up the list? Add first record (first = customer, customer[0].next = NULL) For the remaining records: 1. Starting with 1st record, compare the name with every other name 2. If the new name is greater than the list name: A. If end of list: a. have old record point to new b. set new record pointer to NULL Else if the new name is smaller: A. If first record: a set new record next pointer to old record b set first pointer to new record B. Otherwise: a have previous record point to new record b have new record point to record being compared 3. Get next record (if any) and go to step 1.
10
Following the above procedure:
Add first record (first = customer], customer[0].next = NULL) 9368 9369 9371 9370 9200 “ ” “Chaucer, G.” 342.45 NULL Yes Compare the name with the next name on the list: “ ” “Milton, J.” 0.00 --- The record should be placed after the first record: • Is the first record the last record?
11
Set the new record’s next field point to NULL
Have the old record point to the new record by setting in the address of the new record into the old record’s next field: “ ” “Chaucer, G.” 342.45 9232 Set the new record’s next field point to NULL “ ” “Milton, J.” 0.00 NULL Now repeat the procedure, starting with the first record:
12
Yes Compare the name with the new name:
9368 9369 9371 9370 9200 “ ” “Chaucer, G.” 342.45 9232 Compare the name with the new name: “ ” “Browning R.” -51.25 --- The new record should be placed Before the record: • Is the record the First record? Yes
13
And have the new first record point to the old one:
Store the address of the new first record at address first: 9368 9369 9371 9370 9264 And have the new first record point to the old one: “ ” “Chaucer, G.” 342.45 9232 “ ” “Browning R.” -51.25 9200 Repeat the previous process starting with the new first record: “ ” “Eliot, T.S.” --- The new record FOLLOWS the first record: • Is the first record the LAST record in the list? No
14
Get the next item on the list
Continue by comparing with the next item on the existing list: “ ” “Chaucer, G.” 342.45 9232 “ ” “Browning R.” -51.25 9200 “ ” “Eliot, T.S.” --- The new record FOLLOWS the existing record: • Is the existing record the LAST record in the list? No Get the next item on the list “ ” “Milton, J.” 0.00 NULL
15
No Compare the two items:
“ ” “Milton, J.” 0.00 NULL “ ” “Eliot, T.S.” --- The new record GOES BEFORE the existing record: • Is the existing record the FIRST record in the list? 9368 9369 9371 9370 9264 No Insert the new item in the list by: • Having the previous record point to the new record • Having the new record point to the existing record
16
Offset\Field: ssn name balance * next 1 2 3 4
So far, our database would appear as: 9368 9369 9371 9370 9264 first Offset\Field: ssn name balance * next “ ” “Chaucer, G.” 342.45 9296 “ ” “Milton, J.” 0.00 NULL 1 “ ” “Browning R.” -51.25 9200 2 “ ” “Eliot, T.S.” 9232 3 “ ” “Shelley, P.” 32.44 --- 4 With only one record NOT set into the list:
17
Get the next item on the list
Add The final record by repeating all of the steps: 9368 9369 9371 9370 9264 first “ ” “Browning R.” -51.25 9200 Compare with “ ” “Shelley, P.” 32.44 --- The new record FOLLOWS the existing record: • Is the existing record the LAST record in the list? Get the next item on the list No
18
Get the next item on the list
Continue: “ ” “Chaucer, G.” 342.45 9232 “ ” “Browning R.” -51.25 9200 “ ” “Shelley, P.” 32.44 --- The new record FOLLOWS the existing record: • Is the existing record the LAST record in the list? No Get the next item on the list “ ” “Eliot, T.S.” 9232
19
Get the next item on the list
Continue Comparisons: “ ” “Eliot, T.S.” 9232 “ ” “Shelley, P.” 32.44 --- The new record FOLLOWS the existing record: • Is the existing record the LAST record in the list? Get the next item on the list No “ ” “Milton, J.” 0.00 NULL
20
Set the item into the list
Continue Comparisons: “ ” “Milton, J.” 0.00 NULL “ ” “Shelley, P.” 32.44 --- The new record FOLLOWS the existing record: • Is the existing record the LAST record in the list? Set the item into the list YES The old last item points to the new item: “ ” “Milton, J.” 0.00 9328 And the new item points to NULL: “ ” “Shelley, P.” 32.44 NULL
21
#include <string.h> // for strcmp
struct custs { char ssn[10], name[30]; // stucture template float balance; struct custs *next; }; int main () { struct custs customer[5] = // initialize array {{“ ”,”Chaucer, G.”,342.45,NULL}, {“ ”,”Milton, J.”,0.00,}, {“ ”,”Browning, R.”,-51.25,}, {“ ”,”Eliot, T.S.”, ,}, {“ ”,”Shelley, P.”,32.44,}}; struct custs *first = customer, *present, *previous; int recno; for (recno = 1; recno < 5; recno++) { present = first; // start with 1st record on list // Is the new record larger AND are there additional records? while ((strcmp(customer[recno].name,present->name)>0) && (present->next != NULL)) { previous = present; // old record now previous present = present->next; } // Then get the next record // Why are we out of the loop? Was the new < old record? if (strcmp(customer[recno].name,present->name) < 0) { if (present == first) first = &customer[recno]; // reset first pointer else previous->next = &customer[recno]; // prev -> new customer[recno].next = present; } // new -> old else // new > old { if (present->next == NULL) customer[recno].next = NULL; // new -> NULL else customer[recno].next = present->next; // new-> old present->next = &customer[recno]; } // old -> new } // the list is linked }
22
How would we search for an item on the list?
We need to perform a sequential search. Suppose we were looking for: “Eliot, T.S.” (which is the 3rd element (alphabetically) and 4th element (physically) on the list). Starting at the top: 9368 9369 9371 9370 9264 first “ ” “Browning R.” -51.25 9200 Search Element? No: Get Next “ ” “Chaucer, G.” 342.45 9296 Search Element? No: Get Next “ ” “Eliot, T.S.” 9232 Search Element? YES: Stop
23
We Do NOT Have to search until the end IF the item is NOT on the list
The C Code Necessary ?? Building on the previous code, consider the following additional code: char temp[50]; // Temporary Storage printf(“Enter Name to search for: ); // Prompt User gets(temp); // Get Input present = first; // point to the 1st record while ((present != NULL) && (strcmp(temp,present->name) < 0)) present = present->next; // Get next record if ((present == NULL) || (strcmp(temp, present->name) >0)) printf(“\nThe Name is not on the list”); // Element not in list else // Element in list printf(“\nThe name %s is on the list”, present->name); Notice that there is one advantage to sequentially searching an ordered list: We Do NOT Have to search until the end IF the item is NOT on the list
24
There are other advantages to linked lists:
Additional Advantage 1: Ordering on multiple keys: • In addition to listing items by name, we could also list items by, for example, balance, WITHOUT physically sorting. • Consider the following change in our structure template and initial declarations: struct custs { char ssn[10]; char name[14]; float balance; struct custs *next_name, *next_balance; }; int main () { struct custs customer[5] = {{ …}}, *first_name = cutomer->name, *first_balance = customer->balance; } Our Database might appear as:
25
9264 *first_balance 9264 *first_name Order by name Order by balance
9368 9369 9371 9370 9264 *first_balance 9368 9369 9371 9370 9264 *first_name Order by name Order by balance ssn name balance *next_ name *next _balance “ ” “Chaucer, G.” 342.45 9308 “ ” “Milton, J.” 0.00 9344 “Browning R.” “ ” -51.25 9200 9236 “ ” “Eliot, T.S.” NULL “ ” Shelley, P.” 32.44
26
Why?? We can also have doubly-linked lists.
To allow us to search from either end of the list. Consider the structured object: struct custs { struct custs * previous; char ssn[10], name[14]; float balance; struct custs *next; }; Our database might appear as: “ ” “Chaucer, G.” 342.45 9308 9272 “ ” “Milton, J.” 0.00 9344 9308 “Browning R.” “ ” -51.25 9200 NULL “ ” “Eliot, T.S.” 9236 9200 “ ” Shelley, P.” 32.44 NULL 9236
27
The links would appear as:
“ ” “Chaucer, G.” 342.45 9308 9272 “ ” “Milton, J.” 0.00 9344 “Browning R.” “ ” -51.25 9200 NULL “ ” “Eliot, T.S.” 9236 “ ” Shelley, P.” 32.44
28
Are there additional Searching techniques on linked lists?
We could set up an array of pointers: struct custs { char ssn[10], name[14]; float balance; }; int main() { struct custs customer[5] = {{…}}, *order[5]; 9246 9200 9274 9228 9302 “ ” “Chaucer, G.” 342.45 “ ” “Milton, J.” 0.00 “Browning R.” “ ” -51.25 “ ” “Eliot, T.S.” “ ” Shelley, P.” 32.44
29
We could also set up leveled lists:
5000 5025 5050 5075 5100 5125 5150 5175 5200 5225 5250 5275 9th 2nd 12th 6th 10th 1st 8th 4th 7th 5th 11th 3rd 5125 1st 5175 4th 5150 8th 5050 12th
30
Comparison of linkage Types
Single Linked List: Advantage Disadvantage Ease of creation Sequential Search only Ease of update Search in One direction (only) 2-extra bytes Doubly Linked List: Search both directions 4-extra bytes/record Still easy create/update Still Sequential Search Array of Pointers: Binary Search More difficult to create Search both directions and update (longer lists) (Only) 2-extra bytes/rec NOTE: All of these linkages require that we know IN ADVANCE how many records there are
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.