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
1 Chapter 22 – Data Structures Outline 22.1 22.2 22.3 22.4 22.5 22.6 Introduction Self-Referential Classes Linked Lists Stacks Queues Trees 2002 Prentice Hall. All rights reserved. 2 22.1 Introduction • Data structures include linked lists, stacks, queues and binary trees • Data structures underlie some of Python’s basic data types, such as lists, tuples and dictionaries 2002 Prentice Hall. All rights reserved. 3 22.2 Self-Referential Classes • Self-referential class contains a member that refers to an object of the same class • Example: class Node with two data members – member data and reference member nextNode which refers to an object of class Node • None reference normally indicates end of a data structure 2002 Prentice Hall. All rights reserved. 4 22.2 Self-Referential Classes 15 10 15 Fig. 22.1 Three linked objects of a self-referential class. 2002 Prentice Hall. All rights reserved. 5 22.3 Linked Lists • Linked list: linear collection of self-referential classes, called nodes, connected by reference links • Accessed via reference to the list’s first node • Insertions and deletions can be performed at any point in a linked list • Circular, singly linked list: last node contains a reference to the first node • Doubly linked list allows traversal both forward and backward 2002 Prentice Hall. All rights reserved. 6 22.3 Linked Lists firstNode H lastNode D … Fig. 22.2 Linked list graphical representation. 2002 Prentice Hall. All rights reserved. Q 7 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 Outline # Fig. 22.3: ListModule.py Self-referential class # Classes List and Node definitions. class Node: """Single node in a data structure""" ListModule.py def __init__( self, data ): """Node constructor""" self._data = data self._nextNode None Return= string representation of Node’s data def __str__( self ): """Node data representation""" return str( self._data ) class List: """Linked list""" def __init__( self ): Initialize """List constructor""" references to last and first nodes of list to None self._firstNode = None self._lastNode = None def __str__( self ): """List string representation""" if self.isEmpty(): return "empty" currentNode = self._firstNode output = [] 2002 Prentice Hall. All rights reserved. 8 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 while currentNode is not None: output.append( str( currentNode._data ) ) currentNode = currentNode._nextNode Insertoutput node at) return " ".join( front of list Outline ListModule.py def insertAtFront( self, value ): Create new Node object """Insert node at front of list""" newNode = Node( value ) if self.isEmpty(): # List is empty self._firstNode = self._lastNode = newNode else: # List is not empty newNode._nextNode = self._firstNode Insert node at end of list self._firstNode = newNode def insertAtBack( self, value ): """Insert node at back of list""" newNode = Node( value ) if self.isEmpty(): # List is empty self._firstNode = self._lastNode = newNode else: # List is not empty self._lastNode._nextNode = newNode self._lastNode newNode Remove= node from end of list def removeFromFront( self ): """Delete node from front of list""" Raise IndexError exception on empty list if self.isEmpty(): # raise exception on empty list raise IndexError, "remove from empty list" tempNode = self._firstNode 2002 Prentice Hall. All rights reserved. 9 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 if self._firstNode is self._lastNode: # one node in list self._firstNode = self._lastNode = None else: self._firstNode = self._firstNode._nextNode return tempNode Remove Outline ListModule.py node from back of list def removeFromBack( self ): """Delete node from back of list""" if self.isEmpty(): # raise exception on empty list raise IndexError, "remove from empty list" tempNode = self._lastNode if self._firstNode is self._lastNode: # one node in list self._firstNode = self._lastNode = None else: currentNode = self._firstNode # locate second-to-last node while currentNode._nextNode is not self._lastNode: currentNode = currentNode._nextNode currentNode._nextNode = None self._lastNode = currentNode Predicate method returns true if List object is empty return tempNode def isEmpty( self ): """Returns true if List is empty""" return self._firstNode is None 2002 Prentice Hall. All rights reserved. 10 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 # Fig. 22.4: fig22_04.py # Driver to test class List. from ListModule import List Outline fig22_04.py # instructions for user instructions = """Enter one of the following: 1 to insert at beginning of list 2 to insert at end of list 3 to delete from beginning of list 4 to delete from end of list Create empty List object 5 to end list processing\n""" listObject = List() # create empty List print instructions # print instructions # obtain user choice until user chooses to quit (choice 5) while 1: choice = raw_input("\n? ") Insert user input at front of list # insert at front if choice == "1": listObject.insertAtFront( raw_input( "Enter value: " ) ) print "The list is: ", listObject Insert user input at end of list # insert at end elif choice == "2": listObject.insertAtBack( raw_input( "Enter value: " ) ) print "The list is: ", listObject 2002 Prentice Hall. All rights reserved. 11 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 # delete from front elif choice == "3": Remove item from front of list try: value = listObject.removeFromFront() except IndexError, message: print "Failed to remove:", message else: print value, "removed from list" print "The list is: ", listObject # delete from end elif choice == "4": Outline fig22_04.py Remove item from back of list try: value = listObject.removeFromBack() except IndexError, message: print "Failed to remove:", message else: print value, "removed from list" print "The list is: ", listObject # exit elif choice == "5": break # terminate while loop # invalid choice else: print "Invalid choice:", choice print instructions print "End list test\n" 2002 Prentice Hall. All rights reserved. 12 Enter one of the following: 1 to insert at beginning of list 2 to insert at end of list 3 to delete from beginning of list 4 to delete from end of list 5 to end list processing Outline ? 2 Enter value: 2 The list is: 2 ? 2 Enter value: 3 The list is: 2 3 ? 1 Enter value: 1 The list is: 1 2 3 ? 3 1 removed from list The list is: 2 3 ? 4 3 removed from list The list is: 2 ? 3 2 removed from list The list is: empty 2002 Prentice Hall. All rights reserved. 13 ? 4 Failed to remove: remove from empty list Outline ? 5 End list test 2002 Prentice Hall. All rights reserved. 14 22.3 Linked Lists (a) _firstNode 7 11 _newNode 12 (b) firstNode 7 11 newNode 12 Fig. 22.5 Graphical representation of the insertAtFront operation. 2002 Prentice Hall. All rights reserved. 15 22.3 Linked Lists (a) _firstNode 12 (b) _lastNode 7 _firstNode 12 11 _lastNode 7 11 newNode 5 newNode 5 Fig. 22.6 Graphical representation of the insertAtBack operation. 2002 Prentice Hall. All rights reserved. 16 22.3 Linked Lists (a) _firstNode 12 (b) _lastNode 7 11 _firstNode 12 5 _lastNode 7 11 5 tempNode Fig. 22.7 Graphical representation of the removeFromFront operation. 2002 Prentice Hall. All rights reserved. 17 22.3 Linked Lists (a) _firstNode 12 (b) _lastNode 7 _firstNode 12 11 _currentNode 7 5 _lastNode 11 5 tempNode Fig. 22.8 Graphical representation of the removeFromBack operation. 2002 Prentice Hall. All rights reserved. 18 22.4 Stacks • Constrained version of a linked list • New nodes can be added to a stack and removed from a stack only at the top • Referred to as a last-in, first-out (LIFO) data structure • Last node set to None to indicate bottom of the stack • Methods push and pop add a new node and remove a node, respectively 2002 Prentice Hall. All rights reserved. 19 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 # Fig. 22.9: StackModule.py Import class # Class Stack definition. Outline List from ListModule from ListModule import List StackModule.py class Stack ( List ): """Stack composed from linked list""" def __init__( self ): """Stack constructor"""Class Stack contains a List object as a data member self._stackList = List() def __str__( self ): List’s __str__ Call """Stack string representation""" method return str( self._stackList ) def push( self, element ): """Push data onto stack""" Method push calls List method insertAtFront self._stackList.insertAtFront( element ) def pop( self ): """Pop data from stack""" Method pop calls List method removeFromFront return self._stackList.removeFromFront() Calls def isEmpty( self ): """Return 1 if Stack is empty""" List method isEmpty return self._stackList.isEmpty() 2002 Prentice Hall. All rights reserved. 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Outline # Fig. 22.10: fig22_10.py # Driver to test class Stack. Create Stack object from StackModule import Stack fig22_10.py stack = Stack() print "Processing Stack" Adda items to Stack object by calling push for i in range( 4 ): stack.push( i ) print "The stackRemove is:", stack items from Stack object by calling pop while not stack.isEmpty(): pop = stack.pop() print pop, "popped from stack" print "The stack is:", stack Processing a Stack The stack is: 0 The stack is: 1 0 The stack is: 2 1 0 The stack is: 3 2 1 0 3 popped from stack The stack is: 2 1 0 2 popped from stack The stack is: 1 0 1 popped from stack The stack is: 0 0 popped from stack The stack is: empty 2002 Prentice Hall. All rights reserved. 21 22.5 Queues • Nodes removed from head of the queue and inserted at tail of the queue • Referred to as a first-in, first-out (FIFO) data structure • Insert and remove operations known as enqueue and dequeue, respectively 2002 Prentice Hall. All rights reserved. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 22 Import class List QueueModule.py Outline # Fig. 22.11: # Class Queue definition. from ListModule import List QueueModule.py class Queue: """Queue composed from linked list""" List def __init__( self ): """Queue constructor""" object data member self._queueList = List() def __str__( self ): List method __str__ Calls """Queue string representation""" return str( self._queueList ) def enqueue( self, element ): Method """Enqueue element""" enqueue calls List method insertAtBack self._queueList.insertAtBack( element ) def dequeue( self ): """Dequeue element""" Method dequeue calls List method removeFromFront return self._queueList.removeFromFront() def isEmpty( self ): Calls List """Return 1 if Queue is empty""" method isEmpty return self._queueList.isEmpty() 2002 Prentice Hall. All rights reserved. 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 # Fig. 22.12: fig22_12.py # Driver to test class QueueModule. Outline Create Queue object from QueueModule import Queue fig22_12.py queue = Queue() items print "processingInsert a Queue" in Queue object by calling method enqueue for i in range( 4 ): queue.enqueue( i ) print "The queue is:", queue Remove items from Queue object by calling method dequeue while not queue.isEmpty(): dequeue = queue.dequeue() print dequeue, "dequeued" print "The queue is:", queue processing a Queue The queue is: 0 The queue is: 0 1 The queue is: 0 1 2 The queue is: 0 1 2 3 0 dequeued The queue is: 1 2 3 1 dequeued The queue is: 2 3 2 dequeued The queue is: 3 3 dequeued The queue is: empty 2002 Prentice Hall. All rights reserved. 24 22.6 Trees • Tree: nonlinear, two-dimensional data structure • Tree nodes contain two or more links • Binary tree: tree whose nodes all contain two links (one or both of which may be None) • Root node: first node in a tree • Each link in the root node refers to a child • Left child: root node of the left subtree • Right child: root node of the right subtree • Siblings: children of a single node • Leaf node: node with no children 2002 Prentice Hall. All rights reserved. 25 22.6 Trees • Binary search tree (BST) – The values in any left subtree are less than the value in the subtree’s parent node and the values in the right subtree are greater than the value in the subtree’s parent node – Node can be inserted only as a leaf node • Tree traversals of a BST – Inorder traversal • Traverse left subtree, process node value and traverse right subtree • prints the node values in ascending order in a process called binary-tree sort – Preorder traversal: process node value, traverse left subtree and traverse right subtree – Postorder traversal: traverse left subtree, traverse right subtree and process node value 2002 Prentice Hall. All rights reserved. 26 22.6 Trees B A D C Fig. 22.13 Binary tree graphical representation. 2002 Prentice Hall. All rights reserved. 27 22.6 Trees 47 25 11 7 77 43 17 31 65 44 93 68 Fig. 22.14 Binary search tree graphical representation. 2002 Prentice Hall. All rights reserved. 28 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 # Fig. 22.15: TreeModule.py a node in # Treenode and Represents Tree definition. Outline a binary tree class Treenode: """Single Node in a Tree""" def __init__( self, data ): References to left """Treenode constructor""" TreeModule.py and right children set to None self._left = None self._data = data self._right = None def __str__( self ): """Tree string representation""" return str( self._data ) class Tree: """Binary search tree""" def __init__( self Set ): _rootNode """Tree Constructor""" Insert node self._rootNode = None to None into tree def insertNode( self, value ): """Insert node into tree""" Create Treenode if self._rootNode is None: # tree is empty insertNodeHelper if Tree self._rootNode Calls = Treenode( value ) else: # tree is not empty self.insertNodeHelper( self._rootNode, value ) is not empty 2002 Prentice Hall. All rights reserved. 29 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 def insertNodeHelper( self, node, value ): Insert smaller values in left subtree """Recursive helper method""" Outline Recursively traverse tree to find place for new Treenode # insert to left TreeModule.py if value < node._data: if node._left is None: node._left = Treenode( value ) else: Insert larger values in right subtree self.insertNodeHelper ( node._left, value ) elif value > node._data: if node._right is None: # insert to right node._right = Treenode( value ) else: Eliminate duplicate node values self.insertNodeHelper( node._right, value ) else: # duplicate node print value, "duplicate" def preOrderTraversal( self ): """Preorder traversal""" Perform preorder traversal self.preOrderHelper( self._rootNode ) def preOrderHelper( self, node ): """Preorder traversal helper function""" if node is not None: print node, self.preOrderHelper( node._left ) self.preOrderHelper( node._right ) 2002 Prentice Hall. All rights reserved. 30 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 def inOrderTraversal( self ): """Inorder traversal""" Perform inorder traversal self.inOrderHelper( self._rootNode ) Outline TreeModule.py def inOrderHelper( self, node ): """Inorder traversal helper function""" if node is not None: self.inOrderHelper( node._left ) print node, self.inOrderHelper( node._right ) def postOrderTraversal( self ): """Postorder traversal""" Perform postorder traversal ) self.postOrderHelper( self._rootNode def postOrderHelper( self, node ): """Postorder traversal helper function""" if node is not None: self.postOrderHelper( node._left ) self.postOrderHelper( node._right ) print node, 2002 Prentice Hall. All rights reserved. 31 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 # Fig. 22.16: fig22_16.py # Driver to test Tree class. from TreeModule import Create TreeTree object Outline fig22_16.py tree = Tree() values = raw_input( "Enter 10 integer values, separated by spaces:\n" ) Add node to Tree object for i in values.split(): tree.insertNode( int( i ) ) Perform tree traversals print "\nPreorder Traversal" tree.preOrderTraversal() print print "Inorder Traversal" tree.inOrderTraversal() print print "Postorder Traversal" tree.postOrderTraversal() print Enter 10 integer values, separated by spaces: 50 25 75 12 33 67 88 6 13 68 Preorder Traversal 50 25 12 6 13 33 75 67 68 88 Inorder Traversal 6 12 13 25 33 50 67 68 75 88 Postorder Traversal 6 13 12 33 25 68 67 88 75 50 2002 Prentice Hall. All rights reserved. 32 22.6 Trees 27 13 6 42 17 33 48 Fig. 22.17 A binary search tree. 2002 Prentice Hall. All rights reserved.