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
Department of Computer and Information Science, School of Science, IUPUI CSCI 230 Data Structures Dale Roberts, Lecturer Computer Science, IUPUI E-mail: [email protected] Dale Roberts Data Structure Algorithms deals with the manipulation of data Data structure deals with the organization of data Algorithms + Data Structures = Programs Suppose we have a list of sorted data on which we have to perform the following operations: Search for an item delete a specified item insert (add) a specified item Example: suppose we begin with the following list: data: 345 358 490 501 513 555 561 701 724 797 location: 0 1 2 3 4 5 6 7 8 9 What is a list? A list is a data structure where data is represented linearly. A list can be implemented using arrays on a machine. Finite sequence of items from the same data type Stored contiguously in the memory Dale Roberts Example: suppose we begin with the following list: data: 345 358 490 501 513 555 561 701 724 797 location: 0 1 2 3 4 5 6 7 8 9 Now, delete item 358 from the above list Q: What is the algorithm to delete an item? Q: What is the cost of deleting an item? data: 345 358 490 501 513 555 561 701 724 797 location: 0 1 2 3 4 5 6 7 8 9 Q: When we delete 358, what happens to that location? Now, add item 498 onto the above list Q: Where would that item go? 498 data: 345 358 490 501 513 555 561 701 724 797 location: 0 1 2 3 4 5 6 7 8 9 Q: What is the cost of inserting an item? Conclusion: Using a list representation of data, what is the overall efficiency of searching, adding, and deleting items? Dale Roberts Linked Representation of Data In a linked representation, data is not stored in a contiguous manner. Instead, data is stored at random locations and the current data location provides the information regarding the location of the next data. 797 358 Adding item 498 on to the linked list Q: What is the cost of adding an item? Q: how about adding 300 and 800 onto the linked list 561 501 345 555 490 701 358 Deleting item 358 from the linked list Q: What is the cost of deleting an item? Q: What is the cost of searching for an item? 513 797 561 345 555 724 490 501 724 701 513 498 358 345 555 498 Dale Roberts 490 797 561 501 701 724 513 Deletion of an Element from a List Algorithm: 1. 2. 3. locate the element in the list (this involves searching) delete the element reorganize the list and index Example: data: location: 345 0 358 1 490 2 501 3 513 4 555 5 561 6 701 7 724 8 797 9 Delete 358 from the above list: 1. Locate 358: if we use ‘linear search’, we’ll compare 358 2. with each element of the list starting from the location 0. Delete 358: remove it from the list data: 345 location: 0 1. 1 490 2 501 3 513 4 555 5 561 6 701 7 724 8 Reorganize the list: move the remaining elements. data: 345 location: 0 490 1 501 2 513 3 555 4 Dale Roberts 561 5 701 6 724 7 797 8 797 9 Insertion of an Element in List Algorithm: locate the position where the element in to be inserted (position may be user-specified in case of an unsorted list or may be decided by search for a sorted list) 2. reorganize the list and create an ‘empty’ slot 3. insert the element 1. Example: (sorted list) data: 345 location: 0 358 1 490 2 501 3 513 4 555 5 561 6 701 7 724 8 797 9 Insert 505 onto the above list: Locate the appropriate position by performing a binary search. 505 should be stored in location 4. 2. Create an ‘empty’ slot 1. data: 345 location: 0 3. 358 1 490 2 501 3 358 1 490 2 501 3 4 513 5 555 6 561 7 701 8 724 9 797 10 505 4 513 5 555 6 561 7 701 8 724 9 797 10 Insert 505 data: 345 location: 0 Dale Roberts Introduction Dynamic data structures Data structures that grow and shrink during execution Linked lists Allow insertions and removals anywhere Stacks Allow insertions and removals only at top of stack Queues Allow insertions at the back and removals from the front Binary trees High-speed searching and sorting of data and efficient elimination of duplicate data items Dale Roberts Linked Lists Linked list Linear collection of self-referential class objects, called nodes Connected by pointer links Accessed via a pointer to the first node of the list Subsequent nodes are accessed via the link-pointer member of the current node Link pointer in the last node is set to null to mark the list’s end Use a linked list instead of an array when You have an unpredictable number of data elements Your list needs to be sorted quickly Dale Roberts Linked List How do we represent a linked list in the memory we use pointers to point to the next data item. Each location has two fields: Data Field and Pointer (Link) Field. Linked List Implementation START Node Element Data Field struct node { int data; struct node *link; }; struct node my_node; Pointer (Link) Field Null Pointer 1 300 5 2 500 0 3 100 4 4 200 1 5 400 2 3 Example: Dale Roberts NULL Self-Referential Structures Self-referential structures 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 3 100 Data member and pointer struct node { int data; struct node *nextPtr; } nextPtr Points to an object of type node Referred to as a link Ties one node to another node Dale Roberts 2 … 500 NULL pointer (points to nothing) Linked Lists Types of linked lists: Singly linked list Begins with a pointer to the first node Terminates with a null pointer Only traversed in one direction Circular, singly linked Pointer in the last node points back to the first node Doubly linked list Two “start pointers” – first element and last element Each node has a forward pointer and a backward pointer Allows traversals both forwards and backwards Circular, doubly linked list Forward pointer of the last node points to the first node and backward pointer of the first node points to the last node Dale Roberts Linked List Manipulation Algorithms List Traversal Let START be a pointer to a linked list in memory. Write an algorithm to print the contents of each node of the list Algorithm set PTR = START repeat step 3 and 4 while PTR NULL print PTR->DATA set PTR = PTR -> LINK stop 1. 2. 3. 4. 5. 10 10 START 20 1000 Data 20 2000 30 30 3000 40 40 4000 50 Link PTR = LINK[PTR] PTR Dale Roberts ptr=NULL; /* basic link list application */ /* forward order */ #define NULL 0 /* List Traversal */ printf(“sequential print of the list\n”); ptr=head; while (ptr->next != NULL) { printf(“The value is: %d\n”, ptr->data); ptr=ptr->next; } struct list { int data; struct list *next; } typedef struct list node; typedef node *link; } main() { link ptr, head; int num, i; head = (link)malloc(sizeof(node)); ptr=head; printf(“input 5 different data\n”); /* construct a linked list */ for (i=0; i<5; i++) { scanf(“%d”,&num); ptr->data = num; ptr->next=(link)malloc(sizeof(node)); ptr=ptr->next; } Dale Roberts input 5 different data 5 4 3 2 9 sequential print of the list The value is: 5 The value is: 4 The value is: 3 The value is: 2 The value is: 9 ptr=ptr->next; /* basic link list application */ /* reverse order */ #define NULL 0 /* List Traversal */ printf(“reverse print of the list\n”); while (ptr->next != NULL) { printf(“The value is: %d\n”, ptr->data); ptr=ptr->next; } struct list { int data; struct list *next; } typedef struct list node; typedef node *link; } main() { link ptr, tail, head; int num, i; tail = (link)malloc(sizeof(node)); tail->next = NULL; ptr=tail; printf(“input 5 different data\n”); /* construct a linked list */ for (i=0; i<5; i++) { scanf(“%d”,&num); ptr->data = num; head =(link)malloc(sizeof(node)); head->next = ptr; ptr = head; } Dale Roberts input 5 different data 5 4 3 2 9 sequential print of the list The value is: 9 The value is: 2 The value is: 3 The value is: 4 The value is: 5 Search for a ITEM Let START be a pointer to a linked list in memory. Write an algorithm that finds the location LOC of the node where ITEM first appears in the list, or sets LOC=NULL if search is unsuccessful. Algorithm 1. 2. 3. 4. 5. 6. 7. 8. set PTR = START repeat step 3 while PTR NULL if ITEM == PTR -> DATA, then set LOC = PTR, and Exit else set PTR = PTR -> LINK set LOC = NULL /*search unsuccessful */ Stop 1000 2000 3000 4000 START PTR Dale Roberts PTR = LINK[PTR] Insertion into a Listed List Let START be a pointer to a linked list in memory with successive nodes A and B. Write an algorithm to insert node N between nodes A and B. Algorithm 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. Set PTR = START Repeat step 3 while PTR NULL If PTR == A, then Set N->LINK = PTR -> LINK (or = B) Set PTR->LINK = N START exit 1000 else Set PTR=PTR->LINK If PTR == NULL insertion unsuccessful START Stop 1000 2000 2000 Node A Node B 3000 4000 Node A Node B 3000 4000 3500 PTR Node N 3 cases: first node, last node, in-between node. (ex: if ITEM = 500? if ITEM = 6000?) Dale Roberts 5000 5000 Deletion from a Linked List Let START be a pointer to a linked list in memory that contains integer data. Write an algorithm to delete note which contains ITEM. Algorithm 1. 2. 3. 4. 5. 6. 7. 8. Set PTR=START and TEMP = START Repeat step 3 while PTR NULL If PTR->DATA == ITEM, then Set TEMP->LINK = PTR -> LINK, exit else TEMP = PTR PTR = PTR -> LINK Stop START 1000 2000 START 1000 2000 ….. Node A Node N Node B 3000 3500 4000 Node A Node N Node B 3000 3500 4000 5000 5000 3500 ITEM TEMP PTR 3 cases: first node, last node, in-between node. (ex: if ITEM = 1000? if ITEM = 5000?) Dale Roberts 1 2 /* Fig. 12.3: fig12_03.c Operating and maintaining a list */ 3 4 5 6 7 8 9 #include <stdio.h> #include <stdlib.h> 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 Define struct struct listNode { /* self-referential structure */ char data; struct listNode *nextPtr; }; Function prototypes typedef struct listNode ListNode; typedef ListNode *ListNodePtr; void insert( ListNodePtr *, char ); char delete( ListNodePtr *, char ); int isEmpty( ListNodePtr ); Abstract Data Type void printList( ListNodePtr ); void instructions( void ); int main() { ListNodePtr startPtr = NULL; Initialize variables int choice; char item; Dale Roberts 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 instructions(); /* display the menu */ printf( "? " ); scanf( "%d", &choice ); Input choice while ( choice != 3 ) { switch ( choice ) { switch case 1: printf( "Enter a character: " ); scanf( "\n%c", &item ); insert( &startPtr, item ); printList( startPtr ); break; case 2: if ( !isEmpty( startPtr ) ) { printf( "Enter character to be deleted: " ); scanf( "\n%c", &item ); if ( delete( &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; Dale Roberts statement 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 default: printf( "Invalid choice.\n\n" ); instructions(); break; } printf( "? " ); scanf( "%d", &choice ); } printf( "End of run.\n" ); return 0; } /* 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" ); } Dale Roberts 78 /* Insert a new value into the list in sorted order */ 79 void insert( ListNodePtr *sPtr, char value ) 80 { 81 ListNodePtr newPtr, previousPtr, currentPtr; 82 83 newPtr = malloc( sizeof( ListNode ) ); 84 85 if ( newPtr != NULL ) { /* is space available */ 86 newPtr->data = value; 87 newPtr->nextPtr = NULL; 88 89 previousPtr = NULL; 90 currentPtr = *sPtr; 91 92 while ( currentPtr != NULL && value > currentPtr->data ) { 93 previousPtr = currentPtr; /* walk to ... */ 94 currentPtr = currentPtr->nextPtr; /* ... next node */ 95 } 96 97 if ( previousPtr == NULL ) { 98 newPtr->nextPtr = *sPtr; 99 *sPtr = newPtr; 100 } 101 else { 102 previousPtr->nextPtr = newPtr; 103 newPtr->nextPtr = currentPtr; 104 } 105 } 106 else 107 printf( "%c not inserted. No memory available.\n", value ); 108 } 109 Dale Roberts 110 /* Delete a list element */ 111 char delete( ListNodePtr *sPtr, char value ) 112 { 113 ListNodePtr previousPtr, currentPtr, tempPtr; 114 115 if ( value == ( *sPtr )->data ) { 116 tempPtr = *sPtr; 117 *sPtr = ( *sPtr )->nextPtr; /* de-thread the node */ 118 free( tempPtr ); /* free the de-threaded node */ 121 { 119 elsereturn value; 122 previousPtr = *sPtr; 120 } 123 currentPtr = ( *sPtr )->nextPtr; 124 125 while ( currentPtr != NULL && currentPtr->data != value ) { 126 previousPtr = currentPtr; /* walk to ... */ 127 currentPtr = currentPtr->nextPtr; /* ... next node */ 128 } 129 130 if ( currentPtr != NULL ) { 131 tempPtr = currentPtr; 132 previousPtr->nextPtr = currentPtr->nextPtr; 133 free( tempPtr ); 134 return value; 135 } 136 } 137 138 return '\0'; 139 } 140 Dale Roberts 141 142 143 144 145 146 /* Return 1 if the list is empty, 0 otherwise */ int isEmpty( ListNodePtr sPtr ) { return sPtr == NULL; } 147 /* Print the list */ 148 void printList( ListNodePtr currentPtr ) 149 { 150 if ( currentPtr == NULL ) 151 printf( "List is empty.\n\n" ); 152 else { 153 printf( "The list is:\n" ); 154 155 while ( currentPtr != NULL ) { 156 printf( "%c --> ", currentPtr->data ); 157 currentPtr = currentPtr->nextPtr; 158 } 161 Enter your choice: 1 to insert an element into the list. 2 to delete an element from the list. 3 to end. ? 1 Enter a character: B The list is: B --> NULL ? 1 Enter a character: A The list is: A --> B --> NULL ? 1 Enter a character: C The list is: A --> B --> C --> NULL ? 2 Enter character to be deleted: D D not found. 159 160 Program Output: printf( "NULL\n\n" ); } ? 2 Enter character to be deleted: B B deleted. The list is: A --> C --> NULL 162 } Dale Roberts Trees Definitions Tree: A tree is a collection of nodes. If the A collection is not empty, it must consist of a unique root node, r, and zero or more nonempty subtrees T1, T2,…, Tk, with roots B G C D E F connected by a direct edge from r I M H J L N K For a tree of N nodes, there must be N-1 edges. Q P A node with no child is called a leaf node; nodes with the same parents are siblings. – Path: a path from node n1 to nk is a sequence of nodes n1, n2, …, nk such that ni is the parent of ni+1 (1 i k); The no. of edges in the path is call the length of the path; A length 0 path is a path from a node to itself. There is a unique path from root to any node ni; The length of this path is called the depth of ni; thus, the root is a depth 0 node. – The height of a node ni is the length of the longest path from ni to a leaf node, thus, the height of a leaf node is 0. – The height of a tree is the height of its root node. The depth of a tree is the depth of the deepest leaf node, which is the same as the height of the tree. Dale Roberts Tree Terminology (Review) A height of tree is 3 Height – deepest level, not including root. Leaf nodes – have no children Interior Notes – have at least one child Degree of a node – Number of children In a binary tree, interior nodes have degree 1 or 2. Dale Roberts B root C D child of A parent of G,H,I and J degree = 4 H I subtrees E F K G L leaf nodes M J Binary Trees •Binary trees – Definition: A binary tree is a tree in which no nodes can have more than two children. – The root node is the first node in a tree. – Each link in the root node refers to a child – A node with no children is called a leaf node – Total number of nodes in a full binary tree of height k is 2k-1 – Implementation Struct BinaryNode { data_type element; BinaryNode left; BinaryNode right; } B A D C Dale Roberts Binary Tree Binary tree has interior nodes restricted to degree 1 or 2. root left child Dale Roberts right child Array implementation of binary tree We can embed the nodes of a binary tree into a one-dimensional array by defining a relationship between the position of each parent node and the position of its children. 1. left_child of node i is 2*i 2. right_child of node i is 2*i+1 3. parent of node i is i/2 (integer division) How much space is required for the array to represent a tree of depth d? d+1 2 – 1 (must assume full tree) Dale Roberts Dynamic Implementation of Binary Tree A dynamic implementation of a binary tree uses space proportional to the actual number of nodes used. Not the size of the full tree. mar apr may null sep jul Struct BinaryNode { data_type element; BinaryNode left; BinaryNode right; } data null null feb oct null dec right-child pointer null Dale Roberts jun null aug left-child pointer null null null jan nov null null null null Binary Search Tree (BST) Binary search tree (BST) Values in left subtree less than parent Values in right subtree greater than parent Facilitates duplicate elimination Fast searches - for a balanced tree, maximum of log2(n) comparisons Construct a BST from the values: 47, 25, 77, 11, 43, 65, 93, 7, 17, 31, 44, 68 47 25 11 7 17 77 43 31 44 Dale Roberts 65 68 93 Binary Search Tree (BST) Question: Construct an Binary Search Tree (BST) for the data 555 501 701 555 555 555 501 501 358 513 561 555 701 501 358 797 358 501 490 555 555 701 345 501 701 358 513 724 555 701 513 561 501 358 701 513 561 797 555 501 358 345 Array Implementation: 555 501 701 358 513 561 797 345 490 724 Dale Roberts 555 701 501 513 561 797 490 345 358 701 513 561 797 490 724 Binary Trees Tree traversals: In-order traversal – prints the node values in ascending order (LNR) 1. Traverse the left sub-tree with an in-order traversal 2. Process the value in the node (i.e., print the node value) 3. Traverse the right sub-tree with an in-order traversal Pre-order traversal (NLR) 1. Process the value in the node 2. Traverse the left sub-tree with a preorder traversal 3. Traverse the right sub-tree with a preorder traversal Post-order traversal (LRN) 1. Traverse the left sub-tree with a post-order traversal 2. Traverse the right sub-tree with a post-order traversal 3. Process the value in the node Dale Roberts Tree Traversal is “Naturally” recursive Naturally recursive because: 1. Subgraphs are similar in character to the original graph. 2. Subgraphs are smaller. 3. Guaranteed to eventually hit a leaf (acyclic is assumed) Obeys fundamental rules of recursion 1.) Base cases 2.) Makes progress through recursion 3.) Assume recursive calls work (abstraction) Always specify the base case; otherwise, infinite recursive will occur and cause “stack-overflow” error. Dale Roberts Sample recursive programs In-order: (LNR) void inorder(tree_pointer ptr) { if (ptr) { inorder(ptr->left_child); printf(“%d”, ptr->data); inorder(ptr->right_child); } } Pre-order: (NLR) void preorder(tree_pointer ptr) { if (ptr) { printf(“%d”, ptr->data); preorder(ptr->left_child); preorder(ptr->right_child); } } Post-order: (LRN) void postorder(tree_pointer ptr) { if (ptr) { postorder(ptr->left_child); postorder(ptr->right_child); printf(“%d”, ptr->data); } } Dale Roberts Example: Expression Tree Example: An Expression Tree 1. Perform in-order traversal (LNR) + A – B + C * E / F 2. Perform post-order traversal (LRN) A B – C E F / * + 3. Perform pre-order traversal (NLR) + - A B * C / E F Dale Roberts - A * B / C E F Tree Traversal Example Try your hand at traversing this tree: mar apr may In-order: (LNR) null Apr, Aug, Dec, Feb, Jan, Jun, Jan, Mar, May, Nov, Oct, Sep null sep jul null null Pre-order: (NLR) feb Mar, Apr, Jul, Feb, Dec, Aug, Jun, Jan, May, Sep, Oct, Nov Post-order: (LRN) Aug, Dec, Jan, Jun, Feb, Jul, Apr, Nov, Oct, Sep, May, Mar oct null dec null aug null Dale Roberts jun null null jan nov null null null null Stacks Stack model A stack is a list with the restriction that insertion & deletion can be performed only at the end (or top) of the list. Only the top node is accessible: New nodes can be added and removed only at the top Similar to a pile of dishes S4 top Last-in, first-out (LIFO) S3 Bottom of stack indicated by a link member to NULL S2 S1 Constrained version of a linked list push Adds a new node to the top of the stack pop top Removes a node from the top Stores the popped value Returns true if pop was successful 1 3 6 Push (4) 4 1 3 6 A stack can be empty, “pop” from an empty stack is an error A stack can never be full (assuming infinite memory) Dale Roberts top Pop (4) 1 3 6 top Stack Operations struct list { int data struct list *next; } typedef struct list node; typedef node *link; 4 newnode 4 3 stack 3 2 Push link push(link stack, int value) { 1 link newnode; newnode = (link)malloc(sizeof(node)); newnode->data = value; newnode->next = stack; stack = newnode; top return(stack); 4 stack } Pop 3 link pop(link stack, int *valuePtr) { 2 link top; top = stack; stack = stack->next; 1 *valuePtr = top->data; free(top); return(stack); } Dale Roberts stack newnode 2 1 4 top 3 stack 2 1 valuePtr 4 Queues Queue Similar to a supermarket checkout line First-in, first-out (FIFO) Nodes are removed only from the head Nodes are inserted only at the tail Insert and remove operations Enqueue (insert) and dequeue (remove) Queue Model queue is a list, with insertion done only at one end and deletion done at the other end. enqueue: insert an element at the end of the queue dequeue: delete (and return) the element at the start of the queue first in first out model (FIFO) Linked list implementation of queues operating as a list constant time for enqueue & dequeue (keeping pointer to both the head and tail of the list) Dale Roberts Queue Operations enqueue link enqueue(link queue, int value) { link newnode; newnode = (link)malloc(sizeof(node)); newnode->data = value; newnode->next = NULL; if (queue!=NULL) { queue->next = newnode; queue = queue->next; } else queue = queue->next; return(queue); } dequeue link dequeue(link queue, int *valuePtr) { link dequeuenode; dequeuenode = queue; *valuePtr = dequeuenode ->data; queue = queue->next; free(dequeuenode); return(queue); } Dale Roberts queue newnode