Sie sind auf Seite 1von 2

COMP2211Analysis of Algorithms, Sem II, 2016Tutorial 2


Department of Computing
COMP2211Analysis of Algorithms
Sem II, 2016
Lecturer(s): Daniel Coore
Tutorial 2

Recursive Data Structures and Analysing Algorithms

Recursive Data Structures
Analysing Algorithms

Recursive Data Structures

Assume that you have the (linked) list ADT discussed in class, implemented in Python as below
(the constructor pair has been replaced with the (traditional Lisp) name cons instead, but the
function is the same. For convenience, we use the native Python empty list to represent an empty
linked list as well (i.e. assume a global definition of nil = []).

def cons (x , y ):
return [x , y ]

def set_car (p , v ):
p [0] = v

def car ( p ):
return p [0]

def set_cdr (p , v ):
p [1] = v

def cdr ( p ):
return p [1]

1. Write a function called llist that acts as a convenience constructor for a linked list from
a native list in Python. For example, llist([1, 2, 3]) should return a linked list with the
elements 1, 2, 3 in that order (we shall denote that as (1 2 3), note the spaces between
elements). In your implementation do not use the list slice feature of Python.
2. Write a function called append that takes two linked lists as arguments and returns a new
list that contains all of the elements of the first list followed by all those of the second. For
example, append(llist([3, 2, 1]), llist([4, 5, 6])) would return the linked list (3 2 1 4 5 6).
3. Write a function called last that takes a linked list as an argument and returns the last
element in the list. For example, last(llist [1, 2, 3]) would return 3.

COMP2211Analysis of Algorithms, Sem II, 2016Tutorial 2

Binary Trees
Given the following implementation of the constructor for binary trees, complete the implementation of the rest of the ADT shown below:
def makeBinTree ( root , left , right ):
return cons ( left , cons ( root , right ))

def leftSubTree ( tree ):

emptyTree = nil
def rightSubTree ( tree ):

def root ( tree ):

1. Write a function called isLeaf(tree) that respects the binary tree ADT above, and that takes
a binary tree as argument and returns True if the tree is a leaf node, and False otherwise.
(Recall that a leaf node is one that has both of its subtrees empty).
2. Write a function called height that accepts a binary tree as an argument and returns the
height of the tree. The height of a binary tree is defined as the length of the longest path
from the root to a leaf node.

Analysing Algorithms
Recall that when analysing an algorithm, you must perform the following steps:
Identify the basic operations for your analysis
Define the size of the input (n) in relation to the actual inputs passed as arguments the function
being analysed.
Count the number of basic operations performed as a function of the size of input, defined in
the previous step.
1. For each of the list algorithms written in the previous section, analyse it to ascertain the
order of growth of its time complexity. You may include the linked list ADT functions in
your basic operations.
2. Obtain a recurrence relation for the time complexity of height which you defined earlier. Use
the binary tree ADT operations along with any arithmetic operations as basic operations.
Define the size of input, n, to be the number of nodes in the argument tree. Let nl and nr
represent the number of nodes in the left and right subtrees, respectively.
(a) Write down an invariant relating n to nl and nr .
(b) Suppose that it is known that at every node in the tree, the sizes of its two subtrees are
equal. Use this information to simplify your recurrence relation for the time complexity
of height.
(c) Are you able to obtain an order of growth from your simplified recurrence relation?