Sunteți pe pagina 1din 10

pdfcrowd.com open in browser PRO version Are you a developer?

Try out the HTML to PDF API


A binary tree with root 1, with branches leading to nodes
labeled 2 and 3, and branches from these leading to 4, 5
and 6, 7, and so on. Note that this is an upside-down tree
structure. A complete binary tree is a tree in which every
level is completely filled. Moreover, all nodes must be as far
left as possible.

I. Defining a Tree
We sped past the general topic of trees in last lab so we could get some immersion in the
all-important binary and binary search trees. But we'll slow down some to consider trees in
data structures in a little greater detail. There is no more important topic.
A breakthrough in computing came with the advent of the tree data structure since it is a
nonlinear structure with important advantages. A tree allows us to implement a score of
algorithms in such a way that we achieve better improvements in efficiency than, for
example, linear data structures such as lists and arrays.
Trees provide almost an obvious way to organize data and have, therefore, become widely used in databases, web sites, file
systems and our old friend, graphical user interfaces. They are currently widely used in medical research as well.

Technically a tree is a nonempty finite set of nodes with one node serving as the root of the tree, with the
remaining nodes serving as subtree parts. See the illustration at left. Every node other than the root has a unique
predecessor.

The relationships in a tree lend themselves, in this age of fascination with geneology, to a parallel with family trees, such that the
terms "parent" and "child" are commonly used as we also saw last time.
With the obvious exception of the Adam of all nodes, each element in a tree has a parent and zero or more child elements.
Commonly, Adam is the root of the tree but we turn the tree upside down (that's the one non-intuitive practice) so that the root
is at the top. Each node in the tree has one unique parent (Virgin Birth believers, take heart). A tree can be empty and we can, as
you know, think recursively in building the tree. A node is external if it has no children (25 at left) and a node is internal if it has
one or more children (7 at left).
If the tree is empty or each of its nodes has no more than two subtrees, then it is called a binary tree. As a result, every node in a binary tree either has no children, or it has one left child, or it has
one right child, or it has both a left child and a right child, with each child being the root of a subtree.


1. What is the parallel of trees with object-oriented programming, especially in terms of terminology?

pdfcrowd.com open in browser PRO version Are you a developer? Try out the HTML to PDF API
Games
A complete game tree for checkers is in the
neighborhood of 10^40 nodes, while that
for chess is about 10^120, a prodigious
number. Complete game trees for most
games are too large to be stored
computationally.
As a result, tree-pruning strategies must be
used to prune the tree for most games,
which creates sub-trees that allow the
exploration of a limited number of game
combinations that people do so relatively
easily.
Such strategies are really strategies for
deciding how the complete game tree should
be pruned (or in terms I used above, how
the search space should be constrained),
and then moves are based on information
culled from the pruned game tree.
See the Computers and Games web page for
an illustration of game tree pruning.




Types of Data in a Binary Tree
Every node in a binary tree has its information divided into two parts. The first part
pertains to the structure of the tree--namely, it contains a key field (the part of information
used to order the elements), a parent field, a left-child field, and a right-child field. The
second part is the data.
The data can be either endogenous (data is inside inside the tree) or exogenous (it contains
references to the object's data). The root node of the tree, as you would expect, has its
parent field set to nil. Whenever a node does not have a right child or a left child then, also
as you would expect, that field is set to nil as well.

A complete binary tree, as shown at left, is defined as a binary tree in
which all leaves are at depth n or n-1 for some n.

Specifically, all the children on the last level must occupy the leftmost spots consecutively,
with no spot left unoccupied in between any two. Notice this property also characterizes
upper levels. Again, consider the complete binary tree above left.

Binary Search Tree Property
As we saw in the Lab 0, a Binary Search Tree (BST) is a binary tree in which each node stores an element so that the element stored in the
left sub-tree of a specific node is less than or equal to the node and elements stored in the right sub-tree of the node are greater than or
equal to the node.
This is called binary-search-tree property.

Traversal Methods
Compared to linear data structures which have only one logical way of traversing, moving along in one direction along the structure, such as
linked lists and one-dimensional arrays, there are many different ways to traverse trees. Beginning at the root of a binary tree, as we will see
below, there are three different steps that can be performed with the order that they are performed defining the traversal type.
These steps are:
performing an action on the current node (referred to as "visiting" the node);
or repeating the process with the subtrees rooted at our left and right children.

As a result, the traversal process is most easily described through recursion. Amazing how often we see that word.

pdfcrowd.com open in browser PRO version Are you a developer? Try out the HTML to PDF API
2. Why does a binary tree lend itself to recursive searching?



Building a Binary Search Tree
Part I.
In this practical section, we will use a Binary Search Trees.
We will continue to use the same set of numbers so you can clearly see how this Binary Search Tree
implements, in a different way, the binary search employed in the last lab.
In the last lab, we did a binary search on a series of numbers algorithmically on a prosaic data
structure, our old friend the array. Pretty low tech, even if a lot more efficient than a linear search.
Now we take the idea of binary search and root it (sorry, couldn't resist) more deeply into the data structure itself. General
computer science principle: if we build in algorithmic efficiency into the data structure, we will get improved efficiency.
First, delete all the nodes. Then do the same number set as before, namely, 2,4,5,7,8,9,10,11.
Important: before you insert each one, predict where it will go and how the tree will change with each insertion. Explain why each insertion goes where it does.
After you have done this, compare your results with the results below.
pdfcrowd.com open in browser PRO version Are you a developer? Try out the HTML to PDF API
Of course, we build the tree from top to bottom as usual in the upside-down world of
computer science trees. But in the building of a binary search tree, we must not
imagine that the assignment of locations is permanent because this is a dynamic
structure, which is what we want. Static structures are old-time structures that often
are not time-efficient.
At each insertion, we are effectively doing a binary search as we did in the last lab, but
now we are implementing the results of the search--an algorithmic activity--into the
data structure itself. As a result, this reflects a distinctive trend in computer science of
destroying the classical, problem-generating distinction between data and algorithm.
It might be objected that an ordered list already builds in the ordering into the array
that stored our by-now familiar sequence of 2,4,5,7,8,9,10,11.
But this is quite different. We wish in a binary search tree for the data structure itself
to reflect rather than require the binary search in order to locate items. Even if we
were to keep inserting items into a numeric sequence in an array (and all the hassle
that entails), it would be different from a binary search tree.
In a binary search tree, want the efficiency to be the same as a binary search on an
array, but we don't want the algorithmic effort required for binary searching an array.
Remember the comparisons, the low and the high variables, and the arithmetic
entailed in binarySearch4? We would like those operations to be a thing of the past
and certainly for the cumbersome limitations of arrays to be a thing of the past.
As we build this binary search tree we want the depth of the tree to be as shallow as
possible. The greater the depth of the tree, the more time a search could take. We are
trying to be as frugal as possible with CPU cycles.
At left, when we add 8 to the tree, it entails a reorganization because we don't want a
fourth generation any sooner than necessary. The general rule is to add a row only
when there is no other choice. Only when all the parents have two children do we add
a generation. In this case, only the right sub-tree needs to be reorganized.
But when we add 9, a major shuffle is entailed. A new root is established and 4
becomes the parent of 2 and 5. 8 must be the parent of 9 since 9 is greater than 8.
When we add 10, since we don't want to add a new generation if we don't have to, we
again shuffle the line-up. Even though 8 was entered long before 9, 9 must now
become the parent of 8. Each parent must have two children before we can add more
generations. That rule trumps the current organization every time.
In a word, to keep the execution time as low as possible, a binary search tree keeps
reorganizing as much as is necessary while the data are being added and before the
queries are made so that the queries access an optimized data structure.We
algorithmically invest in the data structure so that run-time operations on the
structure are more efficient.

Building a Binary Search Tree
Part II.
1. What will happen if you enter the same set of numbers but in reverse order? Will you get the same tree? Go ahead do this.
You might be wondering what the AVL and red-black togles are for. An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two children of any
node differ by at most one; as a result, it is also height-balanced. Lookup, insertion, and deletion all take O(log n) time in both the average and worst cases, where n is the
pdfcrowd.com open in browser PRO version Are you a developer? Try out the HTML to PDF API
node differ by at most one; as a result, it is also height-balanced. Lookup, insertion, and deletion all take O(log n) time in both the average and worst cases, where n is the
number of nodes in the tree prior to the operation. Insertions and deletions may require the tree to be rebalanced by one or more tree rotations. The AVL tree is named after
its inventor, G.M. Adelson-Velskii and E.M. Landis.
The balance factor of a node is the height of its right subtree minus the height of its left subtree and a node with balance factor 1, 0, or -1 is
considered balanced. A node with any other balance factor is considered unbalanced and requires rebalancing the tree. The balance factor is either
stored directly at each node or computed from the heights of the subtrees.
AVL trees are distinguished from red-black trees because they support the same set of operations and because red-black trees also take O(log n) time
for the basic operations. A red-black tree is a binary search tree which inserts and removes intelligently, to ensure the tree is reasonably balanced. AVL
trees perform better than red-black trees for applications that entail extensive lookup operations.
2. More important questions: if you have a different structure because of different order of entry, will you get different performance? Enter the set in
this order: 7, 11, 4, 9, 10, 2, 5, and 8. If your parameters are set the same way in the applet, you will get Tree 2 at right.
Will the two trees perform the same in terms of lookup? How many lookups will be necessary for 2 in each case? So far, so good. But how about 11?
So does the same data set guarantee the same performance, regardless of entry order?
Constraining the development of binary search trees in order to optimize performance for different kinds of operations (lookup, insertion, deletion,
traversal, and reorganization) is on ongoing area of computer science research. How many different kinds of binary search trees are there?


II. Traversal of the Tree Recursively

When we wish to do insertions, deletions and lookup operations on a binary tree, it must be traversed.
Remember, we do not have the ease of Compared to linear data structures such aslinked lists and one
dimensional arrays, which have only one logical means of traversal, tree structures can be traversed in
a variety of ways.
The graphic at right is a link to a fine applet that will walk you through the various ways of traversing a binary tree.
As a result, the most common operation on a binary tree is to traverse it, which means we want to visit each node on the binary tree.
For each node, as you could likely guess, we can visit a node first or we can visit that node's sub-tree first. These choices, in turn, lead
to three different kinds of traversals of a binary tree:

Pre-Order Traversal
1. Visit the root.
2. Traverse the left subtree in preorder.
3. Traverse the right subtree in preorder.
In other words, process all nodes of the tree by processing the root, then recursively process all subtrees.
The name of this ordering comes from the fact that the traversal visits a node before it has visited all the other nodes in the subtree of that node.

In-Order Traversal
1. Traverse the left subtree in inorder.
2. Visit the root.
3. Traverse the right subtree in inorder.
Inorder traversal only makes sense for binary trees. While pre-order traversal visits the root first and post-order traversal visits the root last, in-
order traversal visits the root in between visiting the left and right subtrees.
The name of this ordering comes from the fact that the traversal visits nodes before it has visited all the other nodes in the subtree of that node.
pdfcrowd.com open in browser PRO version Are you a developer? Try out the HTML to PDF API
Post-order or Depth-First Traversal
1. Traverse the left subtree in postorder.
2. Traverse the right subtree in postorder.
3. Visit the root.
In contrast with preorder traversal, which visits the root first, postorder traversal visits the root last.
The name of this ordering comes from the fact that the traversal visits a node after it has visited all the other nodes in the subtree of that node.
Last, trees can be traversed in level-order, where each node on a level is visited before going to a lower level. This is sometimes called breadth-first
traversal.
3. What does it mean to "traverse" a binary tree?

Binary Search Tree Traversal
Simulation
Part III.
Open up the Simulation if it is not
open(http://webpages.ull.es/users/jriera/Docencia/AVL/AVL%20tree%20applet.htm), and build in
our old friend, 2,4,5,7,8,9,10,11 (you may need to mix them up to get a non-linked list). Remember
that the tree should stay in tact while you do your traversing.
Before you do this however, to make sure you have a reasonable command of the three basic kinds
of traversal, try to draw in by hand how the traversing would on the diagram just below.
It is a link to a separate page in case you do it by hand, which I encourage. Once you have done one, check your work by actually
running the traversal, with the kind set by the button, illustrated at right. You may need to do it several times to make sure you
have caught all the action.

Questions:
1. For each kind of traversal, how is the traversing recursive, if it is?
2. Which one gets to 11 the quickest, or is there no difference? Note that you
can control the speed of the traversing with the second diamond on the above left.
3. Why is traversing necessary here and not necessary in an array. Why bother with the traversing opacity when an array is so
transparent and obvious in terms of how it works and is accessed?
4. Of the three, which gets to 5 the quickest?
5. Which gets to 7 first and which gets to it last (virtually by definition)?
6. How many steps to get from 2 to 11 in a post-order traversal?
7. If you add 12 to the tree, what will the new order be? Will the tree change much?
8. How about if you now add lucky 13?
pdfcrowd.com open in browser PRO version Are you a developer? Try out the HTML to PDF API
Augsburg Tree Run (last homework assignment):
Traverse Binary Tree
======== ====== ====
Building Binary Tree with this root value: 8
Inserted 2 to left of 8
Inserted 4 to right of 2
Inserted 5 to right of 4
Inserted 7 to right of 5
Inserted 9 to right of 8
Inserted 10 to right of 9
Inserted 11 to right of 10
Traversing tree in order:
========== ==== == =====
Traversed 2
Traversed 4
Traversed 5
Traversed 7
Traversed 8
Traversed 9
Traversed 10
Traversed 11
Traversing tree taking scenic route starting with item 11
Traversed 10
Traversed 9
Traversed 8
9. How many comparisons does it take to find 8 in the tree at left? Is that quicker than a binary search on an ordered array? To get your
answer, you might want to use the Binary Search Applet again.
10. Same question for 2--which is quicker, if one is?





III. Operations on a Binary Search Tree
Most operations on a binary search tree take time which is proportional to the height
of the tree. For a complete binary tree with node n, such operations run in (log n)
worst-case time. Consider the image below and remember that the point of continue
algorithmic reorganization of the binary search tree is to keep its height as small a
number as possible, dynamically.
If the tree, by contrast,
is a linear chain of n
nodes, however, since there is no savings owing to the
structure, the same operations takes (n) worst-case time.
Average case complexity of Search, Insert, and Delete
Operations is O(log n), where n is the number of nodes in
the tree.

Implementation of a Binary Search Tree
A binary search tree can be implemented as a linked data structure in which each node is an object with three pointer
fields. The three pointer fields left, right and p point to the nodes corresponding to the left child, right child and the
parent respectively nil in any pointer field signifies that there exists no corresponding child or parent.

As we saw above, and makes all the sense in the world, the root node is the only node in the binary
search tree structure with nil in its parent field. The root node is the local computational deity.

Note that in-order traversal of a binary search tree always gives a sorted sequence of the values. This is a direct and
perhaps all-too obvious-consequence of the binary search tree property. This provides a way of sorting a given
sequence of keys: first, create a binary search tree with these keys and then do an inorder traversal of the binary
search tree so created.
Note as well that the highest valued element in a binary
search tree can be found by traversing from the root in
the right direction all along until a node with no right link
is found (we can call that the rightmost element in the
binary search tree).
The lowest valued element in a binary search tree can
be found by traversing from the root in the left direction
all along until a node with no left link is found (we can
call that the leftmost element in the BST).
pdfcrowd.com open in browser PRO version Are you a developer? Try out the HTML to PDF API
Traversed 8
Traversed 7
Traversed 5
Traversed 4
Traversed 2
Search is largely uncomplicated in a binary search tree.
We start with the root and keep moving left or right
using the binary search property. If the key we are
seeking is present, this search procedure will lead us to
the key. If the key is not present, of course, we will end
up in a null link.
Insertion in a binary search tree is also an untaxing
operation. If we need to insert an element x, we first search for x. If x is present, there is nothing to do. If x is not
present, then our search procedure ends in a null link. It is at this position of this null link that x will be inserted.
If we repeatedly insert a sorted sequence of values to form a binary search tree, and don't optimize it, we obtain a skewed binary search tree. The height of such a tree, of course, is n - 1 if the tree
has n nodes. As a result, the worst-case complexity of searching for or inserting an element into a binary search tree with n nodes is O(n).

3. Why is insertion of an element into a binary search tree a piece of cake, computationally speaking?


AugsburgTree
Consider the program below which creates a binary tree. Copy it as usual, build and run it--the image is a link to the text version of the
program, with the yellowed out places you complete replaced with red asteriks. You should find that it produces output listed in the right
column, once the *********** have been filled in. There are five of these omissions--and they are simple expressions.
Using the table below (or the printable version), comment it (this should be handed in as homework).
Program Run :
Traverse Binary Tree
======== ====== ====
Building Binary Tree with this root value: 8
Inserted 2 to left of 8
Inserted 4 to right of 2
Inserted 5 to right of 4
Inserted 7 to right of 5
Inserted 9 to right of 8
Inserted 10 to right of 9
Inserted 11 to right of 10
Traversing tree in order:
========== ==== == =====
pdfcrowd.com open in browser PRO version Are you a developer? Try out the HTML to PDF API
Traversed 2
Traversed 4
Traversed 5
Traversed 7
Traversed 8
Traversed 9
Traversed 10
Traversed 11
Traversing tree taking scenic route starting with item 11
Traversed 10
Traversed 9
Traversed 8
Traversed 7
Traversed 5
Traversed 4
Traversed 2
java has exited with status 0.


pdfcrowd.com open in browser PRO version Are you a developer? Try out the HTML to PDF API

S-ar putea să vă placă și