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
Topic 5 Advanced Data Structures and Algorithms (HL) 5.3 Dynamic Data Structures Nodes and Pointers All data structures examined so far have had their size fixed from the start (they are static). A dynamic data structure can vary in size to suit the data it has to contain e.g. a club's membership list will vary in length as members join and leave. Dynamic structures are faster and more efficient to use but harder to program. Arrays are static - in using them to construct a database, separate arrays can be created for different data types. More usual is to arrange the data types into records which describe the individual items concerned e.g. the members of the club The records can then be defined as separate objects called nodes, which have all the characteristics of a club member e.g. Firstname, Surname, Address etc. and behave dynamically. In pseudocode, a node might be defined like this: newtype NODE record /* new type of object that is going to be a record in a database */ declare FIRSTNAME string declare SURNAME string declare AGE integer /* etc........ */ endrecord Such nodes can be stored statically in a single array of type NODE However, to be dynamic, the different nodes can be stored anywhere in memory, but must have a means of "keeping in touch" with the others. so no matter what order they arrive and are stored in, they "remember" the structure they are part of. A pointer is a special type of variable that holds the location of another node in memory (you could imagine it as a hyperlink to that next item). Pointers retain a logical order, which can be anything - In a library database, the books may be held in memory randomly or alphabetically by title - it might be useful to have an extra field for each book containing a pointer to another book by that same author for example newtype NODE record declare FIRSTNAME string declare SURNAME string declare AGE integer declare NEXT pointer --> NODE /* i.e. this node has a pointer that points at another node */ endrecord Linked Lists A list is any collection of items, the order of which usually matters. Lists tend to be recorded (saved or written) in the order in which they arrive (serially). This is Local Admin by Powershell -1- 5/1/2017 Topic 5 Advanced Data Structures and Algorithms (HL) 5.3 Dynamic Data Structures not necessarily the order in which you want to access the list (alphabetical by surname is good for members of a club, but they don't join in that order). A list of data records can be held in an array, with one record following another, but this presents problems when another record needs to be inserted (everything needs to be shuffled along) Records in a dynamic linked list can be stored anywhere in memory since the last part of each record is a pointer to the next item in the list (actually of course to its memory address) Each record will often also contain a head or start pointer that points back to the first item in the list and there may also be a single next free pointer giving the address of the next free record space in memory (you will not need to use these in your programming). The last item of the list will have a nil pointer, a special bit pattern that says "stop traversing the list" In a dynamic structure, inserted records can be stored anywhere in memory and the pointers of appropriate records adjusted You could implement a linked list using arrays e.g. declare NAMES string array (1..100) /* other arrays may be needed */ declare POINTERS integer array (1..100) declare START integer declare NEXTFREE integer not moving the contents of NAMES at all but changing the values in POINTERS, START and NEXTFREE instead. This saves shuffling the data along each time there is a change but is not dynamic and will cause an error when the array becomes full. Better, create each node as a new type of object containing all its data (including pointer to the next node) in one record (this makes the structure more dynamic and efficient). Note how to describe a new record object in pseudocode and that the pointer NEXTRECORD points to a NODE (an object in the process of being defined!) - this is an example of recursion: newtype NODE record declare NAME string /*other fields may be necessary */ declare NEXT pointer --> NODE endrecord declare START pointer --> NODE declare NEXTFREE integer Algorithm for adding an item to the end of a linked list (not done often but easy to follow) With a dynamic structure there is no danger of lack of available space Create the node and put the new data into it, including a nil pointer If the list is empty, make this new node the first Otherwise, traverse the list (follow all the links to find the end of the list Change the last item's pointer to point to the new item A possible pseudocode version: newtype NODE record declare NAME string /*other fields may be necessary */ Local Admin by Powershell -2- 5/1/2017 Topic 5 Advanced Data Structures and Algorithms (HL) 5.3 Dynamic Data Structures declare NEXT pointer --> NODE endrecord declare FRONT pointer --> NODE /* this is the first node in the list */ declare TEMP pointer --> NODE /* a temporary node for running along the list */ procedure INITIALIZE (ref FRONT pointer --> NODE) /* Pass this procedure the name of the first node */ /* This procedure effectively blanks the list */ FRONT <-- nil endprocedure INITIALIZE procedure APPEND (val ENTRY string) allocate (NEWNODE) /* make the node using the data passed*/ if FRONT = nil then FRONT --> nil <-- NEWNODE /* put it in at the front of the list */ /* make FRONT's pointer nil */ endif /* but if there is something in the list already... */ TEMP <-- FRONT --> NEXT while NEXT # nil do TEMP --> NEXT <-- NEXT /* put the next node into TEMP */ endwhile /* until we reach the end where there is space */ NEXT --> nil <-- NEWNODE endprocedure APPEND Deleting nodes from a linked list Nodes are usually deleted from the list by rearranging their pointers The node itself will be deleted when the program terminates (Java is actually good at garbage collection – reusing memory from unused objects) Algorithm for deleting an item from a linked list Guard against trying to delete from an empty list Follow the pointers until you get to the item Change the previous item's pointer to the following item procedure DELETE (val UNWANTED string) declare PREVIOUS pointer --> NODE declare CURRENT pointer --> NODE Local Admin by Powershell -3- 5/1/2017 Topic 5 Advanced Data Structures and Algorithms (HL) 5.3 Dynamic Data Structures /* Temporary nodes to allow traversing of the list */ /* Now check to see if the front node is empty if FRONT = nil then output "List is empty" return endif /* copy the first 2 nodes into PREVIOUS and CURRENT */ PREVIOUS --> NEXT <-- FRONT CURRENT --> NEXT <-- NEXT /* as long as this is not the node to delete, keep moving along the list */ while NAME # UNWANTED do PREVIOUS --> CURRENT <-- CURRENT CURRENT --> NEXT <-- NEXT /* but stop if you reach the end without finding it */ if CURRENT = nil then output "Item is not in the list" return endif endwhile /* delete the CURRENT node */ PREVIOUS --> NEXT <-- NEXT /* this effectively skips CURRENT, leaving it out of the list */ endprocedure DELETE Algorithm for inserting an item into a linked list With a dynamic structure there is no danger of lack of available space Create the new node If the list was empty, put the new node into front Otherwise, follow the links checking each time to find out where to insert the new item Change the new item's pointer to point to the next item Change the previous item's pointer to point to the new item. procedure INSERT (val ENTRY string) allocate (NEWNODE) /* make the node using the data passed*/ declare PREVIOUS pointer --> NODE declare CURRENT pointer --> NODE /* Temporary nodes to allow traversing of the list */ /* Now check to see if the front node is empty if FRONT = nil then FRONT --> nil <-- NEWNODE Local Admin by Powershell -4- 5/1/2017 Topic 5 Advanced Data Structures and Algorithms (HL) 5.3 Dynamic Data Structures return endif /* copy the first 2 nodes into PREVIOUS and CURRENT */ PREVIOUS --> NEXT <-- FRONT CURRENT --> NEXT <-- NEXT /* as long as this is not the place to insert, keep moving along the list */ while NAME < ENTRY do PREVIOUS --> CURRENT <-- CURRENT CURRENT --> NEXT <-- NEXT /* insert at the end if need be */ if CURRENT = nil then CURRENT --> nil <-- NEWNODE return endif /* insert here */ PREVIOUS --> NEXT <-- NEWNODE NEWNODE --> NEXT <-- CURRENT return endwhile endprocedure DELETE Single, double and circular linked lists Normal linked lists with one order are said to be single A list may have two pointers, indicating two different orders (it is double) Sometimes the second set of pointers represents the reverse order of the first A circular linked list has an end node with a pointer pointing at the head node Binary trees Lists, stacks and queues are linear (each item is preceded or followed by exactly one other, with the exception of the first or last Binary trees are non-linear hierarchical data structures where every component may have one super-component directly above and no more than two subcomponents directly below They are finite sets of one or more linked nodes, linked by lines called branches Except when the tree is empty, there is a special node with no parent, called the root node Each subnode of a node is a child (hence left child and right child) Nodes at the same level are siblings From each child downwards can be regarded as a subtree that will behave exactly like the larger tree Like linked lists, binary trees are dynamic but have the additional advantage of being much faster to search (compare the binary search with the linear search for a comparison) On inserting a node, go down the left subtree if the new node comes before and down the right if it comes after. Implementing a binary tree requires the data field and two pointer fields (left and right) Local Admin by Powershell -5- 5/1/2017 Topic 5 Advanced Data Structures and Algorithms (HL) 5.3 Dynamic Data Structures Traversing binary trees Handling binary trees most commonly involves inorder traversal i.e. traverse the left subtree, return to the root node and then traverse the right subtree (this is the most common type of traversal) A preorder traversal would involve visiting the root node, traversing the left subtree, then traversing the rightr subtree. A postorder traversal would involve traversing the left subtree, traversing the right subtree then visiting the root node. As with the linked list, start by creating nodes: newtype NODE record declare NAME string /*other fields may be necessary */ declare LEFT pointer --> NODE declare RIGHT pointer --> NODE endrecord but note that this time each node has two pointers. Some procedures for manipulating the tree are similar to a list declare ROOT pointer --> NODE /* this is the first node in the tree */ declare RUNNER pointer --> NODE /* a temporary node for running along the tree */ procedure INITIALIZE (ref ROOT pointer --> NODE) /* Pass this procedure the name of the first node */ /* This procedure effectively blanks the tree */ ROOT <-- nil endprocedure INITIALIZE However, the easiest way to traverse a tree is to use recursion, e.g. to print the whole tree: procedure PRINTTREE (ref RUNNER pointer --> NODE) if RUNNER <> nil then PRINTTREE (RUNNER --> NEXT <-- LEFT output RUNNER PRINTTREE (RUNNER --> NEXT <-- RIGHT endif endprocedure PRINTTREE Call this procedure with PRINTTREE (ROOT) and it will traverse in order, printing out as it goes, checking left node, printing, checking right node (this illustrates well the elegance recursion can bring) Similarly, to count the number of nodes in a tree: function COUNTNODES (ref RUNNER pointer --> NODE) result integer Local Admin by Powershell -6- 5/1/2017 Topic 5 Advanced Data Structures and Algorithms (HL) 5.3 Dynamic Data Structures declare COUNT integer COUNT <-- 0 if RUNNER <> nil then COUNTNODES (RUNNER --> NEXT <-- LEFT COUNT <-- COUNT + 1 PRINTTREE (RUNNER --> NEXT <-- RIGHT endif return COUNT endfunction COUNTNODES Inserting a node into a binary tree Create the new node Check if the root node is empty (base case) - if so, insert the new node Otherwise, go left if the new node belongs before, go right if it belongs after Repeat these recursively procedure INSERTNODE (val NEWNODE NODE) if ROOT = nil then ROOT = NEWNODE return endif else RUNNER = ROOT while true do if NEWNODE.NAME < RUNNER.NAME then if RUNNER.LEFT = nil then RUNNER.LEFT = NEWNODE return endif else RUNNER = RUNNER.LEFT endelse else if RUNNER.RIGHT = nil then RUNNER.RIGHT = NEWNODE return endif else RUNNER = RUNNER.RIGHT endelse endelse endwhile endelse endprocedure INSERTNODE Deleting a node from a binary tree With two nodes, it is harder to rearrange the nodes in the tree and retain its structure. A possible solution is to have a boolean field for each node that is set to true when a node is deleted. Thus it can be filtered from any searching or displaying Local Admin by Powershell -7- 5/1/2017 Topic 5 Advanced Data Structures and Algorithms (HL) 5.3 Dynamic Data Structures operations. It can actually be deleted from the data file by simply not saving that node. Local Admin by Powershell -8- 5/1/2017