Title: Problem Solving with Data Structures using Java: A Multimedia Approach
1Problem Solving with Data Structures using Java
A Multimedia Approach
- Chapter 10 Generalizing Lists and Trees
2Chapter Objectives
3Story
- What we were just doing with LLNode
- What linked lists are good for.
- Using linked lists to represent structure and
behavior - What trees are good for.
- Using trees to represent structure and behavior
- Examples
- Equations
- Matching
- Unification
4Removing Redundant Code
- The DisplayableNode (for scene graphs) and
CollectableNode (for sound trees) class
hierarchies have lots of the exact same code. - Can we put all this code in one place (an
abstract superclass), make it general, but make
it so that all the old code still works?
5Abstracting LLNode
abstract LLNode Knows next Knows how to do all
basic list operations
6CollectableNode
- Knows just knows the part that specializes LLNode
for collectable (sound-returning) nodes.
7DrawableNode
- Just specializes LLNode to represent things that
can draw with a turtle and draw down their linked
list with a turtle (drawOn).
8LLNode The abstract definition of what a linked
list node is
- Given LLNode, we can make anything we want into a
linked list. - Want a linked list of students?
- Subclass LLNode into StudentNode
- StudentNodes know names and ID numbers, and know
how to access and return these. - The linked list part is inherited from LLNode.
- Every StudentNode knows next and knows how to
getNext, add, etc.
9- /
- Class that represents a node in a linked list
- _at_author Mark Guzdial
- _at_author Barb Ericson
- /
- public abstract class LLNode
- / The next node in the list /
- private LLNode next
- /
- Constructor for LLNode that just sets
- next to null
- /
- public LLNode()
- next null
-
10- /
- Method to set the next element
- _at_param nextOne the element to set as next
- /
- public void setNext(LLNode nextOne)
- this.next nextOne
-
- /
- Method to get the next element
- _at_return the next element in the linked list
- /
- public LLNode getNext()
- return this.next
-
11- / Method to remove a node from the list, fixing
- the next links appropriately.
- _at_param node the element to remove from the
list. - /
- public void remove(LLNode node)
- if (nodethis)
- System.out.println("I can't remove myself
from " - "the head of the list")
- return
-
- LLNode current this
- // While there are more nodes to consider
- while (current.getNext() ! null)
- if (current.getNext() node)
- // Simply make node's next be this next
- current.setNext(node.getNext())
A node cant remove itself
12- /
- Insert the input node after this node.
- _at_param node element to insert after this.
- /
- public void insertAfter(LLNode node)
- // Save what "this" currently points at
- LLNode oldNext this.getNext()
- this.setNext(node)
- node.setNext(oldNext)
-
13- /
- Return the last element in the list
- _at_return the last element in the list
- /
- public LLNode last()
- LLNode current
- current this
- while (current.getNext() ! null)
- current current.getNext()
-
- return current
-
14- /
- Return the number of the elements in the
list - _at_return the number of elements in the list
- /
- public int count()
- LLNode current
- int count 1
- current this
- while (current.getNext() ! null)
- count
- current current.getNext()
-
- return count
-
-
15- /
- Add the passed node after the last node in
this list. - _at_param node the element to insert after
this. - /
- public void add(LLNode node)
- this.last().insertAfter(node)
-
16 while (this.getNext() ! null) temp
this.last() this.remove(temp)
reversed.add(temp) // Now put the
head of the old list on the end of // the
reversed list. reversed.add(this) // At
this point, reversed // is the head of the
list return reversed
- /
- Reverse the list starting at this,
- and return the last element of the list.
- The last element becomes the FIRST element
- of the list, and THIS goes to null.
- _at_return the new head of the list
- /
- public LLNode reverse()
- LLNode reversed, temp
- // Handle the first node outside the loop
- reversed this.last()
- this.remove(reversed)
17Next step Change DrawableNode to extend LLNode
- /
- Stuff that all nodes and branches in the
- scene tree know.
- _at_author Mark Guzdial
- _at_author Barb Ericson
- /
- public abstract class DrawableNode extends LLNode
- /
- Constructor for DrawableNode
- /
- public DrawableNode()
- super() // call to parent constructor
-
18- /
- Use the given turtle to draw oneself
- _at_param t the Turtle to draw with
- /
- public abstract void drawWith(Turtle t)
- // no body in an abstract method
- /
- Draw on the given picture
- _at_param bg the background picture to draw on
- /
- public void drawOn(Picture bg)
- Turtle t new Turtle(bg)
- t.setPenDown(false)
- this.drawWith(t)
-
-
19Have to fix branches
- /
- Ask all our children to draw,
- then tell the next element to draw
- _at_param turtle the Turtle to draw with
- /
- public void drawWith(Turtle turtle)
- // start with the first child
- DrawableNode current this.getFirstChild()
- // Have my children draw
- while (current ! null)
- current.drawWith(turtle)
- turtle.moveTo(turtle.getXPos()gap,turtle.ge
tYPos()) - current (DrawableNode) current.getNext()
-
- // Have my next draw
- if (this.getNext() ! null)
getNext() returns an LLNode, but we need it to be
a DrawableNode so that we can drawWith().
20Rewriting CollectableNode to extend LLNode
- /
- Node in a sound tree.
- _at_author Mark Guzdial
- _at_author Barb Ericson
- /
- public abstract class CollectableNode extends
LLNode - /
- No argument constructor
- /
- public CollectableNode()
- super() // call to parent class constructor
-
21- /
- Play the list of sound elements
- after me
- /
- public void playFromMeOn()
- this.collect().play()
-
- /
- Collect all the sounds from me on
- _at_return the collected sound
- /
- public abstract Sound collect()
All the linked list methods are now factored out.
22Have to cast
- /
- Collect all the sound from our firstChild,
- then collect from next.
- _at_return the combined sound
- /
- public Sound collect()
- Sound childSound
- CollectableNode node
- if (firstChild ! null)
- childSound firstChild.collect()
-
- else
- childSound new Sound(1)
-
- // Collect from my next
- if (this.getNext() ! null)
This error doesnt show up at compile time, but
it does at runtime. Same error really, similar
fix.
23Now we have a generic Linked List Node!
- We can generate a new linked list easily, by
subclassing LLNode. - Lets create a linked list of students.
24- /
- Class that represents a student node
- in a linked list
- _at_author Mark Guzdial
- _at_author Barb Ericson
- /
- public class StudentNode extends LLNode
- / the student this node is keeping track off
/ - private Student myStudent
- /
- Constructor that takes the student
- _at_param someStudent the student to store at
this node - /
- public StudentNode(Student someStudent)
- super()
- myStudent someStudent
-
25- /
- Method to get the student stored at this
node - _at_return the student stored at this node
- /
- public Student getStudent() return myStudent
- /
- Method to get information about this node
- _at_return an information string
- /
- public String toString()
- if (this.getNext() null)
- return "StudentNode with student "
myStudent -
- else
- return "StudentNode with student "
myStudent - " and next " this.getNext()
-
-
26- /
- Main method for testing
- /
- public static void main(String args)
- Student student1 new Student("Tanya
Clark",1) - Student student2 new Student("Tim
O'Reilly",2) - Student student3 new Student("Tesheika
Mosely",3) - StudentNode node1 new StudentNode(student1)
- StudentNode node2 new StudentNode(student2)
- StudentNode node3 new StudentNode(student3)
- node1.setNext(node2)
- node2.setNext(node3)
- StudentNode node (StudentNode)
node1.getNext().getNext() - System.out.println(node.getStudent())
-
27Why do people use linked lists?
- Whenever you want dynamic size to the list,
- You may want the ordering to represent something,
- You want insertion and deletion to be cheap and
easy, - You are willing to make finding a particular item
slower.
28Examples of Linked Lists
- Order of layers in Visio or PowerPoint
- Notes in a Phrase in JMusic
- Video segments in non-linear video editing.
- Items in a toolbar.
- Slides in a PowerPoint presentation.
29But what are trees good for?
- Trees represent hierarchical structure.
- When just representing ordering (linearity) isnt
enough. - Trees can store operations (behavior), as well as
data. - Linked lists can, too, but not as useful.
30Examples of Trees
- Representing how parts of music assemble to form
a whole. - Representing the elements of a scene.
- Scene graph
- Representing the inheritance relationships among
classes. - Class hierarchy
- Files and directories on your hard disk.
- Elements in an HTML page.
- Organization chart
- Political affiliations
31Example Tree Equation
- Its fairly easy to turn an equation into a tree.
- If you see an operation, make a branch.
- Otherwise, make a node.
- The structure here represents order of operation.
- Evaluating this tree is like collecting() the
sounds, but collection involves computation
(behavior) at the branches.
3 4 5
3
4
5
32Example Tree Taxonomies(Keeping track of
meaning)
- Lets say that you want to compare prices at
various websites for the same item. - At one site, they call it the retail price
- At another, they call it the customers cost
- How do you track that these are similar meanings?
- Its the same as knowing that a MoveBranch is a
kind of Branch is a kind of DrawableNode!
33Tree of Meanings
Here, the arrows mean the same thing as in a
class hierarchy. The thing below is a
specialization of the thing above. Artificial
Intelligence (AI) and Semantic Web researchers
really do represent taxonomies in just this way.
Price
Retail price
Wholesale price
Business-to-business price
Customer cost
Customer price
34Algorithm for matching
- Traverse the tree to find phrase1.
- Traverse the tree to find phrase2.
- Do both have a common ancestor (parent)?
- Thats the meaning in common!
- If not, need to extend the taxonomy.
35Example tree Unification
My cat ate a fat worm.
- Sentence Diagrams are trees.
- Arrows dont mean the same things here.
- Some arrows are saying instance-of a category
(like noun) - Other arrows are saying has-pieces-within (like
links from subject and object)
ate
verb
subject
object
noun
article
noun
cat
adjective
adjective
a
worm
My
fat
36How do we search a collection of sentence
diagrams?
- Imagine Youre an expert with the National
Security Agency. - You have megabytes of captured terrorist
messages. - Using specialized Natural Language Understanding
(NLU) technology, you have trees of all this
text. - Now what do you do with it?
37Compare trees
attack
- We can create a tree describing the kind of
sentence that we want to find. - We leave variables that can be bound in the
process of the query. - Matching complex trees like this is sometimes
called unification. - Not exactly the same word? How do we determine if
its close enough? See previous slides
verb
object
subject
noun
noun
ltsuspectgt
ltlocation in United Statesgt
38Trees in User Interfaces
- Any user interface is actually composed of a
tree! - Windows hold panes hold buttons and text areas.
window
pane
pane
button
button
text area
button
39Binary Trees
- Binary trees have at most two children per
branch. - Any node can be a branch.
- Binary search trees are binary trees that are
well-structured.
40Binary Trees
- Binary trees can represent any kind of tree.
- Lots of interesting properties.
- The minimum number of levels of n nodes in a
binary tree is log2(n)1
41Binary Search Trees
- Binary search trees are particularly fast to
search. - Lists are always O(n) to search
- Well-structured trees are O(log2 n) to search.
- Rule For each data node
- Items to left are less than data in this node.
- Items to right are greater than data in this
node.
bear
apple
cash
ant
ark
card
cat
42Implementing Binary Trees
- /
- Class that represents a binary tree node
- _at_author Mark Guzdial
- _at_author Barb Ericson
- /
- public class TreeNode
- / the data stored at this node /
- private String data
- / the left child /
- private TreeNode left
- / the right child /
- private TreeNode right
43Constructing a new node
- /
- Constructor that takes the string
- to store
- _at_param something the string to store
- /
- public TreeNode(String something)
- data something
- left null
- right null
-
Any node can be the root of a tree
44Printing a tree, recursively
- // Skipping getters and setters you know what
those look like - /
- Method to return a string of information
- _at_return the information string
- /
- public String toString()
- return
- "This " this.getData()
- " Left " this.getLeft()
- " Right " this.getRight()
-
45Testing our TreeNode
- gt TreeNode node1 new TreeNode("George")
- gt node1 // with no ending '' it is like a
System.out.println(node) - This George Left null Right null
- gt TreeNode node1b new TreeNode("Alicia")
- gt node1.setLeft(node1b)
- gt node1
- This George Left This Alicia Left null Right
null Right null
46Implementing insert for binary search trees
- Well use strings as data.
- To compare them, use compareTo
47- /
- Method to add a new tree node in the tree
- _at_param newOne the node to add
- /
- public void insert(TreeNode newOne)
- / if the data at this node is greater than
the - data in the passed node
- /
- if (this.data.compareTo(newOne.data) gt 0)
- // and no left child then add this as the
left child - if (this.getLeft() null)
- this.setLeft(newOne)
-
- // else insert it into the left subtree
- else
- this.getLeft().insert(newOne)
-
-
48- // must be great than or equal
- else
- // if no right child use this as the right
child - if (this.getRight() null)
- this.setRight(newOne)
-
- // else insert into the right subtree
- else
- this.getRight().insert(newOne)
-
-
49Testing
- gt TreeNode node1 new TreeNode("Shilpa")
- gt TreeNode node2 new TreeNode("Sam")
- gt TreeNode node3 new TreeNode("Tina")
- gt TreeNode node4 new TreeNode("Zach")
- gt System.out.println(node1)
- This Shilpa Left null Right null
- gt node1.insert(node2)
- gt System.out.println(node1)
- This Shilpa Left This Sam Left null Right
null Right null - gt node1.insert(node3)
- gt System.out.println(node1)
- This Shilpa Left This Sam Left null Right
null Right This - Tina Left null Right null
- gt node1.insert(node4)
- gt System.out.println(node1)
- This Shilpa Left This Sam Left null Right
null Right This - Tina Left null Right This Zach Left null
Right null
50Finding in a binary search tree
- /
- Method to find the passed someValue in
- the tree and return the node or return null
- if it isn't found in the tree
- _at_param someValue the value to find
- /
- public TreeNode find(String someValue)
- // if we found the value return the node
- if (this.getData().compareTo(someValue) 0)
- return this
-
51- / if the data in the current node is greater
than - the value /
- if (this.data.compareTo(someValue) gt 0)
- // if no left child return null (not found)
- if (this.getLeft() null)
- return null
-
- // else look in the left subtree
- else
- return this.getLeft().find(someValue)
-
-
52- / the data in the current node is less than the
- value /
- else
- // if no right child then not found
- if (this.getRight() null)
- return null
-
- // look in the right subtree
- else
- return this.getRight().find(someValue)
-
-
-
53Testing the search on example tree
54Balancing a tree
- Both these trees are well-ordered as search
trees. - But balanced trees lead to O(log2n) search times.
- We balance by rotating subtrees
Original,unbalanced
Rotating right branch of Sam
55Printing out the elements in alphabetical order
- Our default toString() goes as left as possible
before doing any right branches. - How do we print out everything in the binary
search tree in order?
56- /
- Method to do an inorder traversal of the
tree - _at_return a string with the data values in it
- /
- public String traverse()
- String returnValue ""
- // Visit left
- if (this.getLeft() ! null)
- returnValue " " this.getLeft().traverse
() -
- // Visit me
- returnValue " " this.getData()
- // Visit right
- if (this.getRight() ! null)
- returnValue " " this.getRight().travers
e() -
- return returnValue
57In-Order Traversal of our example tree
- gt node1.traverse()
- Sam Shilpa Tina Zach
58Pre-order vs. In-Order
- If equations were trees ?
- toString() does a pre-order traversal.
- 3 4 x y
- traverse() does in-order
- 3 4 x y
- Post-order gives the RPN version
- y x 4 3
59Using trees as lists
- /
- Method to add the newOne node as
- the first node in the tree (treating
- the tree like a list
- _at_param newOne the new node to add
- /
- public void addFirst(TreeNode newOne)
- if (this.getLeft() null)
- this.setLeft(newOne)
-
- else
- this.getLeft().addFirst(newOne)
-
-
60- /
- Method to add the newNode as the last
- node in a list (treating the tree like a
list) - _at_param newOne the node to add
- /
- public void addLast(TreeNode newOne)
- if (this.getRight() null)
- this.setRight(newOne)
-
- else
- this.getRight().addLast(newOne)
-
-
Example use gt TreeNode node1 new
TreeNode("the") gt node1.addFirst(new
TreeNode("George of")) gt node1.addLast(new
TreeNode("jungle")) gt node1.traverse() " George
of the jungle"