Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Dynamic Data Structures n Linked List n CS215 © Peter Lo 2004 1 Dynamic data structures u Data structures that grow and shrink during execution Linked lists u Allow insertions and removals anywhere CS215 © Peter Lo 2004 2 The linked list - a common use of structs which contain themselves Self-Referential Structures n n n Imagine we are reading lines from a file but don't know how many lines will be read. We need a structure which can extend itself. u u u head_of_list information information information nextptr nextptr nextptr= NULL n Structure that contains a pointer to a structure of the same type Can be linked together to form useful data structures such as lists, queues, stacks and trees Terminated with a NULL pointer (0) Diagram of two self-referential structure objects linked together 15 This is known as a linked list. By passing the value of the head of the list to a function we can pass ALL the information. CS215 © Peter Lo 2004 Self-referential structures Data member and pointer 3 CS215 © Peter Lo 2004 10 NULL pointer (points to nothing) 4 1 Self-Referential Classes Linked list pros & cons n n n Example struct node { int data; struct node *nextPtr; } nextPtr u Points to an object of type node u Referred to as a link t Ties one node to another node CS215 © Peter Lo 2004 n 5 Dynamic Memory Allocation n n Deallocates memory allocated by malloc u Takes a pointer as an argument free ( newPtr ); u u We can make the list as big as we like Con: u Complicated for a beginner to program (don't underestimate this) u Hard to find nth element u Slightly larger since we store pointer and information CS215 © Peter Lo 2004 n malloc u u Takes number of bytes to allocate t Use sizeof to determine the size of an object Returns pointer of type void * A void * pointer may be assigned to any pointer If no memory available, returns NULL Example newPtr = malloc( sizeof( struct node ) ); t t u CS215 © Peter Lo 2004 6 Dynamic Memory Allocation Dynamic memory allocation u Obtain and release memory during execution free u Pro: u Can easily add items to the head or middle of the list (tough with array) - good for ordered lists 7 CS215 © Peter Lo 2004 8 2 Dynamic Linked Lists n Types of Dynamic Linked Lists n Dynamic Linked list u u Linear collection of self- referential class objects, called nodes Connected by pointer links u Accessed via a pointer to the first node of the list u Subsequent nodes are accessed via the link-pointer member of the current node u Singly linked list u n Begins with a pointer to the first node Terminates with a null pointer u Only traversed in one direction Circular, singly linked u Pointer in the last node points back to the first node Link pointer in the last node is set to null to mark the list’s end Use a dynamic linked list instead of a static array when u n u u You have an unpredictable number of data elements Your list needs to be sorted quickly CS215 © Peter Lo 2004 9 Types of Dynamic Linked Lists n u Two “ start pointers” – first element and last element Each node has a forward pointer and a backward pointer n u Allows traversals both forwards and backwards 10 Linked List Operation head of list Doubly Linked List u CS215 © Peter Lo 2004 NULL Adding an item to the middle of the list head of list Circular, Doubly Linked List u Forward pointer of the last node points to the first node and backward pointer of the first node points to the last node move this link NULL new item points at next item Deleting an item from the middle of the list move this link head of list CS215 © Peter Lo 2004 11 CS215 © Peter Lo 2004 NULL delete this node 12 3 Examples n Forming a Linked List In these examples, the following structure will be used extensively: struct Node { int Value; struct Node *Next_Ptr; n Forward Growing (Adding to the End): u Use one pointer to refer to the "head" of the list. u Use a second pointer to refer to the "tail" of the list. u Add every new structure to Tail->Next_Ptr. n Reverse Growing (Adding to the Beginning): u Use one pointer to refer to the "head" of the list. u Use a temporary pointer to refer to a new structure. }; n Example linked list: u u CS215 © Peter Lo 2004 13 Set Temp_Ptr->Next_Ptr = Head_Ptr Set Head = Temp_Ptr CS215 © Peter Lo 2004 Forward Growing Forward Growing n n The first thing we must do in either case is allocate the Head. u if (Head_Ptr == NULL) { t Head_Ptr = malloc (sizeof (struct Node)); t assert(Head_Ptr != NULL); t Head_Ptr->Next _Ptr = NULL; u} CS215 © Peter Lo 2004 15 14 In the forward growing case, we then set the Tail to the Head. u Tail_Ptr = Head_Ptr; CS215 © Peter Lo 2004 16 4 Forward Growing Forward Growing n n n n Tail->Next _Ptr = malloc( sizeof (struct Node)); assert(Tail->Next _Ptr != NULL); Tail->Next _Ptr->Next _Ptr = NULL; CS215 © Peter Lo 2004 17 Tail = Tail->Next _Ptr; CS215 © Peter Lo 2004 Reverse Growing Reverse Growing n n In the reverse growing case, we then set the Temp pointer to NULL first. n n CS215 © Peter Lo 2004 19 18 Temp _Ptr = malloc (sizeof (struct Node ) ); assert (Temp _Ptr != NULL); Temp _Ptr->Next _Ptr = NULL; CS215 © Peter Lo 2004 20 5 Reverse Growing Reverse Growing n n n Temp _Ptr->Next _Ptr = Head_Ptr; Head_Ptr = Temp _Ptr; CS215 © Peter Lo 2004 n 21 Example 9A n n n n CS215 © Peter Lo 2004 n n n n n n /* 9A: Operating and maintaining a dynamic linked list */ #include <stdio.h> #include <stdlib.h> #include <conio.h> n n n struct listNode { /* self-referential structure */ char data; struct listNode *nextPtr; }; instructions(); /* display the menu */ printf( "? " ); scanf( "%d", &choice ); n while ( choice != 3 ) { n typedef struct listNode ListNode ; typedef ListNode *ListNodePtr; n n n n n n void insertnode ( ListNodePtr *, char ); char deletenode( ListNodePtr *, char ); int isEmpty ( ListNodePtr ); void printList ( ListNodePtr ); void instructions( void ); CS215 © Peter Lo 2004 n n n n 23 int main() { ListNodePtr startPtr = NULL; int choice; char item; n n n n 22 Example 9A (cont’) n n Temp _Ptr->Next _Ptr = Head_Ptr; Head_Ptr = Temp _Ptr; switch ( choice ) { case 1: printf( "Enter a character: " ); scanf( "\n%c", &item ); insertnode(&startPtr, item ); printList( startPtr ); break; CS215 © Peter Lo 2004 24 6 Example 9A (cont’) case 2: if ( !isEmpty( startPtr ) ) { printf( "Enter character to be deleted: " ); scanf( "\n%c", &item ); if ( deletenode ( &startPtr, item ) ) { printf( "%c deleted. \n", item ); printList ( startPtr ); } else printf( "%c not found.\ n\n", item ); } else printf( "List is empty.\ n\n" ); break; default: printf( "Invalid choice. \n\n" ); instructions(); break; } printf( "? " ); scanf ( "%d", &choice ); n n n n n n n n n n n n n n n n n n n n n n Example 9A (cont’) n n n n n n n n n n n n 25 Example 9A (cont’) CS215 © Peter Lo 2004 n n n n n n n n n n n n n n n n n n n n n /* Insert a new value into the list in sorted order */ void insertnode ( ListNodePtr *sPtr, char value ) { ListNodePtr newPtr , previousPtr , currentPtr; (void *) newPtr = malloc ( sizeof( ListNode ) ); /* malloc returns pointer to void */ if ( newPtr != NULL ) { /* is space available */ newPtr->data = value; newPtr->nextPtr = NULL; previousPtr = NULL; currentPtr = *sPtr; while ( currentPtr != NULL && value >currentPtr->data ) { previousPtr = currentPtr; /* walk to ... */ currentPtr = currentPtr->nextPtr; /* ... next node */ } if ( previousPtr == NULL ) { newPtr->nextPtr = *sPtr; *sPtr = newPtr ; } else { previousPtr->nextPtr = newPtr; newPtr->nextPtr = currentPtr; } } else printf( "%c not inserted. No memory available.\ n", value ); } CS215 © Peter Lo 2004 26 Example 9A (cont’) n n /* Print the instructions */ void instructions( void ) { printf( "Enter your choice:\n" " 1 to insert an element into the list.\n" " 2 to delete an element from the list.\n" " 3 to end.\n" ); } } CS215 © Peter Lo 2004 n printf( "End of run.\n" ); getch(); return 0; } n n n n n n n n n n n n n n n n n n n n n 27 /* Delete a list element */ char deletenode( ListNodePtr *sPtr, char value ) { ListNodePtr previousPtr , currentPtr, tempPtr; if ( value == ( *sPtr )->data ) { tempPtr = *sPtr; *sPtr = (*sPtr )->nextPtr; /* de-thread the node */ free( tempPtr ); /* free the de-threaded node */ return value; } else { previousPtr = *sPtr; currentPtr = (*sPtr )->nextPtr; while ( currentPtr != NULL && currentPtr->data != value ) { previousPtr = currentPtr; /* walk to ... */ currentPtr = currentPtr->nextPtr; /* ... next node */ } if ( currentPtr != NULL ) { tempPtr = currentPtr ; previousPtr->nextPtr = currentPtr->nextPtr; free( tempPtr ); return value; } } return '\ 0'; } CS215 © Peter Lo 2004 28 7 Example 9A (cont’) n n n n n n n n n n n n /* Return 1 if the list is empty, 0 otherwise */ int isEmpty ( ListNodePtr sPtr ) { return sPtr == NULL; } /* Print the list */ void printList ( ListNodePtr currentPtr ) { if ( currentPtr == NULL ) printf( "List is empty.\ n\n" ); else { printf( "The list is:\n" ); while ( currentPtr != NULL ) { printf( "%c --> ", currentPtr->data ); currentPtr = currentPtr->nextPtr; } printf( "NULL\n\n" ); n n n n n } n n Output Result } CS215 © Peter Lo 2004 29 CS215 © Peter Lo 2004 30 8