COSC 01 - Data Structures and Algorithms
COSC 01 - Data Structures and Algorithms
COURSE MATERIAL
FOR
ALGORITHMS
1
ACKNOWLEDGEMENT
We acknowledge the use of the Courseware of the National Open University of
Nigeria (NOUN) as the primary resource. Internal reviewers in Ahmadu Bello
University have also been duly listed.
2
COPYRIGHT PAGE
© 2018 Ahmadu Bello University (ABU) Zaria, Nigeria
All rights reserved. No part of this publication may be reproduced in any form or
by any means, electronic, mechanical, photocopying, recording or otherwise
without the prior permission of the Ahmadu Bello University, Zaria, Nigeria.
ISBN:
Tel: +234
E-mail:
3
COURSE WRITERS/DEVELOPMENT TEAM
Editor
Prof. M.I Sule
Language Reviewer
Enegoloinu Ojokojo
Instructional Designers/Graphics
Emmanuel Ekoja / Ibrahim Otukoya
ODL Expert
Dr. Abdulkarim Muhammad
4
QUOTE
5
COURSE STUDY GUIDE
i. COURSE INFORMATION
Course Code: COSC 301
Course Title: Data Structures and Algorithms
Credit Units: 3
Year of Study: 3
Semester: 1
Description:
This course is an introduction to design patterns and recursion. Data structures
such as trees (including binary, AVL and multiway trees), heaps, stacks and queues
will be covered. Graphs and hashing techniques are also covered. In the course of
this study, you will learn how to design new algorithms for each new data structure
studied, create and perform simple operations on graph data structures, describe
6
and implement common algorithms for working with advanced data structures and
recognise which data structure is best used in solving each particular problem.
7
STL (2nd Edition), New Jersey: Prentice Hall.
French C. S. (1992). Computer Science, DP Publications, (4th Edition),
199-217.
Robert L., “Data Structures and Algorithms in Java”, 2nd Edition,
Sams Publishing, 2003.
Shaffer, Clifford A. A. (1998). Practical Introduction to Data Structures
and Algorithm Analysis, Prentice Hall, pp. 77–102.
ii. Other Resources
http://www.gnu.org/manual/emacs-20.3/emacs.html
http://www.indiana.edu/~ucspubs/b131
http://yoda.cis.temple.edu:8080/UGAIWWW/help
http://www.cs.sunysb.edu/~skiena/214/lectures/
https://www.geeksforgeeks.org/doubly-linked-list/
v. COURSE AIM
The aim of this course is to give you a feel for algorithms and data
structures as a central part of what it is to be a computer scientist. You
will develop skills in selecting and implementing appropriate data
structures and algorithms to solve problems.
vi. COURSE GOAL
This course strives to strengthen your ability to solve problems
computationally by utilizing an understanding of algorithm analysis and
data structures. A strong understanding of algorithm analysis and data
structures will greatly improve your ability to solve problems with
powerful and efficient programs. It should be of interest to you that
Employees and Graduate schools are really interested in students who
possess these skills, so you should take this course seriously.
8
vii. COURSE OUTCOMES
After studying this course, you should be able to:
1. Describe the basic operations on stacks, lists and queue data structures.
2. Explain the notions of trees, hashing and binary search trees.
3. Identify the basic concepts of object-oriented programing.
4. Develop java programs for simple applications.
5. Discuss the underlying principles of basic data types: lists, stacks and
queues.
6. Describe structures and algorithms for external storage: external sorting,
external search trees.
7. Identify directed and undirected graphs.
8. Discuss sorting: internal and external sort.
9. Describe the efficiency of algorithms, recursion and recursive programs.
9
ix. TIME (TO COMPLETE SYLLABUS/COURSE)
To cope with this course, you would be expected to commit a minimum of three
hours weekly for the course.
C. Grading Scale:
A = 70-100
B = 60 – 69
C = 50 - 59
D = 45-49
F = 0-44
D. Feedback
Courseware based:
10
1. In-text questions and answers (answers preceding references)
2. Self-assessment questions and answers (answers preceding references)
Tutor based:
1. Discussion Forum tutor input
2. Graded Continuous assessments
Student based:
1. Online program assessment (administration, learning resource, deployment,
and assessment).
11
OEDb: over 10,000 free courses from universities as well as reviews of
colleges and rankings of college degree programs
Open Tapestry: over 100,000 open licensed online learning resources for an
academic and general audience
OER Commons: over 40,000 open educational resources from elementary
school through to higher education; many of the elementary, middle, and
high school resources are aligned to the Common Core State Standards
Open Content: a blog, definition, and game of open source as well as a
friendly search engine for open educational resources from MIT, Stanford,
and other universities with subject and description listings
Academic Earth: over 1,500 video lectures from MIT, Stanford, Berkeley,
Harvard, Princeton, and Yale
JISC: Joint Information Systems Committee works on behalf of UK higher
education and is involved in many open resources and open projects
including digitising British newspapers from 1620-1900!
Other sources for open education resources
Universities
The University of Cambridge's guide on Open Educational Resources for
Teacher Education (ORBIT)
OpenLearn from Open University in the UK
Global
Unesco's searchable open database is a portal to worldwide courses and
research initiatives
African Virtual University (http://oer.avu.org/) has numerous modules on
subjects in English, French, and Portuguese
12
https://code.google.com/p/course-builder/ is Google's open source software
that is designed to let anyone create online education courses
Global Voices (http://globalvoicesonline.org/) is an international community
of bloggers who report on blogs and citizen media from around the world,
including on open source and open educational resources
Individuals (which include OERs)
Librarian Chick: everything from books to quizzes and videos here, includes
directories on open source and open educational resources
K-12 Tech Tools: OERs, from art to special education
Web 2.0: Cool Tools for Schools: audio and video tools
Web 2.0 Guru: animation and various collections of free open source
software
Livebinders: search, create, or organise digital information binders by age,
grade, or subject (why re-invent the wheel?)
13
xii. ABU DLC ACADEMIC CALENDAR/PLANNER
PERIOD
Semester Semester 1 Semester 2 Semester 3
Activity JAN FEB MAR APR MAY JUN JUL AUG SEPT OCT NOV DEC
Registration
Resumption
Late Registn.
Facilitation
Revision/
Consolidation
Semester
Examination
14
xiii. COURSE STRUCTURE AND OUTLINE
Course Structure
WEEK/DAYS MODULE STUDY SESSION ACTIVITY
15
1. Read Courseware for the corresponding Study Session.
2. View the Video(s) on this Study Session
Study Session 4 3. Listen to the Audio on this Study Session
Title: Linked Lists 4. View any other Video/U-tube (http://bit.ly/2Pbi90H,
http://bit.ly/2UdSX8R , http://bit.ly/2ME8Y74 ,
Pp. 66 http://bit.ly/33ZOZoE , http://bit.ly/2U5ZHp4,
http://bit.ly/2ZebDea , http://bit.ly/2MD0M70
)
5. View referred OER (address/site )
6. View referred Animation (http://bit.ly/33VilVj )
7. Read Chapter/page of Standard/relevant text.
8. Any additional study material
9. Any out of Class Activity
1. Read Courseware for the corresponding Study Session.
2. View the Video(s) on this Study Session
Study Session 5 3. Listen to the Audio on this Study Session
Title: Stacks and 4. View any other Video/U-tube (http://bit.ly/2Lc6l91 ,
Queues http://bit.ly/341wCiX , http://bit.ly/329fKoZ ,
http://bit.ly/2ZAGrW4 , http://bit.ly/2ZAGrW4 ,
Pp. 85 http://bit.ly/2PoKrVM , http://bit.ly/33W2NAu ,
http://bit.ly/2MArY6p )
5. View referred OER (address/site )
6. View referred Animation (http://bit.ly/341wCiX )
Week 4 7. Read Chapter/page of Standard/relevant text.
8. Any additional study material
9. Any out of Class Activity
1. Read Courseware for the corresponding Study Session.
2. View the Video(s) on this Study Session
Study Session 6 3. Listen to the Audio on this Study Session
Title: Recursion 4. View any other Video/U-tube (http://bit.ly/30wvulo ,
http://bit.ly/2PeeWO5 , http://bit.ly/33U1HoZ ,
Pp. 103 http://bit.ly/2U3P5a2 , http://bit.ly/2U97Bhp ,
http://bit.ly/2ZgAYnZ )
5. View referred OER (address/site )
6. View referred Animation (http://bit.ly/2U5iHEj )
7. Read Chapter/page of Standard/relevant text.
8. Any additional study material
9. Any out of Class Activity
1. Read Courseware for the corresponding Study Session.
2. View the Video(s) on this Study Session
Study Session 7 3. Listen to the Audio on this Study Session
Title: Analysis of 4. View any other Video/U-tube (http://bit.ly/2MDl2oP ,
Week 5 recursive http://bit.ly/2zocdH4 , http://bit.ly/2ZwIc6k ,
algorithms http://bit.ly/2PdKL9C , http://bit.ly/2Zialiq ,
http://bit.ly/2L6Tg0Q)
Pp. 126 5. View referred OER (address/site )
6. View referred Animation (http://bit.ly/31XCPL4 )
7. Read Chapter/page of Standard/relevant text.
16
8. Any additional study material
9. Any out of Class Activity
1. Read Courseware for the corresponding Study Session.
Study Session 1 2. View the Video(s) on this Study Session
Title: Tree 3. Listen to the Audio on this Study Session
4. View any other Video/U-tube (http://bit.ly/33SfqfQ ,
Pp. 137 http://bit.ly/33ZQbbC , http://bit.ly/2U5YIW4 ,
http://bit.ly/2Pbi90H )
5. View referred OER (address/site )
STUDY 6. View referred Animation (http://bit.ly/2PbLkk5 ,
http://bit.ly/2PbLkk5 )
MODULE 2 7. Read Chapter/page of Standard/relevant text.
8. Any additional study material
9. Any out of Class Activity
1. Read Courseware for the corresponding Study Session.
2. View the Video(s) on this Study Session
Study Session 2 3. Listen to the Audio on this Study Session
Title: Binary Search 4. View any other Video/U-tube (http://bit.ly/2ZpdZCh ,
Tree http://bit.ly/2KWL1FN , http://bit.ly/2Zsrsgz ,
http://bit.ly/2ZrXntm , http://bit.ly/3207oja ,
Pp. 151 http://bit.ly/2PdLyHC , http://bit.ly/2zm08C3 ,
http://bit.ly/2zn37Kt )
Week 6 5. View referred OER (address/site )
6. View referred Animation (http://bit.ly/2MChZxj )
7. Read Chapter/page of Standard/relevant text.
8. Any additional study material
9. Any out of Class Activity
1. Read Courseware for the corresponding Study Session.
2. View the Video(s) on this Study Session
3. Listen to the Audio on this Study Session
Study Session 3 4. View any other Video/U-tube (http://bit.ly/2MDlWBJ ,
Title: Tree http://bit.ly/3419IZl , http://bit.ly/2KUgGYm ,
Traversal http://bit.ly/3497bMK , http://bit.ly/31XE78S )
5. View referred OER (address/site )
Pp. 162 6. View referred Animation (http://bit.ly/2MD3UQi )
7. Read Chapter/page of Standard/relevant text.
8. Any additional study material
9. Any out of Class Activity
17
7. Read Chapter/page of Standard/relevant text.
8. Any additional study material
9. Any out of Class Activity
1. Read Courseware for the corresponding Study Session.
2. View the Video(s) on this Study Session
Study Session 5 3. Listen to the Audio on this Study Session
Title: AVL Tree 4. View any other Video/U-tube (http://bit.ly/30BdWVf ,
http://bit.ly/2ZfeBz7 , http://bit.ly/2ZfeBz7 ,
Pp. 189 http://bit.ly/2MDjPOl , http://bit.ly/30B1KE7 ,
http://bit.ly/2L4Aasg )
5. View referred OER (address/site )
6. View referred Animation (http://bit.ly/2U7Rq3R )
7. Read Chapter/page of Standard/relevant text.
8. Any additional study material
9. Any out of Class Activity
1. Read Courseware for the corresponding Study Session.
2. View the Video(s) on this Study Session
Study Session 6 3. Listen to the Audio on this Study Session
Title: B-Tree 4. View any other Video/U-tube (http://bit.ly/340haUk ,
http://bit.ly/340haUk , http://bit.ly/2Hr7DMp,
Pp. 211 http://bit.ly/2Nxku3B , http://bit.ly/2NyTikU
, http://bit.ly/30BgsuF ,
http://bit.ly/2NufU6d )
5. View referred OER (address/site )
6. View referred Animation (http://bit.ly/2ZnVr5r)
7. Read Chapter/page of Standard/relevant text.
8. Any additional study material
Week 8 9. Any out of Class Activity
1. Read Courseware for the corresponding Study Session.
Study Session 1 2. View the Video(s) on this Study Session
Title: Huffman 3. Listen to the Audio on this Study Session
Coding 4. View any other Video/U-tube (http://bit.ly/2KWfKCS ,
http://bit.ly/2HnJVR5 , http://bit.ly/2HnJVR5 ,
Pp. 231 http://bit.ly/30zWjVW ,
http://bit.ly/33ZeA0Z, http://bit.ly/2KVExa7
STUDY )
5. View referred OER (address/site )
MODULE 3
6. View referred Animation (http://bit.ly/33ZeA0Z )
7. Read Chapter/page of Standard/relevant text.
8. Any additional study material
9. Any out of Class Activity
18
1. Read Courseware for the corresponding Study Session.
2. View the Video(s) on this Study Session
Study Session 2 3. Listen to the Audio on this Study Session
Title: Graphs 4. View any other Video/U-tube (http://bit.ly/2Zm1nQo ,
http://bit.ly/2ZrUMQn ,
Week 9 Pp. 246 http://bit.ly/2KU4uaa, http://bit.ly/2zogYQW,
http://bit.ly/2ZteSd4, http://bit.ly/2U2FkJv,
http://bit.ly/2KXJgIA )
5. View referred OER (address/site )
6. View referred Animation (http://bit.ly/33YXJLF )
7. Read Chapter/page of Standard/relevant text.
8. Any additional study material
9. Any out of Class Activity
1. Read Courseware for the corresponding Study Session.
2. View the Video(s) on this Study Session
3. Listen to the Audio on this Study Session
Study Session 3 4. View any other Video/U-tube (http://bit.ly/2MDqJTE ,
Title: Topological http://bit.ly/2U31Kdz , http://bit.ly/2ZeLfRv
Sort , http://bit.ly/31XKrgC ,
http://bit.ly/2LaTbJw, http://bit.ly/2Pekd8l
Pp. 274 )
5. View referred OER (address/site )
6. View referred Animation (http://bit.ly/2MDqJTE )
7. Read Chapter/page of Standard/relevant text.
8. Any additional study material
9. Any out of Class Activity
1. Read Courseware for the corresponding Study Session.
2. View the Video(s) on this Study Session
Study Session 4 3. Listen to the Audio on this Study Session
Title: Shortest Path 4. View any other Video/U-tube (http://bit.ly/2MBOyvm ,
algorithm http://bit.ly/2z9zgoQ , http://bit.ly/2PcMVpW ,
http://bit.ly/2ZcxrXw , http://bit.ly/31XL6i6
Pp. 281 )
5. View referred OER (address/site )
6. View referred Animation (http://bit.ly/2MBOyvm )
7. Read Chapter/page of Standard/relevant text.
8. Any additional study material
Week 10 9. Any out of Class Activity
1. Read Courseware for the corresponding Study Session.
2. View the Video(s) on this Study Session
Study Session 5 3. Listen to the Audio on this Study Session
Title: Minimum 4. View any other Video/U-tube (http://bit.ly/2L6NvjT ,
Spanning Tree http://bit.ly/30Bvdxt , http://bit.ly/2U67xiE ,
http://bit.ly/2PfJ77y , http://bit.ly/2MqAy7o ,
Pp. 289 http://bit.ly/30LDPSc )
5. View referred OER (address/site )
6. View referred Animation (http://bit.ly/2PfJ77y )
19
7. Read Chapter/page of Standard/relevant text.
8. Any additional study material
9. Any out of Class Activity
20
Study Session 4 3. Listen to the Audio on this Study Session
Title: Memory 4. View any other Video/U-tube (http://bit.ly/2ZsSYX8 ,
Management http://bit.ly/2ZoSUNj , http://bit.ly/2NwIe7R,
http://bit.ly/2U9fT9c , http://bit.ly/2HFbc1V
Pp. 357 , http://bit.ly/2U5DeZ7 )
5. View referred OER (address/site )
6. View referred Animation (http://bit.ly/323jCaN )
7. Read Chapter/page of Standard/relevant text.
8. Any additional study material
9. Any out of Class Activity
Week 13 REVISION/TUTORIALS (On Campus or Online) & CONSOLIDATION
WEEK
21
TABLE OF CONTENT
Title Page……………………………………………...……………………………..……1
Acknowledgement Page …………………………………………………….……………2
Copyright Page ………………………………………..…………..………….…………..3
Course Writers/Development Team ……………………...……….………….…………4
Quote …………………………………..…………………...……….………….…………5
22
2.0 MODULE 2: Trees……………………………………………………………….......137
Study Session 1: Tree …………………………………………………………………......137
Study Session 2: Binary Tree……………………………………………………………...151
Study Session 3: Binary Search Tree…………………………………………………..,…162
Study Session 4: Binary Heap…………………………………………………………......171
Study Session 5: AVL Tree……………………………………………………………......189
Study Session 6: B-Tree……………………………………………………………….......211
23
Course Outline
MODULE 1: Design Patterns and Recursion
Study Session 1: Review of Object-Oriented Concepts in JAVA
Study Session 2: Design Patterns
Study Session 3: Complexity Analysis
Study Session 4: Linked Lists
Study Session 5: Stacks and Queues
Study Session 6: Recursion
Study Session 7: Analysis of recursive algorithms
MODULE 2: Trees
Study Session 1: Tree
Study Session 2: Binary Tree
Study Session 3: Binary Search Tree
Study Session 4: Binary Heap
Study Session 5: AVL Tree
Study Session 6: B-Tree
MODULE 4: Hashing
Study Session 1: Hashing
Study Session 2: Lempel-Ziv Compression Techniques
Study Session 3: Garbage Collection
24
Study Session 4: Memory Management
25
xii. STUDY MODULES
MODULE 1: Design Patterns and Recursion
Contents:
Study Session 1: Review of Object-Oriented Concepts in JAVA
Study Session 2: Design Patterns
Study Session 3: Complexity Analysis
Study Session 4: Linked Lists
Study Session 5: Stacks and Queues
Study Session 6: Recursion
Study Session 7: Analysis of recursive algorithms
STUDY SESSION 1
Review of Object-Oriented Concepts in JAVA
Section and Subsection Headings:
Introduction
1.0 Learning Outcomes
2.0 Main Content
2.1 - Object-Oriented Concepts supported by JAVA.
2.2 - Advantages of Object-Orientation.
2.3 - Review of Inheritance.
2.3.1- Notes about Inheritance
2.4 - Review of Abstract Classes.
2.5 - Review of Interfaces.
3.0 Tutor Marked Assignments (Individual or Group assignments)
4.0 Study Session Summary and Conclusion
5.0 Self-Assessment Questions and Answers
6.0 Additional Activities (Videos, Animations & Out of Class activities)
7.0 Self-Assessment Question Answers
26
8.0 References/Further Readings
Introduction:
We begin this course by taking a review of some object-oriented Concepts that
you have learnt from COSC 211 and COSC 212. In this first study session, we
shall take a look at some of the advantages of the object-oriented concepts
supported by Java and their advantages. We then go on to review some concepts
such as inheritance, abstract classes and interfaces.
27
- Polymorphism: Same code behaves differently at different times during
execution. This is due to dynamic binding.
28
class Employee {
protected String name;
protected double payRate;
public Employee(String name, double payRate) {
this.name = name;
this.payRate = payRate;
}
public String getName() {return name;}
public void setPayRate(double newRate) {
payRate = newRate;
}
public double pay() {return payRate;}
public void print() {
System.out.println("Name: " + name);
System.out.println("Pay Rate: "+payRate);
}
}
Now, suppose we wish to define another class to represent a part-time employee
whose salary is paid per hour. We inherit from the Employee class as follows:
29
- Constructors are not inherited, but can be called using the super keyword.
Such a call must be the first statement.
- If the constructor of the super class is not called, then the complier inserts
a call to the default constructor -watch out!
- The super keyword may also be used to call a method of the super class.
-
30
The following extends the Employee abstract class to get MonthlyEmployee
class.
class MonthlyEmployee extends Employee {
public MonthlyEmployee(String empName, double empRate) {
super(empName, empRate);
}
public double pay() {
return payRate;
}
}
The next example extends the MonthlyEmployee class to get the Executive
class.
class Executive extends MonthlyEmployee {
private double bonus;
public Executive(String exName, double exRate) {
super(exName, exRate);
bonus = 0;
}
public void awardBonus(double amount) {
bonus = amount;
}
public double pay() {
double paycheck = super.pay() + bonus;
bonus = 0;
return paycheck;
}
public void print() {
super.print();
System.out.println("Current bonus: " + bonus);
}
}
In-text Question 1
An Abstract class must contain at least one abstract method, (true or false)?
Answer
True
31
Figure 1.1.1: Inheritance and Abstract Classes
Next, we highlight the advantages of organising classes using abstract classes,
inheritance - same type, polymorphism using the following example which is
based on the examples from sections 2.3 and 2.4
32
importantly, interfaces are here to provide a kind of "multiple inheritance"
which is not supported in Java. If both parents of a child implement a method,
which one does the child inherit? (Multiple inheritance confusion). Interfaces
allow a child to be of both type A and B. Recall that Java has the Comparable
interface defined as:
interface Comparable {
int compareTo(Object o);
}
Recall also that java has the java.util.Arrays class, which has a sort method that
can separate any array whose contents are either primitive values or comparable
objects. Thus, to sort our list of Employee objects, all we need is to modify the
Employee class to implement the Comparable interface. Notice that this will
work even if the Employee class is extending another class or implementing
another interface. This modification is shown in the example below.
In-text Question 2
Not all methods provided by an interface must be implemented by a class that implements
that interface, (True or False).
Answer
False
33
Since Employee class implements the Comparable interface, the array of
employees can now be sorted as shown below:
import java.util.Arrays;
public class TestInterface {
public static void main(String[] args) {
Employee[] list = new Employee[3];
list[0] = new Executive("Jarallah Al-Ghamdi", 50000);
list[1] = new HourlyEmployee("Azmat Ansari", 120);
list[2] = new MonthlyEmployee("Sahalu Junaidu", 9000);
((Executive)list[0]).awardBonus(11000);
for(int i = 0; i < list.length; i++)
if(list[i] instanceof HourlyEmployee)
((HourlyEmployee)list[i]).addHours(60);
Arrays.sort(list);
for(int i = 0; i < list.length; i++) {
list[i].print();
System.out.println("Paid: " + list[i].pay());
System.out.println("**********************");
}
}
The
} output of the program is
34
5. An instance of a class can be assigned to a variable of type any of the
interfaces the class implements, (true or false)?
4.0 Conclusion/Summary
In this study session, we reviewed some object-oriented concepts supported by
Java and their advantages. You then learnt about some concepts such as
inheritance, abstract classes and interfaces using examples. In the next study
session, you will learn about design patterns, which allow reusability among
unrelated classes.
6.0 Additional Activities (Videos, Animations & Out of Class activities) e.g.
a. Visit U-tube http://bit.ly/2FIJOOy , http://bit.ly/2KOX1t0 , http://bit.ly/2KOGbKL ,
http://bit.ly/2Y0czSY , http://bit.ly/2YmsL0c , http://bit.ly/2GmSA63 ,
http://bit.ly/2TVWV5L , http://bit.ly/2L5Kosd, http://bit.ly/2SAN2cW,
http://bit.ly/2P9AhYQ , http://bit.ly/2SAlowE , http://bit.ly/2YaPGaA ,
http://bit.ly/30SYVOe , http://bit.ly/2JZzBzh , http://bit.ly/2Zjl479 Watch the video &
summarise in 1 paragraph
b. View the animation on http://bit.ly/2JZh2yt and critique it in the discussion
forum.
c. Take a walk and engage any 3 students on Abstract Classes and Interfaces; In
2 paragraphs summarise their opinion of the discussed topic. etc.
35
7.0 Self Assessment Question Answers
1. True
2. False
36
STUDY SESSION 2
Design Patterns
Section and Subsection Headings:
Introduction
1.0 Learning Outcomes
2.0 Main Content
2.1- What is Design Pattern?
2.1.1- The Container Pattern.
2.1.1.1- The AbstractContainer Class
2.1.2: The Iterator Pattern.
2.1.3: The Visitor Pattern.
2.1.3.1: The isDone method
2.1.3.2: The AbstractVisitor Class
2.1.3.3: The toString Method
2.1.3.4: The accept Method
2.1.4: The SearchableContainer Pattern.
2.1.5: The Association Pattern.
3.0 Tutor Marked Assignments (Individual or Group assignments)
4.0 Study Session Summary and Conclusion
5.0 Self-Assessment Questions and Answers
6.0 Additional Activities (Videos, Animations & Out of Class activities)
7.0 Self-Assessment Question Answers
8.0 References/Further Readings
Introduction:
In the last study session, we reviewed some object-oriented concepts. As a
follow up to that, you will learn about some basic design patterns in this study
session. Learning to use these patterns makes code become even more reusable,
more flexible, etc, as you would see.
37
1.0 Study Session Learning Outcomes
After studying this session, I expect you to be able to:
1. Explain what design patterns are
2. Design and implement Containers
3. Implement visitors
4. Use searchable containers and associations
38
2.1.1.1 The Abstract Container Class
The following is the AbstractContainer class that implements the Container
interface which will be used as base from which concrete container classes are
derived.
39
2.1.3 The Visitor Pattern
Many operations on data structures are observed to have the pattern of visiting
each object - hence, the Visitor pattern. For this pattern we define the Visitor
interface as follows:
public interface Visitor {
void visit (Object object);
boolean isDone ();
}
Note that the loop that iterates the container‟s objects is not in the visit method.
It is in the container‟s accept method. To print all objects in an instance, c of
SomeContainer, the accept method is called as follows:
Container c = new SomeContainer();
//....
c.accept (new PrintingVisitor());
40
2.1.3.1 The isDone method
The isDone method of the visitor is used to stop the visit method from visiting
the other objects of a container when a success is recorded. The following code
segment shows how the isDone method is used.
In-text Question 1
What is the function of the isDone method of the Visitor class?
Answer
The Association Pattern
41
public abstract class AbstractVisitor implements Visitor {
public abstract void visit (Object object);
public boolean isDone () {
return false;
}
}
42
While the accept method takes only one visitor, a container can have more than
one Iterator at the same time.
2.1.4 The SearchableContainer Pattern
Some of the data structures we shall study have the additional property of being
searchable. The SearchableContainer interface extends the Container interface
by adding four more methods as shown below:
public interface SearchableContainer extends Container {
boolean isMember (Comparable object);
void insert (Comparable object);
void withdraw (Comparable obj);
Comparable find (Comparable object);
}
The find method is used to locate an object in the container and returns its
reference. It returns null if not found.
43
public class Association implements Comparable {
protected Comparable key;
protected Object value;
public Association(Comparable comparable, Object obj){
key = comparable;
value = obj;
}
public Association(Comparable comparable){
this(comparable, null);
}
// ...
public Comparable getKey(){return key;}
public void setKey(Comparable key){this.key = key;}
public Object getValue(){return value;}
public void setValue(Object value){this.value = value;}
public int compareTo(Object obj){
Association association = (Association)obj;
return key.compareTo(association.getKey());
}
public boolean equals(Object obj){
return compareTo(obj) == 0;
}
public String toString() {
String s = "{ " + key;
if(value != null)
s = s + " , " + value;
return s + " }";
}
}
In-text Question 2
Which design pattern do we use whenever we need to associate one object to another?
Answer
The isDone method of the visitor is used to stop the visit method from visiting the other
objects of a container when a success is recorded.
44
2. Suppose we have a container which contains only instances of the Integer
class. Design a Visitor that computes the sum of all the integers in the
container.
3. Using visitors, devise implementations for the isMember and find
methods of the AbstractSearchableContainer class. Using visitors, devise
implementations for the isMember and find methods of the
AbstractSearchableContainer class.
4. Consider the following pair of Associations:
Comparable a=new Association (new Integer(3), new Integer(4));
Comparable b=new Association (new Integer(3));
Give the sequence of methods called in order to evaluate a comparison
such as "a.equals(b)''. Is the result of the comparison true or false?
4.0 Conclusion/Summary
In this study session, you were introduced to some basic design patterns and
their implementations. You have learnt that using these patterns make code to
become even more reusable, more flexible, etc. In the next study session, you
will be introduced to complexity analysis.
5.0 Self-Assessment Questions
1. Which of the patterns that you have studied provides a means to access
one-by-one, all the objects in a container?
2. From what you have learnt so far, design patterns allow us to make
unrelated classes reusable. (True or False)?
45
6.0 Additional Activities (Videos, Animations & Out of Class activities) e.g.
a. Visit U-tube http://bit.ly/33Zay8Y , http://bit.ly/325YXDbm , http://bit.ly/33VbZ8p ,
http://bit.ly/30yUQ1X , http://bit.ly/2PdEF9e , http://bit.ly/32dYO0H , http://bit.ly/33Y6khM .
46
STUDY SESSION 3
Complexity Analysis
Section and Subsection Headings:
Introduction
1.0 Learning Outcomes
2.0 Main Content
2.1: Introduction Complexity Analysis
2.1.1: Motivations for Complexity Analysis
2.1.2: Machine independence
2.1.3: Example of Basic Operations
2.1.4: Best, Average, and Worst case complexities.
2.1.5: Simple Complexity Analysis Examples.
2.2: Asymptotic Complexity
2.2.1: Big-O (asymptotic) Notation
2.2.1.1: Warnings about O-Notation
2.2.2: Big-O Computation Rules
2.2.3: Proving Big-O Complexity
2.2.4: How to determine complexity of code structures
3.0 Tutor Marked Assignments (Individual or Group assignments)
4.0 Study Session Summary and Conclusion
5.0 Self-Assessment Questions and Answers
6.0 Additional Activities (Videos, Animations & Out of Class activities)
7.0 Self-Assessment Question Answers
8.0 References/Further Readings
47
Introduction:
Away from design patterns, you will learn about complexity analysis in this
study session. You will also learn what basic operations are with examples.
Next, you will be introduced to the concept of average, best and worst cases, as
well as some examples of simple complexity analysis. The concluding part of
this study session will introduce you to the Big-O (asymptotic) Notation, how to
prove Big-O complexity and how to determine complexity of code structures.
48
2.1.2 Machine independence
The evaluation of efficiency should be as machine independent as possible. It is
not useful to measure how fast the algorithm runs as this depends on type of
computer, OS, programing language, compiler, and the kinds of input that are
used in testing. Instead,
- We count the number of basic operations the algorithm performs.
- We calculate how this number depends on the size of the input.
A basic operation is an operation which takes a constant amount of time to
execute. Hence, the efficiency of an algorithm is the number of basic operations
it performs. This number is a function of the input size n.
49
2.1.4 Best, Average, and Worst case complexities
It is reasonable to measure an algorithm‟s efficiency as a function of a
parameter indicating the size of the algorithm‟s input. There are a number of
algorithms whose running times depend not only on an input size but also on the
specifics of a particular input. Consider as an example, sequential search. This
is a straightforward algorithm that searches for a given item (some search key
K) in a list of n elements by checking successive elements of the list until either
a match with the search key is found or the list is exhausted. Here is the
algorithm‟s pseudocode, in which, for simplicity, a list is implemented as an
array. It also assumes that the second condition A[i] K will not be checked if
the first one, which checks that the array‟s index does not exceed its upper
bound, fails.
ALGORITHM SequentialSearch(A[0..n − 1], K)
//Searches for a given value in a given array by
sequential search
//Input: An array A[0..n − 1] and a search key K
//Output: The index of the first element in A that
matches K
// or −1 if there are no matching elements
i ←0
while i < n and A[i] K do
i ←i + 1
if i < n return i
else return −1
You can see clearly that, the running time of this algorithm can be quite
different for the same list size n. In the worst case, when there are no matching
elements or the first matching element happens to be the last one on the list, the
algorithm makes the largest number of key comparisons among all possible
inputs of size n: Cworst(n) = n.
The worst-case efficiency of an algorithm is its efficiency for the worst-case
input of size n, which is an input (or inputs) of size n for which the algorithm
runs the longest among all possible inputs of that size. The way to determine the
worst-case efficiency of an algorithm is, in principle, quite straightforward:
50
analyse the algorithm to see what kind of inputs yield the largest value of the
basic operation‟s count C(n) among all possible inputs of size n and then
compute this worst-case value Cworst(n).
The best-case efficiency of an algorithm is its efficiency for the best-case input
of size n, which is an input (or inputs) of size n for which the algorithm runs the
fastest among all possible inputs of that size. Accordingly, we can analyse the
best case efficiency as follows. First, we determine the kind of inputs for which
the count C(n) will be the smallest among all possible inputs of size n. Note that
the best case does not mean the smallest input; it means the input of size n for
which the algorithm runs the fastest.
It should be clear from our discussion, however, that neither the worst-case
analysis nor its best-case counterpart yields the necessary information about an
algorithm‟s behavior on a “typical” or “random” input. This is the information
that the average-case efficiency seeks to provide. To analyse the algorithm‟s
average case efficiency, we must make some assumptions about possible inputs
of size n.
We are usually interested in the worst case complexity, that is, what are the
most operations that might be performed for a given problem size. We usually
focus on worst case analysis because:
- Easier to compute
- Usually close to the actual running time
- Crucial to real-time systems such as air-traffic control, etc.
51
Figure 1.3.1: Best, Worst and Average Case complexities
Selection sort n2 n2
Inserstion sort n2 n2
52
In-text Question 1
What is a basic operation?
Answer
A basic operation is an operation which takes a constant amount of time to execute.
55
Definition of Big-O
Consider a function f(n) that is non-negative n 0. We say that “f(n) is Big-O
of g(n)” i.e., f(n) = O(g(n)), if n0 0 and a constant c > 0 such that f(n)
cg(n), n n0
This definition of Big-O implies that for all sufficiently large n, c *g(n) is an
upper bound of f(n)
Note: By the definition of Big-O: f(n) = 3n + 4 is O(n)
it is also O(n2),
it is also O(n3),
...
it is also O(nn)
However when Big-O notation is used, the function g in the relationship f(n) is
O(g(n)) is chosen to be as small as possible. We call such a function g a tight
asymptotic bound of f(n)
Table 1.3.2 shows some Big-O complexity classes in order of magnitude from
smallest to highest
56
Table 1.3.2: Some Big-O complexity classes in order of magnitude from
smallest to highest
O(1) Constant
O(log(n)) Logarithmic
O(n) Linear
O(n!) Factorial
O(nn)
57
2.2.1.1 Warnings about O-Notation
You should take note of the following about the O – Notation.
- Big-O notation cannot compare algorithms in the same complexity class.
- Big-O notation only gives sensible comparisons of algorithms in different
complexity classes when n is large.
- Consider two algorithms for same task:
Linear: f(n) = 1000 n
Quadratic: f'(n) = n2/1000
The quadratic one is faster for n < 1000000.
2.2.2 Big-O Computation Rules
For large values of input n, the constants and terms with lower degree of n are
ignored.
1. Multiplicative Constants Rule: Ignoring constant factors.
O(c f(n)) = O(f(n)), where c is a constant;
Example:
O(20 n3) = O(n3)
2. Addition Rule: Ignoring smaller terms.
If O(f(n)) < O(h(n)) then O(f(n) + h(n)) = O(h(n)).
Example:
O(n2 log n + n3) = O(n3)
O(2000 n3 + 2n ! + n800 + 10n + 27n log n + 5) = O(n !)
3. Multiplication Rule: O(f(n) * h(n)) = O(f(n)) * O(h(n))
Example:
O((n3 + 2n 2 + 3n log n + 7)(8n 2 + 5n + 2)) = O(n 5)
58
2.2.3 Proving Big-O Complexity
To prove that f(n) is O(g(n)) we find any pair of values n0 and c that satisfy:
f(n) ≤ c * g(n) for n n0
Note: The pair (n0, c) is not unique. If such a pair exists then there is an infinite
number of such pairs.
Example: Prove that f(n) = 3n2 + 5 is O(n2)
We try to find some values of n and c by solving the following inequality:
3n2 + 5 cn2 OR
3 + 5/n2 c
By putting different values for n, we get corresponding values for c
n0 1 2 3 4
Example:
Prove that f(n) = 3n2 + 4n log n + 10 is O(n2) by finding appropriate values for
c and n0
We try to find some values of n and c by solving the following inequality
3n2 + 4n log n + 10 cn2
OR 3 + 4 log n / n+ 10/n2 c
In-text Question 2
The most commonly used notation for specifying asymptotic complexity is the big-O notation.
(True or False)?
Answer
True
59
We used Log of base 2, but another base can be used as well
n0 1 2 3 4
}
i = i*2
O(log n)
60
Sequence of statements: Use Addition rule
O(s1; s2; s3; … sk) = O(s1) + O(s2) + O(s3) + … + O(sk) = O(max(s1, s2, s3, .
. . , sk))
Example:
for (int j = 0; j < n * n; j++)
sum = sum + j;
for (int k = 0; k < n; k++)
sum = sum - l;
System.out.print("sum is now ” + sum);
Complexity is O(n2) + O(n) +O(1) = O(n2)
char key;
int[] X = new int[n];
int[][] Y = new int[n][n];
........
switch(key) {
case 'a':
for(int i = 0; i < X.length; i++)
sum += X[i];
o(n)
break;
case 'b':
2
o(n )
for(int i = 0; i < Y.length; j++)
for(int j = 0; j < Y[0].length; j++)
sum += Y[i][j];
break;
} // End of switch block
61
Sometimes if-else statements must carefully be checked:
O(if-else) = O(Condition)+ Max[O(if), O(else)]
int[] integers = new int[n];
........
if(hasPrimes(integers) == true)
integers[0] = 20; O(1)
else
integers[0] = -20; O(1)
public boolean hasPrimes(int[] arr) {
for(int i = 0; i < arr.length; i++)
..........
O(if-else) = O(Condition)
.......... =O(n) O(n)
} // End of hasPrimes()
Note: Sometimes a loop may cause the if-else rule not to be applicable.
Consider the following loop:
while (n > 0) {
if (n % 2 = = 0) {
System.out.println(n);
n = n / 2;
} else{
System.out.println(n);
System.out.println(n);
n = n – 1;
}
}
The else-branch has more basic operations; therefore one may conclude that the
loop is O(n). However the if-branch dominates. For example if n is 60, then the
sequence of n is: 60, 30, 15, 14, 7, 6, 3, 2, 1, and 0. Hence, the loop is
logarithmic and its complexity is O(log n).
62
2. Use the informal definitions of to determine whether the
following assertions are true or false.
a. n(n + 1)/2 ∈ O(n3)
b. n(n + 1)/2 ∈ O(n2)
c. n(n + 1)/2 ∈ (n3)
d. n(n + 1)/2 ∈ (n)
3. List the following functions according to their order of growth from the
4.0 Conclusion/Summary
In this study session, you were introduced to complexity analysis. You learnt
what basic operations are and some examples. You were also introduced to the
concept of average, best and worst cases, as well as some examples of simple
complexity analysis. The concluding part of the study session introduced you to
63
the Big-O (asymptotic) Notation, how to prove Big-O complexity and how to
determine complexity of code structures. In the next study session, you will be
introduced to linked lists.
6.0 Additional Activities (Videos, Animations & Out of Class activities) e.g.
a. Visit U-tube http://bit.ly/2ZkJtxx , http://bit.ly/2zbO71O, http://bit.ly/2ZoLvbD ,
http://bit.ly/2MDWQ5I, http://bit.ly/2PcWUeR , http://bit.ly/2zljMho , http://bit.ly/2U2QIoF
64
8.0 References/Further Readings
Adam D., “Data Structures and Algorithms in Java”, 2nd Edition,
Thomson Learning, ISBN 0-534-49252-5.
Anany L., “Introduction to the Design and Analysis of Algorithms”,
3rd Edition, Pearson Education, Inc., 20012.
Bruno R. P., “Data Structures and Algorithms with Object Oriented
Design Patterns in Java”, John Wiley & Sons, Inc., 2000.
65
STUDY SESSION 4
Linked Lists
Section and Subsection Headings:
Introduction
1.0 Learning Outcomes
2.0 Main Content
2.1 - What is a List Data Structure?
2.2 - Elements of a List
2.3 - Operations on Lists
2.4 - Singly Linked Lists
2.4.1 - Representation
2.4.2 - Space Analysis
2.5 - Operations on Singly Linked Lists
2.5.1 - Creation and Insertion
2.5.1.1 - Insertion at the end (Append)
2.5.1.2 - Insertion at the beginning (Prepend)
2.5.1.3 - Insertion before and after an element
2.5.2 - Traversal
2.5.3 - Searching
2.5.4 - Deletion
2.5.4.1 - Deletion - Difference between the MyLinkedList and
the Element extracts
2.5.4.2 - Deletion – Deleting First and Last Element
2.6- Doubly Linked Lists
2.6.1- Doubly linked lists: Representation
2.6.2- Doubly Linked Lists: Space Analysis
2.7- Operations on doubly Linked Lists
2.7.1- Creation and Insertion
2.7.1.1- Insertion at the end (Append)
66
2.7.1.2- Insertion at the beginning (Prepend)
2.7.1.3- Insertion before an element
2.7.2- Traversal
2.7.3- Deletion
3.0 Tutor Marked Assignments (Individual or Group assignments)
4.0 Study Session Summary and Conclusion
5.0 Self-Assessment Questions and Answers
6.0 Additional Activities (Videos, Animations & Out of Class activities)
7.0 Self-Assessment Question Answers
8.0 References/Further Readings
Introduction
What you will learn in this study session borders on Lists, their operations and
implementations. Typical examples are given to facilitate your understanding of
these features.
67
2.2 Elements of a List
Let us take a look at how the sentence “Dupe is not a boy” can be written as „a
list‟.
68
Okay, now it is time for us to see the different types of lists we have, how we
represent them, their space analysis and how to perfrom some of the operations
we have just outlined on them. Let us get started.
2.4 Singly Linked Lists
A singly linked list is a data structure in which the data items are chained
(linked) in one direction. Figure 2 shows an example of a singly linked list.
list head
tail
Figure 1.4.2: A singly linked list
2.4.1 Representation
In representing a singly linked list, we will be using a representation in which a
linked list has both head and tail references.
public class MyLinkedList{
protected Element head;
protected Element tail;
public final class Element{
Object data;
Element next;
Element(Object obj, Element element){
data = obj;
next = element;
}
public Object getData(){return data;}
public Element getNext(){return next;}
}
}
2.4.2 Space Analysis
Now, we can take a look at the space requirements for a singly linked list:
S(n) = sizeof(MyLinkedList) + n sizeof(MyLinkedList.Element)
= 2 sizeof(MyLinkedList.Element ref) + n [sizeof(Object ref) +
sizeof(MyLinkedList.Element ref)]
= (n + 2) sizeof(MyLinkedList.Element ref) + n sizeof(Object ref)
69
Space Required Explanation
head
tail
Once created, elements can be inserted into the list using either the append or
prepend methods.
for (int k = 0; k < 10; k++)
list.append(new Integer(k));
70
public void append(Object obj){
Element element = new Element(obj, null);
if(head == null)
head = element;
else
tail.next = element;
tail = element;
} Complexity is O(1)
The figures below depict insertion at the end of a singly linked list.
Figure 1.4.3(a): Insertion at the end of list Figure 1.4.3(b): Insertion at the end of list
71
Figure 1.4.4(a): Insertion at the beginning of list
2.5.2 Traversal
To move a reference e from one node to the next, we use:
e = e.next;
72
Example: Count the number of nodes in a linked list.
public int countNodes(){
int count = 0;
Element e = head;
while(e != null){ Complexity is O(n)
count++;
e = e.next;
}
return count;
}
In-text Question 1
If we have reference to an element in a list, then we can insert a new element before or after
it. (True of False)?
Answer
True
2.5.3 Searching
To search for an element, we traverse from head until we locate the object.
Example: Count the number of nodes with data field equal to a given object.
2.5.4 Deletion
To delete an element, we use either the extract method of MyLinkedList or that
of the Element inner class.
73
public void extract(Object obj) {
Element element = head;
Element previous = null;
while(element != null && ! element.data.equals(obj)) {
previous = element;
element = element.next;
}
if(element == null) Complexity is O(n)
throw new IllegalArgumentException("item not found");
if(element == head)
head = element.next;
else
previous.next = element.next;
if(element == tail)
tail = previous;
}
list head
taillinked list
Figure 1.4.7: A doubly
75
2.6.1 Doubly linked lists: Representation
For each element in a doubly linked list, we represent the data it carries, and a
reference to the previous and next elements. The code segment below shows the
representation of a doubly linked list.
public class DoublyLinkedList{
protected Element head, tail;
//. . .
public class Element {
Object data; Element next, previous;
76
2.7 Operations on doubly Linked Lists
2.7.1 Creation and Insertion
An empty doubly linked list is created using the DoublyLinked class from
section 2.6.1 as follows:
DoublyLinkedList list = new DoublyLinkedList();
head
tail
Like singly link list, once Created, elements can be inserted into the list using
either the append or prepend methods.
for (int k = 0; k < 10; k++)
list.append(new Int(k));
Also, if we have reference to a node (an element), we can use insertAfter or
InsertBefore of the Element class.
2.7.1.1 Insertion at the end (Append)
The new element is always added after the last element of the given Linked
List. For example, if the given doubly linked list is 510152025 and we add an
element 30 at the end, then the list becomes 51015202530. Since a Linked List
is typically represented by the head of it, we have to traverse the list till the end
and then change the last elements to a new element. The code segment below
describes how to add an element at end of a doubly linked list
public void append(Object obj){
Element element = new Element(obj, null, tail);
if(head == null)
head = tail = element;
else {
tail.next = element;
tail = element;
}
}
Complexity is O(1)
77
Figure 1.4.8 (a): Before Insertion Figure 1.4.8 (b): After Insertion
Figure 1.4.9 (a): Before Insertion Figure 1.4.9 (b): After Insertion
78
Figure 1.4.10 (a): Before Insertion
In-text Question 2
What is the complexity of appending an element to a linked list?
Answer
The complexity of appending an element to a linked list is O(1).
2.7.2 Traversal
For DoublyLinked list, traversal can be done in either direction. Forward,
starting from head, or backward starting from tail. The code segment below
shows how to traverse in both ways.
Element e = head; Element e = tail;
while (e != null) { while (e != null) {
//do something //do something
e = e.next; e = e.previous;
} }
79
Example: The following computes the sum of the last n nodes:
if(head == null)
throw new ListEmptyException();
if(element == null)
throw new IllegalArgumentException("item notComplexity is O(n)
found");
if(element == head) {
head = element.next;
if(element.next != null)
element.next.previous = null;
}else{
element.previous.next = element.next;
if(element.next != null)
element.next.previous = element.previous;
}
if(element == tail)
tail = element.previous;
}
80
3.0 Tutor Marked Assignments (Individual or Group)
1. Mention at least two types of lists.
2. For the MyLinkedList class, implement each of the following methods:
- String toString()
- Element find(Object obj)
- void insertAt(int n) //counting the nodes from 1.
State the complexity of each method.
- Which methods are affected if we do not use the tail reference in
MyLinkedList class.
3. For the DoublyLinkedList class, Implement each of the following
methods and state its complexity.
- String toString()
- Element find(Object obj)
- void ExtractLast()
- void ExtractFirst()
- void ExtractLastN(int n)
4. For the DoublyLinkedList.Element inner class, implement each of the
following methods and state its complexity.
- void insertBefore()
- void insertAfter()
- void extract()
What are the methods of DoublyLinkedList and its Element inner class are more
efficient than those of MyLinkedList class?
4.0 Conclusion/Summary
In this study session, you have learned about linked Lists. You have also been
able to identify the elements of a linked List. You have learnt that linked lists
are of two types, namely, singly linked lists and doubly linked lists. Finally, you
learnt the different operations that could be carried out on linked lists. We
81
introduce stacks and queues in the next study session.
6.0 Additional Activities (Videos, Animations & Out of Class activities) e.g.
a. Visit U-tube http://bit.ly/2Pbi90H, http://bit.ly/2UdSX8R , http://bit.ly/2ME8Y74 ,
http://bit.ly/33ZOZoE , http://bit.ly/2U5ZHp4, http://bit.ly/2ZebDea , http://bit.ly/2MD0M70.
82
Algorithms, New York: McGraw-Hill.
Deitel, H.M. and Deitel, P.J. (1998). C++ How to Program (2nd
Edition), New Jersey: Prentice Hall.
Nell D., Daniel T. J., Chip W., “Object-Oriented Data Structures using Java”,
Jones and Bartlett Publishers, Inc., 2002.
Ford, W. and Topp, W. (2002). Data Structures with C++ Using the
STL (2nd Edition), New Jersey: Prentice Hall.
French C. S. (1992). Computer Science, DP Publications, (4th Edition),
199-217.
Robert L., “Data Structures and Algorithms in Java”, 2nd Edition,
Sams Publishing, 2003.
Shaffer, Clifford A. A. (1998). Practical Introduction to Data Structures
and Algorithm Analysis, Prentice Hall, pp. 77–102.
83
STUDY SESSION 5
Stacks and Queues
Section and Subsection Headings:
Introduction
1.0 Learning Outcomes
2.0 Main Content
2.1- What is a Stack?
2.1.1- Stack Implementations
2.1.1.1- Stack implementation using array.
2.1.1.2- Stack implementation using linked list.
2.1.2- Applications of Stack.
2.1.2.1- Evaluating Postfix Expression
2.2- What is a queue?
2.2.1- Queue Implementations
2.2.1.1 - QueueAsArray Implementation
2.2.1.2 - QueueAsCircularArray Implementation
2.2.1.3 - QueueAsLinkedList Implementation
2.2.2- Applications of Queues.
2.2.3- Priority queues
3.0 Tutor Marked Assignments (Individual or Group assignments)
4.0 Study Session Summary and Conclusion
5.0 Self-Assessment Questions and Answers
6.0 Additional Activities (Videos, Animations & Out of Class activities)
7.0 Self-Assessment Question Answers
8.0 References/Further Readings
84
Introduction:
In this study session, we will look at two data structures – the stack and the
queue data structures. While the stack stores data on the basis of Last in First
out (LIFO), the queue stores data on the basis of First in First out (FIFO).
We shall study the operations of these data structures, their applications, as well
as their implementations using arrays and linked lists.
85
Figure 1.5.1: An example of a Stack
86
StackAsArray – Constructor
In the StackAsArray implementation that follows, the top of the stack is
array[count – 1] (where count is the number of elements in the array) and the
bottom is array[0]. The constructor‟s single parameter, size, specifies the
maximum number of items that can be stored in the stack. The variable array is
initialised to be an array of length size as shown in the code fragment below.
public class StackAsArray extends AbstractContainer
implements Stack {
protected Object[] array;
public StackAsArray(int size){
array = new Object[size];
}
// …
87
StackAsArray – pop() Method
The pop method removes an item from the stack and returns that item. The pop
method first checks if the stack is empty. If the stack is empty, it throws a
ContainerEmptyException. Otherwise, it simply decreases count by one and
returns the item found at the top of the stack. The code fragment below shows
how to pop an object from a stack.
88
public Iterator iterator() {
return new Iterator() {
private int position = count-1;
public boolean hasNext() {
return position >=0;
}
public Object next () {
if(position < 0)
throw new NoSuchElementException();
else
return array[position--];
}
};
}
2.1.1.2 Stack implementation using linked list
For the StackAsLinkedList implementation, the underlying data structure is an
object of MyLinkedList. We have described what the various methods of the
stack achieve; therefore, we only provide their implementations here.
public StackAsLinkedList(){
list = new MyLinkedList();
}
public void purge(){
list.purge();
count = 0; Complexity is O(1)
}
// …
89
public void push(Object obj){
list.prepend(obj);
count++; Complexity is O(1)
}
public Object pop(){
if(count == 0)
throw new ContainerEmptyException();
else{
Object obj = list.getFirst();
list.extractFirst();
count--;
Complexity is O(1)
return obj;
}
}
public Object getTop(){
if(count == 0)
throw new ContainerEmptyException();
else Complexity is O(1)
return list.getFirst();
}
90
2.1.2 Applications of Stack
Let us now outline some applications some direct applications are which I am
quite sure are very familiar to you. They are:
- Page-visited history in a Web browser
- Undo sequence in a text editor
- Chain of method calls in the Java Virtual Machine
- Evaluating postfix expressions
Some indirect applications are:
- Auxiliary data structure for some algorithms
- Component of other data structures
91
Table 1.5.1: Infix expressions with postfix equivalent
Infix Postfix
16 / 2 16 2 /
(2 + 14)* 5 2 14 + 5 *
2 + 14 * 5 2 14 5 * +
(6 – 2) * (5 + 4) 6 2 - 5 4 +*
Pop the only one number from the stack – that‟s the result of the evaluation
Example: Consider the postfix expression, 2 10 + 9 6 - /, which is (2 +
10) / (9 - 6) in infix, the result of which is 12 / 3 = 4.
The following is a trace of the postfix evaluation algorithm for the above.
92
In-text Question 1
A stack is a Last in First Out structure. (True or False)?
Answer
True
Queue operations
Some operations that we can perform on a queue include:
- Enqueue: Adds a new item
- Dequeue: Removes an item
- GetHead: Returns the item at the top of the queue
93
Figure 1.5.3: Example of a queue
2.2.1: Queue Implementations
In our implementation, a queue is a container that extends the
AbstractContainer class and implements the Queue interface below.
public interface Queue extends Container{
public abstract Object getHead();
public abstract void enqueue(Object obj);
public abstract Object dequeue();
}
Now we can have two implementations: QueueAsArray,
QueueAsCircularArray or QueueAsLinkedList as we shall see in the next three
sections.
94
public class QueueAsArray extends AbstractContainer
implements Queue {
protected Object[] array;
protected int rear = 0;
protected int size;
95
public Iterator iterator() {
return new Iterator() {
int index = 0;
public boolean hasNext(){
return index < count;
}
public Object next(){
if(index == count)
throw new NoSuchElementException();
else {
Object obj = array[index++];
return obj;
}
}
};
}
96
Figure 1.4.4(b): Circular queue
We now provide the implementation of a queue as a circular array.
97
public Object getHead(){
if(count == 0) throw new ContainerEmptyException();
else return array[front];
Complexity is O(1)
}
public void enqueue(Object obj){
if(count == size) throw new
ContainerFullException();
else {
array[rear] = obj;
rear = (rear + 1) % size; Complexity is O(1)
count++;
}
}
public Object dequeue(){
if(count == 0)throw new ContainerEmptyException();
else {
Object obj = array[front]; Complexity is O(1)
front = (front + 1) % size;
count--;
return obj;
}
}
public Iterator iterator(){
return new Iterator() {
int index = front;
int counter = 0;
public boolean hasNext(){
return counter < count;
}
public Object next(){
if(counter == count)
throw new NoSuchElementException();
else {
Object obj = array[index];
index = (index + 1) % size;
counter++;
return obj;
}
}
};
}
In-text Question 2
Queues can be used to evaluate postfix expressions. (True or False)?
Answer
False
98
2.2.1.3 QueueAsLinkedList Implementation
We also provide implementation of a queue and its operations using our
MyLinkedList singly linked list class.
public class QueueAsLinkedList extends AbstractContainer
implements Queue {
protected MyLinkedList list;
100
5. Applying the LIFO principle to the third stack S above, what would be
the state of the stack S, after the operation S. POP ( ) is executed?
Illustrate this with a simple diagram.
4.0 Conclusion/Summary
In this study, you have learned about the stack and queue data structures. You
have also been able to understand the basic operations on stacks and queues.
You should also have learnt about the implementation of stacks and queues
using different data structures as well as their application in computing.
6.0 Additional Activities (Videos, Animations & Out of Class activities) e.g.
a. Visit U-tube http://bit.ly/2Lc6l91 , http://bit.ly/341wCiX , http://bit.ly/329fKoZ ,
http://bit.ly/2ZAGrW4 , http://bit.ly/2ZAGrW4 , http://bit.ly/2PoKrVM , http://bit.ly/33W2NAu ,
101
7.0 Self Assessment Question Answers
1. A stack is called a Last in First Out structure because the last element to
be added is always the first element to be removed.
2. A queue is called a First in First out structure because the first item to
be added to the queue is the first to be removed from the queue.
102
STUDY SESSION 6
Recursion
Section and Subsection Headings:
Introduction
1.0 Learning Outcomes
2.0 Main Content
2.1- Review of Recursion
2.1.1- What is a Recursive Method?
2.1.2- The need for Auxiliary (or Helper) Methods
2.1.3- How Recursive Methods work
2.1.4- Tracing of Recursive Methods
2.2- Types of Recursive Methods
2.2.1- Direct and Indirect Recursive Methods
2.2.2- Nested and Non-Nested Recursive Methods
2.2.3- Tail and Non-Tail Recursive Methods
2.2.3.1- Converting tail-recursive method to iterative
2.2.3.2- Why tail recursion?
2.2.4- Converting non-tail to tail recursive method
2.2.5- Linear and Tree Recursive Methods
2.2.6- Excessive Recursion
2.3- More on Recursion
2.3.1- Recursion vs. Iteration
2.3.2- Why Recursion?
2.3.3- Common Errors in Writing Recursive Methods
3.0 Tutor Marked Assignments (Individual or Group assignments)
4.0 Study Session Summary and Conclusion
5.0 Self-Assessment Questions and Answers
6.0 Additional Activities (Videos, Animations & Out of Class activities)
7.0 Self-Assessment Question Answers
103
8.0 References/Further Readings
Introduction:
A recursive method is a method that calls itself either directly or indirectly. In
this study session, we introduce recursion and how it works. You will learn how
to make and trace recursive calls. We shall conclude the study session by
looking at different types of recursive methods, why we need to use recursions
and some common errors that could occur when writing recursion.
105
public long factorial(int x){
if (x < 0)
throw new IllegalArgumentException("Negative
argument");
else
return factorialAuxiliary(x);
}
private long factorialAuxiliary(int x){
if (x == 0)
return 1;
else
return x * factorialAuxiliary(x – 1);
}
The first time the method is called, the parameter low and high must be set to 0
and array.length – 1 respectively. Example:
106
public int binarySearch(int target, int[] array){
return binarySearch(target, array, 0, array.length - 1);
}
private int binarySearch(int target, int[] array, int low,
int high){
if(low > high)
return -1;
else{
int middle = (low + high)/2;
if(array[middle] == target)
return middle;
else if(array[middle] < target)
return binarySearch(target, array, middle + 1,
high);
else
return binarySearch(target, array, low, middle -
1);
}
}
Answer
A recursive method is a method is recursive if it calls itself either directly or indirectly.
108
- The Activation Record is popped entirely from the stack.
Recursion is handled in a similar way. Each recursive call creates a separate
Activation Record as each recursive call completes, its Activation Record is
popped from the stack. Ultimately, control passes back to the calling statement.
109
Figure 1.6.2: Output of the recursive call
import java.io.*;
public class TowersOfHanoi{
public static void main(String[] args) throws IOException
{
BufferedReader stdin =
new BufferedReader(new
InputStreamReader(System.in));
System.out.print("Enter the value of n: " );
int n = Integer.parseInt(stdin.readLine());
hanoi(n, 'A', 'C', 'B');
}
As an example, we draw the recursion tree of the method hanoi for n = = 3 and
determine the output of the above program.
111
Figure 1.6.4: Recursive Tree for tower of Hanoi with three disks
Output of the program is:
A -------> C
A -------> B
C -------> B
A -------> C
B -------> A
B -------> C
A -------> C
112
2.2.1 Direct and Indirect Recursive Methods
A method is directly recursive if it contains an explicit call to itself.
long factorial (int x) {
if (x == 0)
return 1;
else
return x * factorial (x – 1);
}
113
public static double sin(double x){
if(x < 0.0000001)
return x - (x*x*x)/6;
else{
double y = tan(x/3);
return sin(x/3)*((3 - y*y)/(1 + y*y));
}
}
114
2.2.3 Tail and Non-Tail Recursive Methods
A method is tail recursive if in each of its recursive cases it executes one
recursive call and if there are no pending operations after that call.
Example 1:
public static void f1(int n){
System.out.print(n + " ");
if(n > 0)
f1(n - 1);
}
Example 2:
public static void f3(int n){
if(n > 6){
System.out.print(2*n + " ");
f3(n – 2);
} else if(n > 0){
System.out.print(n + " ");
f3(n – 1);
}
}
The following are examples of non-tail recursive methods.
Example 1:
public static void f4(int n){
if (n > 0)
f4(n - 1);
System.out.print(n + " ");
}
After each recursive call there is a pending System.out.print(n + " ") operation.
Example 2:
long factorial(int x) {
if (x == 0)
return 1;
else
return x * factorial(x – 1);
}
After each recursive call there is a pending * operation.
115
Tail recursive method
Corresponding iterative method
public static void f1(int n) { public static void f1(int n) {
System.out.print(n + " "); for( int k = n; k >= 0; k--)
if (n > 0) System.out.print(k + " ");
f1(n - 1); }
}
public static void f3 (int n) {
public static void f3 (int n) {
while (n > 0) {
if (n > 6) {
if (n > 6) {
System.out.print(2*n + " ");
System.out.print(2*n + " ");
f3(n – 2);
n = n – 2;
} else if (n > 0) {
} else if (n > 0) {
System.out.print(n + " ");
System.out.print(n + " ");
f3 (n – 1);
n = n – 1;
}
}
}
}
}
116
method. This is simply to keep the syntax clean and to hide the fact that
auxiliary parameters are needed.
Example 1: Converting non-tail recursive factorial to tail-recursive factorial
long factorial (int n) {
if (n == 0)
return 1;
else
return n * factorial (n – 1);
}
118
2.2.6 Excessive Recursion
A recursive method is excessively recursive if it repeats computations for some
parameter values. Example: The call fib(6) results in two repetitions of f(4).
This in turn results in repetitions of fib(3), fib(2), fib(1) and fib(0):
In-text Question 2
Nested recursion occurs when a method is only defined in terms of itself but it is not used as
one of the parameters. (True/False?)
Answer
False
119
2.3.2 Why Recursion?
Usually recursive algorithms have less code, therefore algorithms can be easier
to write and understand - e.g. Towers of Hanoi. However, avoid using
excessively recursive algorithms even if the code is simple. Sometimes
recursion provides a much simpler solution. Obtaining the same result using
iteration requires complicated coding - e.g. Quicksort, Towers of Hanoi, etc.
Recursive methods provide a very natural mechanism for processing recursive
data structures. A recursive data structure is a data structure that is defined
recursively – e.g. Tree. Functional programing languages such as Clean, FP,
Haskell, Miranda, and SML do not have explicit loop constructs. In these
languages looping is achieved by recursion.
Some recursive algorithms are more efficient than equivalent iterative
algorithms.
Example:
int anotherBadFactorial(int x) {
if(x == 0)
return 1;
else
return x*(x-1)*anotherBadFactorial(x -2);
// When x is odd, we never reach the base case!!
}
2. Post increment and decrement operators must not be used since the
update will not occur until AFTER the method call - infinite recursion.
121
When result is initialized to 0, the method returns 0 for whatever value of the
parameter n. The result returned is that of the final return statement to be
executed. Example: A trace of the call sum(3, 0) is:
4. For each of the following recursive methods, identify the base and
general cases and explain what the method does.
a.
int power(int base, int exponent)
{
if (exponent == 0)
return 1;
else
return (base * power(base, exponent–1));
}
b.
123
int recur(int n)
{
if (n < 0)
return –1;
else if (n < 10)
return 1;
else
return (1 + recur(n / 10);
}
c.
int recur2(int n)
{
if (n < 0)
return –1;
else if (n < 10)
return n;
else
return (n % 10) + recur2(n / 10);
}
4.0 Conclusion/Summary
In this study session, you learnt that a recursive method is a method that calls
itself either directly or indirectly. You were shown how recursion works. You
also learnt how to make and trace recursive calls. The different types of
recursive methods, why we need to use recursions and some common errors that
occur when writing recursion were studied in the concluding part of study
session. In the next study session, we will study how to analyse recursive
algorithms.
124
6.0 Additional Activities (Videos, Animations & Out of Class activities) e.g.
a. Visit U-tube http://bit.ly/30wvulo , http://bit.ly/2PeeWO5 , http://bit.ly/33U1HoZ ,
http://bit.ly/2U3P5a2 , http://bit.ly/2U97Bhp , http://bit.ly/2ZgAYnZ. Watch the video &
summarise in 1 paragraph
b. View the animation on http://bit.ly/2U5iHEj and critique it in the discussion
forum
c. Take a walk and engage any 3 students on how to trace recursive calls; In 2
paragraphs summarise their opinion of the discussed topic. etc.
125
STUDY SESSION 7
Analysis of Recursive Algorithms
Section and Subsection Headings:
Introduction
1.0 Learning Outcomes
2.0 Main Content
2.1 - What is a recurrence relation?
2.2 - Forming Recurrence Relations
2.3 - Solving Recurrence Relations
2.4 - Analysis of Recursive Factorial method
2.5 - Analysis of Recursive Selection Sort
2.6 - Analysis of Recursive Binary Search
2.7 - Analysis of Recursive Towers of Hanoi Algorithm
3.0 Tutor Marked Assignments (Individual or Group assignments)
4.0 Study Session Summary and Conclusion
5.0 Self-Assessment Questions and Answers
6.0 Additional Activities (Videos, Animations & Out of Class activities)
7.0 In-text Question Answers
8.0 Self-Assessment Question Answers
9.0 References/Further Readings
Introduction:
In the last study session of this module, you will study how to analyse recursive
algorithms. In particular, we will introduce recurrence relations, how to form
and solve them. We conclude the session by analysing the algorithm of some
common recursive problems.
126
1.0 Study Session Learning Outcomes
After studying this session, I expect you to be able to:
1. Define and form recurrence relations
2. Solve recurrence relations
3. Analyse recursive algorithms
Example:
The portion of the definition that does not contain T is called the base case of
the recurrence relation; the portion that contains T is called the recurrent or
recursive case. Recurrence relations are useful for expressing the running times
(i.e., the number of basic operations executed) of recursive algorithms.
2.2 Forming Recurrence Relations
For a given recursive method, the base case and the recursive case of its
recurrence relation correspond directly to the base case and the recursive case of
the method.
Example 1: Write the recurrence relation for the following method.
public void f (int n) {
if (n > 0) {
System.out.println(n);
f(n-1);
}
}
127
The base case is reached when n == 0. The method performs one comparison.
Thus, the number of operations when n == 0, T(0), is some constant a.
When n > 0, the method performs two basic operations and then calls itself,
using ONE recursive call, with a parameter n – 1.
Therefore the recurrence relation is:
Answer
False
Iterative Method
Steps:
- Expand the recurrence
- Express the expansion as a summation by plugging the recurrence back
into itself until you see a pattern.
128
- Evaluate the summation
In evaluating the summation, one or more of the following summation formulae
may be used:
Arithmetic series:
Geometric Series:
Harmonic Series:
129
Others:
Let us now look at how to analyse some the recursive methods we previously
discussed.
2.4 Analysis of Recursive Factorial method
Example1: Form and solve the recurrence relation for the running time of
factorial method and hence determine its big-O complexity:
130
2.5 Analysis of Recursive Selection Sort
public static void selectionSort(int[] x) {
selectionSort(x, x.length - 1);}
private static void selectionSort(int[] x, int n) {
int minPos;
if (n > 0) {
minPos = findMinPos(x, n);
swap(x, minPos, n);
selectionSort(x, n - 1);
}
}
private static int findMinPos (int[] x, int n) {
int k = n;
for(int i = 0; i < n; i++)
if(x[i] < x[k]) k = i;
return k;
}
private static void swap(int[] x, int minPos, int n) {
int temp=x[n]; x[n]=x[minPos]; x[minPos]=temp;
}
The findMinPos method is O(n), and swap is O(1), therefore the recurrence
relation for the running time of the selectionSort method is:
T(0) = a
T(n) = T(n – 1) + n + c n > 0
= [T(n-2) +(n-1) + c] + n + c = T(n-2) + (n-1) + n + 2c
= [T(n-3) + (n-2) + c] +(n-1) + n + 2c= T(n-3) + (n-2) + (n-1) + n +
3c
= T(n-4) + (n-3) + (n-2) + (n-1) + n + 4c
= ……
= T(n-k) + (n-k + 1) + (n-k + 2) + …….+ n + kc
When k = n, we have :
131
2.6 Analysis of Recursive Binary Search
public int binarySearch (int target, int[] array,
int low, int high) {
if (low > high)
return -1;
else {
int middle = (low + high)/2;
if (array[middle] == target)
return middle;
else if(array[middle] < target)
return binarySearch(target, array, middle + 1,
high);
else
return binarySearch(target, array, low, middle -
1);
}
}
The recurrence relation for the running time of the method is:
T(1) = a if n = 1 (one element array)
T(n) = T(n / 2) + b if n > 1
Expanding:
T(n) = T(n / 2) + b
= [T(n / 4) + b] + b = T (n / 22) + 2b
= [T(n / 8) + b] + 2b = T(n / 23) + 3b
= ……..
= T( n / 2k) + kb
When n / 2k = 1 n = 2k k = log2 n, we have:
T(n) = T(1) + b log2 n
= a + b log2 n
Therefore, Recursive Binary Search is O(log n)
In-text Question 2
To solve a recurrence relation T(n) we need to derive a closed form of the recurrence
relation. (True or False)?
Answer
True
132
2.7 Analysis of Recursive Towers of Hanoi Algorithm
public static void hanoi(int n, char from, char to, char
temp){
if (n == 1)
System.out.println(from + " --------> " + to);
else{
hanoi(n - 1, from, temp, to);
System.out.println(from + " --------> " + to);
hanoi(n - 1, temp, to, from);
}
}
The recurrence relation for the running time of the method hanoi is:
T(n) = a if n = 1
T(n) = 2T(n - 1) + b if n > 1
Expanding:
T(n) = 2T(n – 1) + b
= 2[2T(n – 2) + b] + b = 22 T(n – 2) + 2b + b
= 22 [2T(n – 3) + b] + 2b + b = 23 T(n – 3) + 22b + 2b + b
= 23 [2T(n – 4) + b] + 22b + 2b + b = 24 T(n – 4) + 23 b + 22b + 21b +
20b
= ……
= 2k T(n – k) + b[2k- 1 + 2k– 2 + . . . 21 + 20]
When k = n – 1, we have:
1. Consider the following recursive algorithm for computing the sum of the
first n cubes: S(n) = 13 + 23 + . . . + n3.
ALGORITHM S(n)
133
//Input: A positive integer n
//Output: The sum of the first n cubes
if n = 1 return 1
else return S(n − 1) + n ∗ n ∗ n
a. Set up and solve a recurrence relation for the number of times the
algorithm‟s basic operation is executed.
b. How does this algorithm compare with the straightforward
nonrecursive algorithm for computing this sum?
134
4.0 Conclusion/Summary
In the last study session of this module, you have studied how to analyse
recursive algorithms. You learnt about recurrence relations, how to form and
solve them. We concluded the study session by analysing the algorithm of some
common recursive problems.
6.0 Additional Activities (Videos, Animations & Out of Class activities) e.g.
a. Visit U-tube http://bit.ly/2MDl2oP , http://bit.ly/2zocdH4 , http://bit.ly/2ZwIc6k ,
135
8.0 References/Further Readings
Adam D., “Data Structures and Algorithms in Java”, 2nd Edition,
Thomson Learning, ISBN 0-534-49252-5.
Anany L., “Introduction to the Design and Analysis of Algorithms”,
3rd Edition, Pearson Education, Inc., 20012.
Bruno R. P., “Data Structures and Algorithms with Object Oriented
Design Patterns in Java”, John Wiley & Sons, Inc., 2000.
136
MODULE 2
Trees
Contents:
Study Session 1: Tree
Study Session 2: Binary Search Tree
Study Session 3: Tree Traversal
Study Session 4: Binary Heap
Study Session 5: AVL Tree
Study Session 6: B-Tree
STUDY SESSION 1
Tree
Section and Subsection Headings:
Introduction
1.0 Learning Outcomes
2.0 Main Content
2.1 - What is a Tree?
2.2 - Tree terminology
2.3 - Why trees?
2.4 - General Trees and its Implementation
2.4.1 - N-ary Trees
2.4.2 - N-ary Trees Implementation
2.5 - Binary trees
2.6 - Binary tree implementation
2.7 - Application of Binary trees
3.0 Tutor Marked Assignments (Individual or Group assignments)
4.0 Study Session Summary and Conclusion
5.0 Self-Assessment Questions and Answers
6.0 Additional Activities (Videos, Animations & Out of Class activities)
137
7.0 In-text Question Answers
8.0 Self-Assessment Question Answers
9.0 References/Further Readings
Introduction:
In the first study session of this module, we shall introduce trees, which are used
to define a parent-child relationship. You will learn more about what trees are as
well as some tree terminologies in this session. We will also look at how to
implement trees. We shall conclude the session by introducing binary trees, its
implementation and applications.
138
Figure 2.1.1: Example of a tree
139
2.2 Tree Terminology
We outline some tree terminologies in the section as follow:
Ordered tree: A tree in which the children of each node are linearly ordered
(usually from left to right).
Ancestor of a node v: Any node, including v itself, on the path from the root to
the node.
Proper ancestor of a node v: Any node, excluding v, on the path from the root
to the node.
140
Figure 2.1.2(d): Some tree terminologies
141
Level (or depth) of a node v: The level of a node is the length of the path from
the root to v.
Height of a node v: The height of a node is the length of the longest path from v
to a leaf node.
- The height of a tree is the height of its root mode.
- By definition, the height of an empty tree is -1.
142
2.4 General Trees and its Implementation
In a general tree, there is no limit to the number of children that a node can
have. In representing a general tree by linked lists:
- Each node has a linked list of the subtrees of that node.
- Each element of the linked list is a subtree of the current node
public class GeneralTree extends AbstractContainer {
protected Object key ;
protected int degree ;
protected MyLinkedList list ;
// . . .
}
Answer
A tree, is a finite set of nodes together with a finite set of directed edges that define parent-
child relationships.
143
2.4.2 N-ary Trees Implementation
The code fragment below shows the implementation of the N-ary tree.
144
Figure 2.1.5: Example showing the growth of a full binary tree
A complete binary tree is either an empty binary tree or a binary tree in which:
1. Each level k, k > 0, other than the last level contains the maximum
number of nodes for that level, that is 2k.
2. The last level may or may not contain the maximum number of nodes.
3. If a slot with a missing node is encountered when scanning the last level
in a left to right direction, then all remaining slots in the level must be
empty.
Thus, every full binary tree is a complete binary tree, but the opposite is not
true.
145
We present the implementation of a binary tree by extending some of our
existing classes. But before then, we present figure 6 below, which is a binary
tree representing the expression a + (b - c) * d
In-text Question 2
Every full binary tree is a complete binary tree, but the opposite is not true. (True or False)?
Answer
True
146
public boolean isEmpty( ){ return key == null ; }
public boolean isLeaf( ){
return ! isEmpty( ) && left.isEmpty( ) &&
right.isEmpty( ) ; }
public Object getKey( ){
if(isEmpty( )) throw new InvalidOperationException( )
;
else return key ;
}
public int getHeight( ){
if(isEmpty( )) return -1 ;
else return 1 + Math.max(left.getHeight( ),
right.getHeight( )) ;
}
public void attachKey(Object obj){
if(! isEmpty( )) throw new InvalidOperationException(
) ;
else{
key = obj ;
left = new BinaryTree( ) ;
right = new BinaryTree( ) ;
}
}
148
b. What are the descendants of node K?
c. What is the maximum possible number of nodes at the level of node
W?
d. What is the maximum possible number of nodes at the level of node
N?
4.0 Conclusion/Summary
In this study session, you learnt about trees and tree terminologies. We also
studied how to implement trees. We concluded the session by introducing
binary trees, its implementation and applications. In the next study session, we
will learn more on binary search trees.
149
5.0 Self-Assessment Questions
1. What do you understand by the term degree of a node?
2. What is a Leaf node?
6.0 Additional Activities (Videos, Animations & Out of Class activities) e.g.
a. Visit U-tube http://bit.ly/33SfqfQ , http://bit.ly/33ZQbbC , http://bit.ly/2U5YIW4 ,
150
STUDY SESSION 2
Binary Search Tree
Section and Subsection Headings:
Introduction
1.0 Learning Outcomes
2.0 Main Content
2.1 - What is a Binary search tree?
2.2 - Why Binary search trees?
2.3 - Binary search tree implementation
2.4 - Insertion in a BST
2.5 - Deletion from a BST
3.0 Tutor Marked Assignments (Individual or Group assignments)
4.0 Study Session Summary and Conclusion
5.0 Self-Assessment Questions and Answers
6.0 Additional Activities (Videos, Animations & Out of Class activities)
7.0 In-text Question Answers
8.0 Self-Assessment Question Answers
9.0 References/Further Readings
Introduction:
In this study session, we shall concentrate on binary search trees and why we
need to use them. We shall also study their implementation, and conclude the
session by looking at some of the operations on a binary search tree.
151
2.0 Main Content
2.1 What is a Binary search tree?
A binary search tree (BST) is a binary tree that is empty or that satisfies the
BST ordering property:
1. The key of each node is greater than each key in the left subtree, if any, of
the node.
2. The key of each node is less than each key in the right subtree, if any, of
the node.
Thus, each key in a BST is unique.
Examples:
Answer
True
152
Table 2.2.1: Average case complexities of using linear data structures
compared to BSTs
Data Structure Retrieval Insertion Deletion
O(log n) O(log n) O(log n)
BST
FAST FAST FAST
O(log n) O(n) O(n)
Sorted Array
FAST* SLOW SLOW
O(n) O(n) O(n)
Sorted Linked List
SLOW SLOW SLOW
The find method of the BinarySearchTree class which is used to locate elements
in the binary search tree is implemented as follows:
Similarly, by the BST ordering property, the maximum key is the key of the
right-most node that has an empty right-subtree. The findMax method of the
BinarySearchTree class which is used to find the maximum key in the tree is
implemented as follows:
public Comparable findMax() {
if(isEmpty())
return null;
if(getRightBST().isEmpty())
return (Comparable)getKey();
else
return getRightBST().findMax();
}
In-text Question 2
What is the complexity of searching for a key in a BST?
Answer
O(log n)
154
invoking the attachKey method. The code for the attachKey and insert methods
are shown below:
155
3. The node to be deleted has two non-empty children.
We will treat each case one after the other.
Example:
157
Deletion By Copying: Method 1
Copy the minimum key in the right subtree of x to the node x, then delete the
one-child or leaf-node with this minimum key.
Example:
159
4.0 Conclusion/Summary
In this study session, we introduced binary search trees and why we need to use
them. We studied their implementation and concluded the session by looking at
some of the operations on a binary search tree. In the next study session, we will
study tree traversal.
6.0 Additional Activities (Videos, Animations & Out of Class activities) e.g.
a. Visit U-tube http://bit.ly/2ZpdZCh , http://bit.ly/2KWL1FN , http://bit.ly/2Zsrsgz ,
http://bit.ly/2ZrXntm , http://bit.ly/3207oja , http://bit.ly/2PdLyHC , http://bit.ly/2zm08C3 ,
160
8.0 References/Further Readings
Adam D., “Data Structures and Algorithms in Java”, 2nd Edition,
Thomson Learning, ISBN 0-534-49252-5.
Anany L., “Introduction to the Design and Analysis of Algorithms”,
3rd Edition, Pearson Education, Inc., 20012.
Bruno R. P., “Data Structures and Algorithms with Object Oriented
Design Patterns in Java”, John Wiley & Sons, Inc., 2000.
Nell D., Daniel T. J., Chip W., “Object-Oriented Data Structures using Java”,
Jones and Bartlett Publishers, Inc., 2002.
Robert L., “Data Structures and Algorithms in Java”, 2nd Edition,
Sams Publishing, 2003.
161
STUDY SESSION 3
Tree Traversal
Section and Subsection Headings:
Introduction
1.0 Learning Outcomes
2.0 Main Content
2.1- Tree Traversal
2.2- Binary Tree Traversal classification
2.2.1- BreadthFirst traversal
2.2.2- DepthFirst traversal
2.3 - Accept method of BinaryTree class
2.4 - Binary Tree Iterator
2.4.1 - Using a Binary Tree Iterator
3.0 Tutor Marked Assignments (Individual or Group assignments)
4.0 Study Session Summary and Conclusion
5.0 Self-Assessment Questions and Answers
6.0 Additional Activities (Videos, Animations & Out of Class activities)
7.0 In-text Question Answers
8.0 Self-Assessment Question Answers
9.0 References/Further Readings
Introduction:
In this study session, you will study tree traversals. You will learn the
classification of binary tree traversal and how they work. We will conclude the
session by revisiting the accept and iterator methods from the BinaryTree class
in study session two
162
1.0 Study Session Learning Outcomes
After studying this session, I expect you to be able to:
1. Define tree traversal
2. Outline the classification of tree traversal
3. Traverse trees using any given traversal technique
163
public void breadthFirstTraversal(Visitor visitor){
QueueAsLinkedList queueaslinkedlist =
new QueueAsLinkedList();
if(!isEmpty()) queueaslinkedlist.enqueue(this);
while(!queueaslinkedlist.isEmpty() &&
!visitor.isDone()){
BinaryTree tree =
(BinaryTree)queueaslinkedlist.dequeue();
visitor.visit(tree.getKey());
if (!tree.getLeft().isEmpty())
queueaslinkedlist.enqueue(tree.getLeft());
if (!tree.getRight().isEmpty())
queueaslinkedlist.enqueue(tree.getRight());
}
}
Example:
In-text Question 1
List the two methods used in traversing a tree
Answer
Breadth-First Traversal and Depth-First Traversal
164
Table 2.3.1: Depth-First Search Classification
165
Depth-first Inorder Traversal
You should note that an inorder traversal of a BST visits the keys sorted in
increasing order.
The following code illustrates how to display the contents of a Binary tree using
each traversal method.
Visitor v = new PrintingVisitor() ;
BinaryTree t = new BinaryTree() ;
// . . .
t.breadthFirstTraversal(v) ;
t.preorderTraversal(v) ;
t.inorderTraversal(v) ;
t.postorderTraversal(v) ;
166
2.3 Accept Method of BinaryTree Class
Usually the accept method of a container is allowed to visit the elements of the
container in any order. A depth-first tree traversal visits the nodes in either
preoder or postorder and for Binary trees inorder traversal is also possible. The
BinaryTree class accept method does a preorder traversal:
public void accept(Visitor visitor)
{
preorderTraversal(visitor) ;
}
public BinaryTreeIterator(){
stack = new StackAsLinkedList();
if(!isEmpty())stack.push(BinaryTree.this);
}
In-text Question 2
Postorder traversal of a BST visits the keys sorted in increasing order. (True or False)?
Answer
False
167
2.4.1 Using a Binary Tree Iterator
As shown in the code fragment below, the iterator() method of the BinaryTree
class returns a new instance of the BinaryTreeIterator inner class each time it is
called:
public Iterator iterator(){
return new BinaryTreeIterator();
}
traversal?
b. What is the order in which the nodes are visited by a preorder
traversal?
168
c. What is the order in which the nodes are visited by a postorder
traversal?
2. True or False?
a. A preorder traversal of a binary search tree processes the nodes in
the tree in the exact reverse order that a postorder traversal
processes them.
b. An inorder traversal of a binary search tree always processes the
elements of the tree in the same order, regardless of the order in
which the elements were inserted.
c. A preorder traversal of a binary search tree always processes the
elements of the tree in the same order, regardless of the order in
which the elements were inserted.
4.0 Conclusion/Summary
In this study session, you learnt tree traversals, you also learnt the classification
of binary tree traversal and how they work. We concluded the session by
revisiting the accept and iterator methods from the BinaryTree class. In the next
study session, we will learn about binary heaps.
5.0 Self-Assessment Questions
1. What is tree traversal?
2. Depth-first traversal is categorized into three. List them.
6.0 Additional Activities (Videos, Animations & Out of Class activities) e.g.
a. Visit U-tube add http://bit.ly/2MDlWBJ , http://bit.ly/3419IZl , http://bit.ly/2KUgGYm ,
http://bit.ly/3497bMK , http://bit.ly/31XE78S. Watch the video & summarise in 1
paragraph.
b. View the animation on http://bit.ly/2MD3UQi and critique it in the discussion
forum.
c. Take a walk and engage any 3 students on the categories of depth-first
traversal; In 2 paragraphs summarise their opinion of the discussed topic. etc.
169
7.0 Self Assessment Question Answers
1. The process of systematically visiting all the nodes in a tree and
performing some computation at each node in the tree is called a tree
traversal.
2.
- Preorder traversal
- Inorder traversal (for binary trees only)
- Postorder traversal
170
STUDY SESSION 4
Binary Heap
Section and Subsection Headings:
Introduction
1.0 Learning Outcomes
2.0 Main Content
2.1 - What is a Binary Heap?
2.2 - Array representation of a Binary Heap
2.3 - MinHeap implementation
2.4 - Operations on Binary Heaps
2.4.1 - enqueuer
2.4.2 - dequeuer
2.4.3 - deleting an arbitrary key
2.4.4 - changing the priority of a key
2.5- Building a binary heap
2.5.1 - Top down approach
2.5.2 - bottom up approach
2.6- Heap Applications
2.6.1 - Heap Sort
2.6.2 - Heap as a priority queue
3.0 Tutor Marked Assignments (Individual or Group assignments)
4.0 Study Session Summary and Conclusion
5.0 Self-Assessment Questions and Answers
6.0 Additional Activities (Videos, Animations & Out of Class activities)
7.0 Self-Assessment Question Answers
8.0 References/Further Readings
171
Introduction:
We introduce a type of binary tree called binary heap in this study session. We
will look at what a binary heap is, how to represent binary heap using arrays and
how to implement it. You will study operations on binary heaps, how to build a
heap and conclude the session with applications of binary heaps.
172
Figure 2.4.1: A binary heap
173
MaxHeap and non-MaxHeap examples
174
- The left child, if any, of array[i] is array[2i+1].
- The right child, if any, of array[i] is array[2i+2].
We shall use an implementation in which the heap elements are stored in an
array starting at index 1.
Value(node i ) array[i] , for i > 1
175
public class BinaryHeap extends AbstractContainer
implements PriorityQueue {
protected Comparable array[];
buildHeapBottomUp();
}
The process of swapping an element with its parent in order to restore the heap
order property is called percolate up, sift up, or reheapification upward.
Thus, the steps for enqueue are:
1. Enqueue the key at the end of the heap.
2. As long as the heap order property is violated, percolate up.
176
MinHeap Insertion Example
Answer
True
177
public void enqueue(Comparable comparable){
if(isFull()) throw new ContainerFullException();
2.4.2 Dequeue
To dequeue means to remove a node from the existing tree while maintaining
the MinHeap property of the tree. The pseudo code algorithm for deleting the
root key in a MinHeap is:
1 dequeueMin(){
2 if(Heap is empty) throw an exception ;
3 extract the element from the root ;
4 if(root is a leaf node){ delete root ; return; }
5 copy the element from the last leaf to the root ;
6 delete last leaf ;
7 p = root ;
8 while(p is not a leaf node and p > any of its
children)
9 swap p with the smaller child ;
10 return ;
11 }
The process of swapping an element with its child, in order to restore the heap
order property is called percolate down, sift down, or reheapification
downward.
178
Thus, the steps for deletion are:
1. Replace the key at the root by the key of the last leaf node.
2. Delete the last leaf node.
3. As long as the heap order property is violated, percolate down.
179
MinHeap dequeue Implementation
The code below is the MinHeap dequeue implementation.
public Comparable dequeueMin(){
if(isEmpty()) throw new ContainerEmptyException();
Comparable minItem = array[1];
array[1] = array[count];
count--;
percolateDown(1);
return minItem;
}
private void percolateDown(int hole){
int minChildIndex;
Comparable temp = array[hole];
while(hole * 2 <= count){
minChildIndex = hole * 2;
if(minChildIndex + 1 <= count && array[minChildIndex +
1].
compareTo(array[minChildIndex])<0)
minChildIndex++;
if(array[minChildIndex].compareTo(temp)<0){
array[hole] = array[minChildIndex];
hole = minChildIndex;
} else
break;
}
array[hole] = temp;
}
180
Figure 2.4.6: Deleting an arbitrary key in a MinHeap
Example: Insert the keys 4, 6, 10, 20, and 8 in this order in an originally
empty max-heap
In-text Question 2
The process of swapping an element with its child, in order to restore the heap order
property is called ____________________
Answer
Percolate down, sift down, or reheapification downward.
182
2.5.2 Bottom up approach (Converting an array into a Binary heap)
The algorithm to convert an array into a binary heap is:
1. Start at the level containing the last non-leaf node (i.e., array[n/2], where
n is the array size).
2. Make the subtree rooted at the last non-leaf node into a heap by invoking
percolateDown.
3. Move in the current level from right to left, making each subtree, rooted
at each encountered node, into a heap by invoking percolateDown.
4. If the levels are not finished, move to a lower level then go to step 3.
The above algorithm can be refined to the following method of the BinaryHeap
class:
private void buildHeapBottomUp(){
for(int i = count / 2; i >= 1; i--)
percolateDown(i);
}
183
2.6 Heap Applications
2.6.1 Heap Sort
A MinHeap or a MaxHeap can be used to implement an efficient sorting
algorithm called Heap Sort. The following algorithm uses a MinHeap:
public static void heapSort(Comparable[] array){
BinaryHeap heap = new BinaryHeap(array) ;
for(int i = 0; i < array.length; i++)
array[i] = heap.dequeueMin() ;
}
184
The algorithm for implementing a priority queue using a MinHeap is shown
below.
Heap Heap
1 priorityQueueEnque(e1)
2 {
3 if(priorityQueue is full) throw an exception;
4 insert e1 at the end of the priorityQueue;
5 while(e1 is not in the root node and e1 < parent(e1))
6 swap(e1 , parent(e1));
7 }
1 priorityQueueDequeue(){
2 if(priorityQueue is empty) throw an exception;
3 extract the highest priority element from the root;
4 if(root is a leaf node){ delete root ; return; }
5 copy the element from the last leaf to the root;
6 delete last leaf;
7 p = root;
8 while(p is not a leaf node and p > any of its children)
9 swap p with the smaller child;
10 return;
11 }
185
3.0 Tutor Marked Assignments (Individual or Group)
1. Which of the following trees are heaps?
2. Draw a tree that satisfies both the binary search property and the order
property of heaps.
3. In this study session, we provide the implementation for the MinHeap
enqueue() method. Provide the implementation of the MinHeap
dequeue().
4. We provided an iterative approach for the MinHeap enqueue(). Provide a
recursive equivalent of this method.
4.0 Conclusion/Summary
In this study session, you were introduced to a type of binary tree called binary
heap.You learnt what a binary heap is, how to represent binary heap using
186
arrays and how to implement it. You also studied operations on binary heaps,
how to build a heap and applications of binary heaps. In the next study sessions,
we will learn about another special type of binary search trees called AVL trees.
6.0 Additional Activities (Videos, Animations & Out of Class activities) e.g.
a. Visit U-tube http://bit.ly/326pvE6 , http://bit.ly/2Zfa1Ri , http://bit.ly/2Zfa1Ri ,
http://bit.ly/2U5kqJN , http://bit.ly/2Zp6xeh Watch the video & summarise in 1
paragraph.
b. View the animation on http://bit.ly/2KXxlKw and critique it in the discussion
forum.
c. Take a walk and engage any 3 students on your understanding of MinHeap
and MaxHeap; In 2 paragraphs summarise their opinion of the discussed topic.
etc.
187
8.0 References/Further Readings
Adam D., “Data Structures and Algorithms in Java”, 2nd Edition,
Thomson Learning, ISBN 0-534-49252-5.
Anany L., “Introduction to the Design and Analysis of Algorithms”,
3rd Edition, Pearson Education, Inc., 20012.
Bruno R. P., “Data Structures and Algorithms with Object Oriented
Design Patterns in Java”, John Wiley & Sons, Inc., 2000.
Nell D., Daniel T. J., Chip W., “Object-Oriented Data Structures using Java”,
Jones and Bartlett Publishers, Inc., 2002.
Robert L., “Data Structures and Algorithms in Java”, 2nd Edition,
Sams Publishing, 2003.
188
STUDY SESSION 5
AVL Tree
Section and Subsection Headings:
Introduction
1.0 Learning Outcomes
2.0 Main Content
2.1: AVL Search Trees
2.1.1: What is an AVL Tree?
2.1.2: AVL Tree Implementation.
2.1.3: Why AVL Trees?
2.1.4: Rotations
2.1.4.1 Single Right Rotation
2.1.4.2 Single Left Rotation
2.1.4.3 Double Right-Left Rotation
2.1.4.4 Double Left-Right Rotation
2.1.4.5 Double Rotation Implementation
2.1.4.6 BST ordering property after a rotation
2.2: Inserting in an AVL tree
2.3: AVL Rotation Summary
2.4: Insertion implementation
2.5: Deleting from an AVL tree
3.0 Tutor Marked Assignments (Individual or Group assignments)
4.0 Study Session Summary and Conclusion
5.0 Self-Assessment Questions and Answers
6.0 Additional Activities (Videos, Animations & Out of Class activities)
7.0 Self-Assessment Question Answers
8.0 References/Further Readings
189
Introduction:
An AVL tree is a binary search tree with a balance factor. In this study session,
you will learn about AVL tree, its implementation and the need to use AVL
trees. You will also study some operations on AVL trees such as rotation,
insertion, deletion and implementation of some of these operations.
190
2.1.2 AVL Tree Implementation
As we have seen so far in this course, we build implementation of structures on
existing codes. The AVL tree is a binary search tree; hence, its implementation
builds on the existing binary search tree class, and then introduces the additional
property of an AVL tree, the balance factor. The code segment below shows the
implementation of an AVL tree.
public class AVLTree extends BinarySearchTree{
protected int height;
public AVLTree(){ height = -1;}
public int getHeight(){ return height } ;
protected void adjustHeight(){
if(isEmpty())
height = -1;
else
height = 1 + Math.max(left.getHeight() ,
right.getHeight());
}
protected int getBalanceFactor(){
if( isEmpty())
return 0;
else
return right.getHeight() - left.getHeight();
}
// . . .
}
2.1.4 Rotations
A rotation is a process of switching children and parents among two or three
adjacent nodes to restore balance to a tree.
191
An insertion or deletion may cause an imbalance in an AVL tree. The deepest
node, which is an ancestor of a deleted or an inserted node, and whose balance
factor has changed to -2 or +2 requires rotation to rebalance the tree.
- Left Rotation.
192
2.1.4.1 Single Right Rotation
In a Single right rotation:
- The left child x of a node y becomes y's parent.
- y becomes the right child of x.
- The right child T2 of x, if any, becomes the left child of y.
-
You should note that the pivot of the rotation is the deepest unbalanced node.
Single Right Rotation Implementation
The implementation for a single right rotation is provided below.
protected void rightRotate(){
if( isEmpty()) throw new InvalidOperationException();
BinaryTree temp = right;
right = left;
left = right.left;
right.left = right.right;
right.right = temp;
Object tmpObj = key;
key = right.key;
right.key = tempObj;
getRightAVL().adjustHeight();
adjustHeight();
}
We now show a detailed example of a single right rotation following the
implementation provided above line by line.
193
In-text Question 1
What is an AVL Tree?
Answer
An AVL tree is a binary search tree with a height balance property.
194
Figure 2.5.4(b) Single Right Rotation Example
195
Figure 2.5.4(d) Single Right Rotation Example
196
Figure 2.5.4(f) Single Right Rotation Example
197
Figure 2.5.4(g) Single Right Rotation Example
198
Figure 2.5.4(j) Single Right Rotation Example
199
Just as in the case of a single right rotation, you should also note that the pivot
of the rotation is the deepest unbalanced node.
200
2.1.4.5 Double Rotation Implementation
The following code segment is an implementation for the double right-left and
double left-right rotations discussed in sections 2.4.1.3 and 2.4.1.4 respectively.
1 protected void rotateRightLeft()
2 {
3 if( isEmpty())
4 throw new InvalidOperationException();
5 getRightAVL().rotateRight();
6 rotateLeft();
7 }
1 protected void rotateLeftRight()
2 {
3 if( isEmpty())
4 throw new InvalidOperationException();
5 getLeftAVL().rotateLeft();
6 rotateRight();
7 }
Answer
False
201
2.2 Inserting in an AVL tree
We insert into an AVL tree using the BST insertion algorithm discussed in the
study session on binary search trees. If the insertion causes an imbalance, the
tree is rebalanced. An imbalance occurs if a node's balance factor changes from
-1 to -2 or from+1 to +2. Rebalancing is done at the deepest or lowest
unbalanced ancestor of the inserted node.
There are three insertion cases:
1. Insertion that does not cause an imbalance.
2. Same side (left-left or right-right) insertion that causes an imbalance.
- Requires a single rotation to rebalance.
3. Opposite side (left-right or right-left) insertion that causes an imbalance.
- Requires a double rotation to rebalance.
Insertion: case 1
Example: An insertion that does not cause an imbalance.
Insertion: case 2
Case 2a: The lowest node (with a balance factor of -2) had a taller left-subtree
and the insertion was on the left-subtree of its left child.
It requires single right rotation to rebalance.
202
Figure 2.5.9 (b): Insertion case 2(a)
Case 2b: The lowest node (with a balance factor of +2) had a taller right-
subtree and the insertion was on the right-subtree of its right child.
It requires single left rotation to rebalance.
Insertion: case 3
Case 3a: The lowest node (with a balance factor of -2) had a taller left-subtree
and the insertion was on the right-subtree of its left child.
203
It requires a double left-right rotation to rebalance.
204
2.3 AVL Rotation Summary
Figure 9 below is a summary of scenarios that could lead to an imbalance in an
AVL tree and the type of rotation required to rebalance the tree.
205
The AVLTree class overrides the attachKey method of the BinarySearchTree
class:
public void attachKey(Object obj)
{
if(!isEmpty())
throw new InvalidOperationException();
else
{
key = obj;
left = new AVLTree();
right = new AVLTree();
height = 0;
}
}
206
Deletion case 1 example:
207
Figure 2.5.11(b): Deletion case 2
208
3.0 Tutor Marked Assignments (Individual or Group)
1. Which of the following binary trees are AVL trees?
2. For each of the following lists, construct an AVL tree by inserting their
4.0 Conclusion/Summary
In this study session, you learnt about AVL tree and its properties. You also
learnt about AVL tree implementation and the need to use AVL trees. We
concluded the study session by looking at some operations on AVL trees such
as rotation, insertion, deletion and implementation of some of these operations.
We will study B-Trees in the next study session.
209
6.0 Additional Activities (Videos, Animations & Out of Class activities) e.g.
a. Visit U-tube (http://bit.ly/30BdWVf , http://bit.ly/2ZfeBz7 , http://bit.ly/2ZfeBz7 ,
210
STUDY SESSION 6
B-Trees
Section and Subsection Headings:
Introduction
1.0 Learning Outcomes
2.0 Main Content
2.1- Disk Storage
2.2- What is a multiway tree?
2.2.1- The node structure of a Multi-way tree
2.2.2- Examples of Multi-way Trees
2.3- What is a B-tree?
2.3.1- B-Tree Examples
2.4- Motivation for studying Multi-way and B-trees
2.5- Why B-trees?
2.5.1- Comparing B-Trees with AVL Trees
2.6- Insertion in a B-tree
2.6.1- B-Tree Insertion Algorithm
2.7- Deletion in a B-tree
2.7.1- B-Tree Deletion Algorithm
3.0 Tutor Marked Assignments (Individual or Group assignments)
4.0 Study Session Summary and Conclusion
5.0 Self-Assessment Questions and Answers
6.0 Additional Activities (Videos, Animations & Out of Class activities)
7.0 Self-Assessment Question Answers
8.0 References/Further Readings
211
Introduction:
In the last study session of this module, we shall be looking at multi-way trees
and why we need to use them. Our focus will be on B-Trees. As we have done
in previous study sessions on trees, you will learn about operations on B-Trees
with examples and algorithms for implementing these operations.
212
2.2 What is a Multiway Tree?
A multi-way (or m-way) search tree of order m is a tree in which
- Each node has at most m subtrees, where the subtrees may be empty.
- Each node consists of at least 1 and at most m-1 distinct keys
- The keys in each node are sorted.
213
- Corresponding to each key, there is a data reference that refers to the data
record for that key in secondary memory.
- In our representations, we will omit the data references.
- The literature contains other node representations that we will not
discuss.
214
- Each non-leaf node, other than the root, has at least m/2 non-empty
subtrees and at most m non-empty subtrees. (Note: x is the lowest
integer > x ).
- The number of keys in each non-leaf node is one less than the number of
non-empty subtrees for that node.
- All leaf nodes are at the same level; that is the tree is perfectly balanced.
215
Note that:
- The data references are not shown.
- The leaf references are to empty subtrees
216
for a specific field), called the search key, and quickly finds all records
with that property.
217
Figure 2.6.6: Insertion in a B-tree
218
2.6.1 B-Tree Insertion Algorithm
The algorithm for inserting a key into a B-tree is shown below.
insertKey (x){
if(the key x is in the tree)
throw an appropriate exception;
let the insertion leaf-node be the currentNode;
insert x in its proper location within the node;
219
Key predecessor successor
20 17 25
30 25 32
34 32 40
50 45 53
60 55 64
70 68 75
78 75 88
In-text Question 1
What is a block?
Answer
A block is the smallest amount of data that can be accessed on a disk
220
Underflow Condition: A non-root node of a B-tree of order m underflows if,
after a key deletion, it contains m / 2 - 2 keys
The root node does not underflow. If it contains only one key and this key is
deleted, the tree becomes empty.
Deletion algorithm:
If a node underflows, rotate the appropriate key from the adjacent right- or
left-sibling if the sibling contains at least m / 2 keys; otherwise perform a
merging.
A key rotation must always be attempted before a merging
There are five deletion cases:
1. The leaf does not underflow.
2. The leaf underflows and the adjacent right sibling have at least m / 2
keys.
Perform a left key-rotation
3. The leaf underflows and the adjacent left sibling have at least m / 2 keys.
Perform a right key-rotation
4. The leaf underflows and each of the adjacent right sibling and the adjacent
left sibling has at least m / 2 keys.
Perform either a left or a right key-rotation
5. The leaf underflows and each adjacent sibling has m / 2 - 1 keys.
Perform a merging
221
Case 1: The leaf does not underflow.
Example:
Case 2: The leaf underflows and the adjacent right sibling have at least m /
2 keys.
Perform a left key-rotation:
1. Move the parent key x that separates the siblings to the node with
underflow
2. Move y, the minimum key in the right sibling, to where the key x was
3. Make the old left subtree of y to be the new right subtree of x.
222
Figure 2.6.8(c): Deleting a key from a B-tree
Case 3: The leaf underflows and the adjacent left sibling has at least m /
2 keys.
Perform a right key-rotation:
1. Move the parent key x that separates the siblings to the node with underflow
2. Move w, the maximum key in the left sibling, to where the key x was
3. Make the old right subtree of w to be the new left subtree of x
In-text Question 2
The height h of a B-tree of order m, with a total of n keys, satisfies the inequality _________
Answer
.h <= 1 + log m / 2 ((n + 1) / 2)
Example:
223
Case 5: The leaf underflows and each adjacent sibling has m / 2 - 1 keys.
If the parent of the merged node underflows, the merging process propagates
upward. In the limit, a root with one key is deleted and the height decreases by
one.
Note: The merging could also be done by using the left sibling instead of the
right sibling.
Example:
224
Figure 2.6.8(h): Deleting a key from a B-tree
225
Figure 2.6.8(i): Deleting a key from a B-tree
226
2.7.1 B-Tree Deletion Algorithm
The algorithm for deleting a key from a B-tree is shown below.
deleteKey (x) {
if (the key x to be deleted is not in the tree)
throw an appropriate exception;
if (the tree has only one node) {
delete x ;
return;
}
if (the key x is not in a leaf node)
swap x with its successor or predecessor; // each
will be in a leaf node
delete x from the leaf node;
if(the leaf node does not underflow) // after deletion
numKeys m / 2 - 1
return;
let the leaf node be the CurrentNode;
done = false;
while (! done && numKeys(CurrentNode) m / 2 - 1) { //
there is underflow
if (any of the adjacent siblings t of the CurrentNode
has at least m / 2 keys) { // ROTATION CASE
if (t is the adjacent right sibling) {
• rotate the separating-parent key w of
CurrentNode and t to CurrentNode;
• rotate the minimum key of t to the previous
parent-location of w;
• rotate the left subtree of t, if any, to become
the right-most subtree of CurrentNode;
}
else { // t is the adjacent left sibling
• rotate the separating-parent key w between
CurrentNode and t to CurrentNode;
• rotate the maximum key of t to the previous
parent-location of w;
• rotate the right subtree of t , if any, to
become the left-most subtree of CurrentNode;
}
done = true;
}
else { // MERGING CASE: the adjacent or each
adjacent sibling has m / 2 - 1 keys
select any adjacent sibling t of CurrentNode;
create a new sibling by merging currentNode, the sibling t,
and their parent-separating key ;
If (parent node p is the root node) {
if (p is empty after the merging)
make the merged node the new root;
done = true;
227
} else
let parent p be the CurrentNode;
}
} // while
return;
}
2. Draw the B-tree obtained after inserting 30 and then 31 in the B-tree in
the figure above. Assume that a leaf cannot contain more than three
items.
3. Outline an algorithm for finding the largest key in a B-tree.
4. Write a program implementing a key insertion algorithm in a B-tree.
4.0 Conclusion/Summary
In the last study session of this module, you learnt about multi-way trees and
why we need to use them. We focused on B-Trees and as we did in previous
study sessions on trees, you learnt about operations on B-Trees with examples
and algorithms for implementing these operations. In the next module, we will
study graphs and sorting.
228
inserting a key into a B-tree?
2. Why do we need B-Trees?
6.0 Additional Activities (Videos, Animations & Out of Class activities) e.g.
a. Visit U-tube add http://bit.ly/340haUk , http://bit.ly/340haUk , http://bit.ly/2Hr7DMp,
229
8.0 References/Further Readings
Adam D., “Data Structures and Algorithms in Java”, 2nd Edition,
Thomson Learning, ISBN 0-534-49252-5.
Anany L., “Introduction to the Design and Analysis of Algorithms”,
3rd Edition, Pearson Education, Inc., 20012.
Bruno R. P., “Data Structures and Algorithms with Object Oriented
Design Patterns in Java”, John Wiley & Sons, Inc., 2000.
230
MODULE 3
Graph and Sorting
Contents:
Study Session 1: Huffman Coding
Study Session 2: Graphs
Study Session 3: Topological Sort
Study Session 4: Shortest Path algorithm
Study Session 5: Minimum Spanning Tree
STUDY SESSION 1
Huffman Coding
Section and Subsection Headings:
Introduction
1.0 Learning Outcomes
2.0 Main Content
2.1 - Introduction to Data Compression
2.1.1 - What is Data Compression?
2.1.2 - Why Data Compression?
2.1.3 - How is Data Compression possible?
2.2 - Lossless and Lossy Data Compression
2.2.1- Classification of Lossless Compression Techniques
2.3 - Compression Utilities and Formats
2.4 - Run-length Encoding
2.5 - Static Huffman Coding
2.5.1 - Static Huffman Coding Algorithm
2.6 - The Prefix property
3.0 Tutor Marked Assignments (Individual or Group assignments)
4.0 Study Session Summary and Conclusion
231
5.0 Self-Assessment Questions and Answers
6.0 Additional Activities (Videos, Animations & Out of Class activities)
7.0 In-text Question Answers
8.0 Self-Assessment Question Answers
9.0 References/Further Readings
Introduction:
In the first study session of this module, you will be introduced to data
compression, the need to compress data and how to go about compressing data.
You will also learn the different techniques of compressing data. You will then
be introduced to compression utilities and formats, run-length encoding and
static Huffman coding. We will be concluding the study session by looking at
the prefix property.
232
the fewest number of bits. Compressed data can only be understood if the
decoding method is known by the receiver.
233
- Examples: Run-length, Huffman, LZ77, LZ78, and LZW
Lossy compression reduces a file by permanently eliminating certain redundant
information. They exploit redundancy and human perception and are applied to
audio, image, and video
- Examples: JPEG and MPEG
Lossy techniques usually achieve higher compression rates than lossless ones
but the latter are more accurate.
234
Common image compression formats:
- JPEG, JPEG 2000, BMP, GIF, PCX, PNG, TGA, TIFF, WMP
Common audio (sound) compression formats:
- MPEG-1 Layer III (known as MP3), RealAudio (RA, RAM, RP), AU,
Vorbis, WMA, AIFF, WAVE, G.729a
Common video (sound and image) compression formats:
- MPEG-1, MPEG-2, MPEG-4, DivX, Quicktime (MOV), RealVideo
(RM), Windows Media Video (WMV), Video for Windows (AVI), Flash
video (FLV)
235
0, 10 1, 20 0, 10
0, 40
The first line says that the first line of the bitmap consists of 40 0's. The third
line says that the third line of the bitmap consists of 10 0's followed by 20 1's
followed by 10 more 0's, and so on for the other lines
In-text Question 1
What is data compression?
Answer
Data compression is the representation of an information source (e.g. a data file, a speech
signal, an image, or a video signal) as accurately as possible using the fewest number of bits.
236
}
Assign 0 and 1 weights to the edges of the resulting tree, such that the left and
right edge of each node do not have the same weight; // 3
Note: The Huffman code tree for a particular set of characters is not unique.
(Steps 1, 2, and 3 may be done differently).
Example: Information to be transmitted over the internet contains the following
characters with their associated frequencies:
237
Figure 3.1.1(a): Static Huffman Coding
238
Figure 3.1.1(b): Static Huffman Coding
239
Figure 3.1.1(c): Static Huffman Coding
If we assume the message consists of only the characters a,e,l,n,o,s,t then the
number of bits for the compressed message will be 696:
240
If the message is sent uncompressed with 8-bit ASCII representation for the
characters, we have 261*8 = 2088 bits.
Assuming that the number of character-codeword pairs and the pairs are
included at the beginning of the binary file containing the compressed message
in the following format:
241
2.6 The Prefix property
Data encoded using Huffman coding is uniquely decodable. This is because
Huffman codes satisfy an important property called the prefix property. In a
given set of Huffman codewords, no codeword is a prefix of another Huffman
codeword. For example, in a given set of Huffman codewords, 10 and 101
cannot simultaneously be valid Huffman codewords because the first is a prefix
of the second. We can see by inspection that the codewords we generated in the
previous example are valid Huffman codewords.
To see why the prefix property is essential, consider the codewords given below
in which “e” is encoded with 110 which is a prefix of “f”
242
Answer: Decode a bit-stream by starting at the root and proceeding down the
tree according to the bits in the message (0 = left, 1 = right). When a leaf is
encountered, output the character at that leaf and restart at the root .If a leaf
cannot be reached, the bit-stream cannot be decoded.
(a) 0110011101000 => lost
(b) 11101110101011 => The decoding fails in this case because the
corresponding node for 11 is not a leaf
In-text Question 2
The Huffman code tree for a particular set of characters is unique. (True or False)?
Answer
False
243
4. Write a Java program that implements the Huffman coding algorithm.
4.0 Conclusion/Summary
In this study session, you were introduced to data compression, the need to
compress data and how to go about compressing data. You also learnt the
different techniques to compress data. You were then introduced to compression
utilities and formats, run-length encoding and static Huffman coding. We
concluded the study session by looking at the prefix property. In the next study
session, you will learn about graphs.
6.0 Additional Activities (Videos, Animations & Out of Class activities) e.g.
a. Visit U-tube http://bit.ly/2KWfKCS , http://bit.ly/2HnJVR5 , http://bit.ly/2HnJVR5 ,
244
8.0 References/Further Readings
Adam D., “Data Structures and Algorithms in Java”, 2nd Edition,
Thomson Learning, ISBN 0-534-49252-5.
Anany L., “Introduction to the Design and Analysis of Algorithms”,
3rd Edition, Pearson Education, Inc., 20012.
Bruno R. P., “Data Structures and Algorithms with Object Oriented
Design Patterns in Java”, John Wiley & Sons, Inc., 2000.
245
STUDY SESSION 2
Graphs
Section and Subsection Headings:
Introduction
1.0 Learning Outcomes
2.0 Main Content
2.1- What is a Graph?
2.2- Some Example applications of Graphs
2.3- Graph Terminologies
2.4- Representation of Graphs
2.4.1- Adjacency Matrix
2.4.2- Adjacency Lists
2.4.3- Simple Lists
2.6- Implementation of Graph
2.6.1- Identification of Classes and Interfaces
2.6.2- Concrete Implementations for Graph
2.7- Graph Traversals
2.7.1- Depth-First Traversals.
2.7.2- Breadth-First Traversal.
2.8- Testing for Connectedness and Cycles
2.8.1- Connectedness of an Undirected Graph
2.8.2- Implementation of Connectedness detection Algorithm.
2.8.3- Connectedness of a Directed Graph
2.8.4- Implementation of Strong Connectedness Algorithm.
2.8.5- Cycles in a Directed Graph.
3.0 Tutor Marked Assignments (Individual or Group assignments)
4.0 Study Session Summary and Conclusion
5.0 Self-Assessment Questions and Answers
6.0 Additional Activities (Videos, Animations & Out of Class activities)
246
7.0 Self-Assessment Question Answers
8.0 References/Further Readings
Introduction:
In this study session, we introduce graphs. Graphs are a generalisation of trees.
You will learn what a graph is, application of graphs and some graph
terminologies. You will also learn different ways of representing graphs. Next,
you will study graph implementation and graph traversals. We conclude this
study session by studying how to test for connectedness and cycles in a graph.
247
Figure 3.2.1: Examples of graph
Path and cycles in a digraph: Paths and cycles in a digraph must move in the
direction specified by the arrow.
Connectedness in a digraph: Connectedness in a digraph can be either strong
or weak.
- Strongly Connected: A digraph is said to be strongly connected if
connected as a digraph - following the arrows.
- Weakly connected: A digraph is said to be weakly connected if the
underlying undirected graph is connected (i.e. ignoring the arrows).
249
Figure 3.2.2(b): Graph terminologies
Emanate: An edge e = (v, w) is said to emanate from v.
- A(v) denotes the set of all edges emanating from v.
Incident: An edge e = (v, w) is said to be incident to w.
- I(w) denote the set of all edges incident to w.
Out-degree: The out-degree of a vertex v is the number of edges emanating
from v -- |A(v)|
In-degree: The in-degree of a vertex v is the number of edges incident to w --
|I(w)|.
250
2.4.1 Adjacency Matrix
An Adjacency Matrix uses a 2-D array of dimension |V|x|V| for edges. (For
vertices, a 1-D array is used). The presence or absence of an edge, (v, w) is
indicated by the entry in row v, column w of the matrix. For an unweighted
graph, boolean values could be used while for a weighted graph, the actual
weights are used.
251
We will represent vertices as a one dimensional array and edges as an array of
linked list (the emanating edges of vertex 1 will be in the list of the first
element, and so on).
252
- Graph
A graph can be represented in different ways (we know three of them).
Accordingly, we use the following six classes.
- AbstractGraph (having the following two inner classes)
• GraphVertex
• GraphEdge
- GraphAsMatrix
- GraphAsArrayLists
- GraphAsLists
Answer
False
254
public interface Graph {
public int getNumberOfEdges();
public int getNumberOfVertices();
public Iterator getVertices();
public Iterator getEdges();
public void addVertex(String label);
public void addVertex(String label, Comparable weight);
public Vertex getVertex(String label);
public int getIndex(Vertex v);// vertices are indexed starting from zero
public void addEdge(String from, String to);
public void addEdge(String from, String to, Comparable weight);
public Edge getEdge(String from, String to);
public boolean isReachable(String from, String to);
public boolean isDirected();
public boolean isWeighted();
public boolean isConnected();
public abstract boolean isStronglyConnected();
public abstract boolean isWeaklyConnected();
public boolean isCyclic();
public void preorderDepthFirstTraversal(Visitor visitor, Vertex start);
public void postorderDepthFirstTraversal(Visitor visitor, Vertex start);
public void breadthFirstTraversal(Visitor visitor, Vertex start);
public abstract int topologicalOrderTraversal(Visitor visitor);
}
255
public boolean isWeighted(){
Iterator p = getEdges();
if(((Edge)p.next()).getWeight() == null) return false;
return true;
}
public Vertex getVertex(String label){
Iterator i = getVertices();
while (i.hasNext()){
Vertex v = (Vertex) i.next();
if (v.getLabel().equals(label)) return v;
}
return null;
}
public Edge getEdge(String from, String to){
Iterator i = getEdges();
while (i.hasNext()){
Edge e = (Edge) i.next();
if (e.getFromVertex().getLabel().equals(from) &&
e.getToVertex().getLabel().equals(to))
return e;
}
return null;
}
public Iterator getEmanatingEdges(Vertex from) {
Iterator i = getEdges();
MyLinkedList emEdges = new MyLinkedList();
while (i.hasNext()){
Edge edge = (Edge) i.next();
if (edge.getFromVertex().equals(from))
emEdges.append(edge);
}
return emEdges.iterator();
}
public Iterator getIncidentEdges(Vertex to) {
Iterator i = getEdges();
MyLinkedList inEdges = new MyLinkedList();
while (i.hasNext()){
Edge edge = (Edge) i.next();
if (edge.getToVertex().equals(to))
inEdges.append(edge);
}
return inEdges.iterator();
}
public int getIndex(Vertex v){ return
getIndex(v.getLabel());}
protected abstract int getIndex(String label);
256
The GraphVertex class
The GraphVertex class is implemented as an inner class:
protected final class GraphVertex implements Vertex {
protected String label; protected Comparable weight;
protected GraphVertex(String s, Comparable w) {
label = s; weight = w;
}
protected GraphVertex(String s) {this(s, null);}
public int compareTo(Object obj) {
return label.compareTo(((GraphVertex)obj).getLabel());
}
public Iterator getIncidentEdges() {
return AbstractGraph.this.getIncidentEdges(this);
}
public Iterator getPredecessors() {
return new Iterator() {
Iterator edges = getIncidentEdges();
public boolean hasNext() {return edges.hasNext();}
public Object next() {
Edge edge = (Edge)edges.next();
return edge.getMate(GraphVertex.this);
}
};
}
} The getEmanatingEdges and getSuccessors
methods are implemented in the same way.
258
public Iterator getVertices(){
return new Iterator(){
int index = 0;
public boolean hasNext(){return index <
numberOfVertices;}
public Object next(){return vertices[index++];}
};
}
public Iterator getEdges() {
return new Iterator(){
int count = 0,i=0,j=0;
public boolean hasNext(){return count <
numberOfEdges;}
public Object next(){
if (count==numberOfEdges) throw new
NoSuchElementException();
while (i<numberOfVertices && j<numberOfVertices &&
edges[i][j]==null){
j++; if (j==numberOfVertices){j=0;i++;}
}
Edge r = edges[i][j];
count++;
// for next call, adust i and j
j++; if (j==numberOfVertices){j=0;i++;}
return r;
}
};
}
259
public class GraphAsLists extends AbstractGraph {
private MyLinkedList listOfVertices, listOfEdges;
public GraphAsLists(boolean directed) {
super(directed);
listOfVertices = new MyLinkedList();
listOfEdges = new MyLinkedList();
}
public void purge() {
listOfVertices.purge();
listOfEdges.purge();
super.purge();
}
public int getIndex(String label){
int index = -1;
MyLinkedList.Element e = listOfVertices.getHead();
while (e != null){
index++;
Vertex v = (Vertex) e.getData();
if (label.equals(v.getLabel())) return index;
e = e.getNext();
}
return -1;
}
260
public void addVertex(String label, Comparable weight){
if (getIndex(label)!=-1)
throw new IllegalArgumentException("Duplicate
vertex");
listOfVertices.append(new GraphVertex(label, weight));
numberOfVertices++;
}
public void addEdge(String from, String to, Comparable
weight){
Vertex fromVertex = getVertex(from);
Vertex toVertex = getVertex(to);
if (fromVertex==null || toVertex==null)
throw new IllegalArgumentException("Vertex not in this
graph");
if (fromVertex == toVertex)
throw new IllegalArgumentException("Loops not
supported");
if (getEdge(from, to)==null){
listOfEdges.append(new GraphEdge(fromVertex, toVertex,
weight));
numberOfEdges++;
if (!isDirected() && getEdge(to, from)==null){
listOfEdges.append(new GraphEdge(toVertex,
fromVertex, weight));
numberOfEdges++;
}
}
}
public Iterator getEdges() {return listOfEdges.iterator();}
public Iterator getVertices(){return
listOfVertices.iterator();}
Implementing GraphAsArrayLists (Adjacency List)
261
public class GraphAsArrayLists extends AbstractGraph {
private int size;
private Vertex[] vertices;
private MyLinkedList[] edges;
public GraphAsArrayLists(int size, boolean directed) {
super(directed);
this.size = size;
vertices = new GraphVertex[size];
edges = new MyLinkedList[size];
for (int i=0;i<size;i++) edges[i] = new
MyLinkedList();
}
// These methods are similar to those in GraphAsMatrix
class
public int getIndex(String label)
public void addVertex(String label, Comparable weight)
public Iterator getVertices()
// These methods will be implemented in the lab
public void purge()
public void addEdge(String from, String to, Comparable
weight)
public Iterator getEdges()
}
262
Note: Adjacent vertices can be pushed in any order; but to obtain a unique
traversal, we will push them in reverse alphabetical order.
Example: Demonstrates depth-first traversal using an explicit stack.
dfsPreorder(v){
visit v;
for(each neighbour w of v)
if(w has not been visited)
dfsPreorder(w);
}
263
private void preorderDepthFirstTraversal(Visitor visitor,
Vertex v, boolean[] visited)
{
if(visitor.isDone())
return;
visitor.visit(v);
visited[getIndex(v)] = true;
Iterator p = v.getSuccessors();
while(p.hasNext()) {
Vertex to = (Vertex) p.next();
if(! visited[getIndex(to)])
preorderDepthFirstTraversal(visitor, to, visited);
}
}
264
public void postorderDepthFirstTraversal(Visitor visitor,
Vertex start)
{
boolean visited[] = new boolean[numberOfVertices];
for(int v = 0; v < numberOfVertices; v++)
visited[v] = false;
postorderDepthFirstTraversal(visitor, start, visited);
}
In-text Question 2
What is the in-degree of a vertex v?
Answer
The in-degree of a vertex v is the number of edges incident to it.
265
Figure 3.2.8: Recursive Postorder Depth-first implementation
Note: Adjacent vertices can be enqueued in any order; but to obtain a unique
traversal, we will enqueue them in alphabetical order.
Example: Demonstrating breadth-first traversal using a queue.
266
Figure 3.2.9: breadth-first traversal
267
2.8 Testing for Connectedness and Cycles
2.8.1 Connectedness of an Undirected Graph
An undirected graph G = (V, E) is connected if there is a path between every
pair of vertices. Although the figure 11 below appears to be two graphs, it is
actually a single graph. Clearly, G is not connected. e.g. no path between A and
D. G consists of two unconnected parts, each of which is a connected sub-graph
--- connected components.
268
2.8.3 Connectedness of a Directed Graph
A directed graph G = (V, E) is strongly connected if there is a directed path
between every pair of vertices. Is the directed graph in figure 12 connected?
G is not strongly connected. No path between any of the vertices in {D, E, F}
However, G is weakly connected since the underlying undirected graph is
connected.
269
In the following graph, after A is visited and removed, all the remaining vertices
have in-degree of one. Thus, a topological order traversal cannot complete. This
is because of the presence of the cycle {B, C, D, B}.
270
4. Write an instance method public Edge minWeightEdge() in one of the
concrete Graph classes that returns the minimum-weight edge. Your
method must throw an appropriate exception if the graph is not weighted.
Your method must not use any Iterator.
5. Write an instance method public int countSpecialEdges() of
AbstractGraph that counts the number of edges in the invoking object
that have starting vertex greater than ending vertex (based on compareTo
method).
271
12.In general, an undirected graph contains one or more connected
components.
a) Devise an algorithm that counts the number of connected
components in a graph.
b) Devise an algorithm that labels the vertices of a graph in such a
way that all the vertices in a given connected component get the
same label and vertices in different connected components get
different labels.
13. Devise an algorithm that takes as input a graph, and a pair of vertices, v
and w, and determines whether w is reachable from v.
4.0 Conclusion/Summary
In this study session, we introduced graphs as a generalisation of trees. You
learnt what a graph is, application of graphs and some graph terminologies. You
also learnt different ways of representing graphs. Next, you studied graph
implementation and graph traversals. We concluded the study session by
studying how to test for connectedness and cycles in a graph. In the next study
session, you will learn about topological sort.
5.0 Self-Assessment Questions
1. What is a graph?
2. When is a graph said to be connected?
6.0 Additional Activities (Videos, Animations & Out of Class activities) e.g.
a. Visit U-tube http://bit.ly/2Zm1nQo , http://bit.ly/2ZrUMQn , http://bit.ly/2KU4uaa,
272
7.0 Self Assessment Question Answers
1. A simple graph G = (V, E) consists of a non-empty set V, whose
members are called the vertices of G, and a set E of pairs of distinct
vertices from V, called the edges of G.
2. A graph is said to be connected if there is a path from any vertex to
every other vertex in the graph.
8.0References/Further Readings
Adam D., “Data Structures and Algorithms in Java”, 2nd Edition,
Thomson Learning, ISBN 0-534-49252-5.
Anany L., “Introduction to the Design and Analysis of Algorithms”,
3rd Edition, Pearson Education, Inc., 20012.
Bruno R. P., “Data Structures and Algorithms with Object Oriented
Design Patterns in Java”, John Wiley & Sons, Inc., 2000.
273
STUDY SESSION 3
Topological Sort
Section and Subsection Headings:
Introduction
1.0 Learning Outcomes
2.0 Main Content
2.1 - Introduction.
2.2 - Definition of Topological Sort.
2.3 - Topological Sort is Not Unique.
2.4 - Topological Sort Algorithm
2.5 - Implementation of Topological Sort
3.0 Tutor Marked Assignments (Individual or Group assignments)
4.0 Study Session Summary and Conclusion
5.0 Self-Assessment Questions and Answers
6.0 Additional Activities (Videos, Animations & Out of Class activities)
7.0 Self-Assessment Question Answers
8.0 References/Further Readings
Introduction:
There are many problems involving a set of tasks in which some of the tasks
must be done before others. In this study session, we introduce topological sort
as one of the ways of solving these problems. You will learn what topological
sort is, examples and finally its implementation.
274
1.0 Study Session Learning Outcomes
After studying this session, I expect you to be able to:
1. define topological sort
2. demonstrate topological sort
3. Implement topological sort
In-text Question 1
Topological sort is not unique. (True or False)?
Answer
True
276
Topological Sort Example
Demonstrating Topological Sort.
277
BinaryHeap queue = new BinaryHeap(numberOfVertices);
p = getVertices();
while(p.hasNext()){
Vertex v = (Vertex)p.next();
if(inDegree[getIndex(v)] == 0)
queue.enqueue(v);
}
In-text Question 2
In the topological sort algorithm, the first vertex must have in-degree zero. (True or False)?
Answer
True
1. List the order in which the nodes of the directed graph GB are visited by
topological order traversal that starts from vertex A.
2. What kind of DAG has a unique topological sort?
3. Generate a directed graph using the required courses for your major. Now
apply topological sort on the directed graph you obtained.
278
4.0 Conclusion/Summary
In this study session, we introduced topological sort. You also learnt what
topological sort is, examples and finally its implementation. In the next study
session, you will learn about the shortest path problem.
279
8.0 References/Further Readings
Adam D., “Data Structures and Algorithms in Java”, 2nd Edition,
Thomson Learning, ISBN 0-534-49252-5.
Anany L., “Introduction to the Design and Analysis of Algorithms”,
3rd Edition, Pearson Education, Inc., 20012.
Bruno R. P., “Data Structures and Algorithms with Object Oriented
Design Patterns in Java”, John Wiley & Sons, Inc., 2000.
280
STUDY SESSION 4
Shortest Path Algorithm
Section and Subsection Headings:
Introduction
1.0 Learning Outcomes
2.0 Main Content
2.1 - What is the Shortest Path Problem?
2.2 - Is the shortest path problem well defined?
2.3 - The Dijkstra's Algorithm for Shortest Path Problem.
2.4 - Data structures required for Implementating Dijkstra's Algorithm
2.5 - Implementation Dijkstra's Algorithm
3.0 Tutor Marked Assignments (Individual or Group assignments)
4.0 Study Session Summary and Conclusion
5.0 Self-Assessment Questions and Answers
6.0 Additional Activities (Videos, Animations & Out of Class activities)
7.0 Self-Assessment Question Answers
8.0 References/Further Readings
Introduction:
Shortest path deals with finding the fastest way to get to a vertex from another
vertex in a weighted graph. In this study session, we introduce the shortest path
algorithm. In particular, you will learn about Dijkstra's Algorithm for shortest
path problem and its implementation.
281
2.0 Main Content
2.1 What is the Shortest Path Problem?
In an edge-weighted graph, the weight of an edge measures the cost of traveling
that edge. For example, in a graph representing a network of airports, the
weights could represent: distance, cost or time. Such a graph could be used to
answer any of the following:
- What is the fastest way to get from A to B?
- Which route from A to B is the least expensive?
- What is the shortest possible distance from A to B?
Each of these questions is an instance of the same problem: The shortest path
problem!
282
A solution can be found even for negative-weight graphs but not for graphs
involving negative cost cycles.
Answer
Shortest path deals with finding the fastest way to get to a vertex from another vertex in a
weighted graph.
283
For each vertex, the algorithm keeps track of its current distance from the
starting vertex and the predecessor on the current path
Example: Trace Dijkstra‟s algorithm starting at vertex B in the graph below:
284
public class Algorithms{
static final class Entry{
boolean known;
int distance;
Vertex predecessor;
Entry(){
known = false;
distance = Integer.MAX_VALUE;
predecessor = null;
}
}
285
public static Graph dijkstrasAlgorithm(Graph g, Vertex
start){
int n = g.getNumberOfVertices();
Entry table[] = new Entry[n];
for(int v = 0; v < n; v++)
table[v] = new Entry();
table[g.getIndex(start)].distance = 0;
PriorityQueue queue = new BinaryHeap(
g.getNumberOfEdges());
queue.enqueue(new Association(new Integer(0), start));
while(!queue.isEmpty()) {
Association association =
(Association)queue.dequeueMin();
Vertex v1 = (Vertex) association.getValue();
int n1 = g.getIndex(v1);
if(!table[n1].known){
table[n1].known = true;
Iterator p = v1.getEmanatingEdges();
while (p.hasNext()){
Edge edge = (Edge) p.next();
Vertex v2 = edge.getMate(v1);
int n2 = g.getIndex(v2);
Integer weight = (Integer) edge.getWeight();
int d = table[n1].distance + weight.intValue();
if(table[n2].distance > d){
table[n2].distance = d;
table[n2].predecessor = v1;
queue.enqueue(new Association(d, v2));
}
}
}
}
it = g.getVertices();
while (it.hasNext()){
Vertex v = (Vertex) it.next();
if (v != start){
String from = v.getLabel();
String to =
table[g.getIndex(v)].predecessor.getLabel();
result.addEdge(from, to);
}
} 286
return result;
}
In-text Question 2
A shortest path solution can be found for graphs involving negative cost cycles. (True or
False)?
Answer
False
4.0 Conclusion/Summary
In this study session, we introduced the shortest path algorithm. You learnt
about Dijkstra's algorithm for shortest path problems, how it works and its
implementation. In the next study session, you will learn about minimum
spanning tree.
287
5.0 Self-Assessment Questions
1. Dijkstra's algorithm solves the single-source shortest path problem for a
non-negative weights graph. (True or False)?
2. Dijkstra's algorithm uses the Entry structure. Mention the three fields an
Entry structure has
6.0 Additional Activities (Videos, Animations & Out of Class activities) e.g.
a. Visit U-tube add http://bit.ly/2MBOyvm , http://bit.ly/2z9zgoQ , http://bit.ly/2PcMVpW ,
288
STUDY SESSION 5
Minimum Spanning Tree
Section and Subsection Headings:
Introduction
1.0 Learning Outcomes
2.0 Main Content
2.1 - What is a Minimum Spanning Tree.
2.2 - Constructing Minimum Spanning Trees.
2.3 - What is a Minimum-Cost Spanning Tree.
2.4 - Applications of Minimum Cost Spanning Trees
2.5 - Prim‟s Algorithm
2.5.1: Implementation of Prim‟s Algorithm
2.6: Kruskal‟s algorithm
2.6.1: Implementation of Kruskal's Algorithm
2.7: Prim‟s and Kruskal‟s Algorithms
3.0 Tutor Marked Assignments (Individual or Group assignments)
4.0 Study Session Summary and Conclusion
5.0 Self-Assessment Questions and Answers
6.0 Additional Activities (Videos, Animations & Out of Class activities)
7.0 Self-Assessment Question Answers
8.0 References/Further Readings
Introduction:
In the last study session of this module, you will learn about minimum spanning
trees and how to construct minimum spanning trees with some examples.
Minimum-cost spanning trees and their applications will also be discussed.
289
1.0 Study Session Learning Outcomes
After studying this session, I expect you to be able to:
1. Define a minimum spanning tree
2. Construct a minimum spanning tree
3. Explain what a minimum-cost spanning tree is
4. Outline applications of minimum-cost spanning tree
290
Figure 3.5.1(a): Graph G Figure 3.5.1(b): spanning tree of G Figure 3.5.1(c): spanning tree of G
291
The graph has two minimum-cost spanning trees, each with a cost of 6:
292
Example: For the graph below, trace Prim‟s algorithm starting at vertex a:
Solution:
In-text Question 1
Any traversal of a connected, undirected graph visits all the vertices in that graph. (True or
False)?
Answer
True
293
public static Graph primsAlgorithm(Graph g, Vertex start){
int n = g.getNumberOfVertices();
Entry table[] = new Entry[n];
for(int v = 0; v < n; v++)
table[v] = new Entry();
table[g.getIndex(start)].distance = 0;
PriorityQueue queue = new BinaryHeap(g.getNumberOfEdges());
queue.enqueue(new Association(new Integer(0), start));
while(!queue.isEmpty()) {
Association association = (Association)queue.dequeueMin();
Vertex v1 = (Vertex) association.getValue();
int n1 = g.getIndex(v1);
if(!table[n1].known){
table[n1].known = true;
Iterator p = v1.getEmanatingEdges();
while (p.hasNext()){
Edge edge = (Edge) p.next();
Vertex v2 = edge.getMate(v1);
int n2 = g.getIndex(v2);
Integer weight = (Integer) edge.getWeight();
int d = weight.intValue();
294
2.6 Kruskal’s Algorithm
Kruskal‟s algorithm also finds the minimum cost spanning tree of a graph by
adding edges one-by-one. The algorithm is shown below:
enqueue edges of G in a queue in increasing order of cost.
T = ;
while(queue is not empty){
dequeue an edge e;
if(e does not create a cycle with edges in T)
add e to T;
}
return T;
Solution
295
public static Graph kruskalsAlgorithm(Graph g){
Graph result = new GraphAsLists(false);
Iterator it = g.getVertices();
while (it.hasNext()){
Vertex v = (Vertex)it.next();
result.addVertex(v.getLabel());
}
PriorityQueue queue = new BinaryHeap(g.getNumberOfEdges());
it = g.getEdges();
while(it.hasNext()){
Edge e = (Edge) it.next();
if (e.getWeight()==null)
throw new IllegalArgumentException("Graph is only,
adds an edge not if it does not
weighted"); create a cycle
queue.enqueue(e);
}
while (!queue.isEmpty()){
Edge e = (Edge) queue.dequeueMin();
String from = e.getFromVertex().getLabel();
String to = e.getToVertex().getLabel();
if (!result.isReachable(from, to))
result.addEdge(from,to,e.getWeight());
}
return result;
}
296
For example for the graph:
The same tree is generated by Prim's algorithm if the start vertex is any of: A, B,
or D; however if the start vertex is C the minimum cost spanning tree is:
In-text Question 2
Prim's and Kruskal's algorithm always generate the same minimum-cost spanning tree. (True
or False)?
Answer
False
1. Find the breadth-first spanning tree and depth-first spanning tree of the
graph GA shown above.
297
2. For the graph GB shown above, trace the execution of Prim's algorithm
as it finds the minimum-cost spanning tree of the graph starting from
vertex a.
3. Repeat question 2 above using Kruskal's algorithm.
4.0 Conclusion/Summary
In the last study session of this module, you learnt about minimum spanning
trees. You learnt how to construct minimum spanning trees and some examples.
Minimum-cost spanning trees and their applications was also be discussed. In
the final module of this course, you will be introduced to hashing.
6.0 Additional Activities (Videos, Animations & Out of Class activities) e.g.
a. Visit U-tube http://bit.ly/2L6NvjT , http://bit.ly/30Bvdxt , http://bit.ly/2U67xiE ,
298
2. True
299
MODULE 4
Hashing
Contents:
Study Session 1: Hashing
Study Session 2: Lempel-Ziv Compression Techniques
Study Session 3: Garbage Collection
Study Session 4: Memory Management
STUDY SESSION 1
Hashing
Section and Subsection Headings:
Introduction
1.0 Learning Outcomes
2.0 Main Content
2.1 - Introduction to Hashing and Hashing Techniques
2.1.1 - Review of Searching Techniques
2.1.2 - Introduction to Hashing
2.1.3 - Hash Tables
2.1.4 - Types of Hashing
2.1.5 - Hash Functions
2.1.6 - Applications of Hash Tables
2.1.7 - Problems for which Hash Tables are not suitable
2.2 - Hashing: Collision Resolution Schemes
2.2.1 - Collision Resolution Techniques
2.2.2 - Separate Chaining
2.2.3 - Separate Chaining with String Keys
2.2.4 - Separate Chaining versus Open-addressing
2.2.5 - The class hierarchy of Hash Tables
300
2.2.6 - Implementation of Separate Chaining
2.2.7 - Introduction to Collision Resolution using Open Addressing
2.2.8 - Linear Probing
2.3 - Collision Resolution: Open Addressing
2.3.1 - Quadratic Probing
2.3.2 - Double Hashing
2.3.3 - Rehashing
2.3.4 - Implementation of Open Addressing
3.0 Tutor Marked Assignments (Individual or Group assignments)
4.0 Study Session Summary and Conclusion
5.0 Self-Assessment Questions and Answers
6.0 Additional Activities (Videos, Animations & Out of Class activities)
7.0 Self-Assessment Question Answers
8.0 References/Further Readings
Introduction:
In the first study session of the final module in this course, you will learn about
hashing. We will start by reviewing some search techniques and then go on to
introduce hashing, hash tables, types of hashing, hash functions and applications
of hashing. You will also learn about collision resolution techniques in hashing.
301
6. Discuss collision resolution techniques in hashing
302
Is there some way that we could get O(1) access without wasting a lot of space?
The answer is hashing.
Hashing is based on the idea of distributing keys among a one-dimensional
array H[0..m − 1] called a hash table. The distribution is done by computing,
for each of the keys, the value of some predefined function h called the hash
function. This function assigns an integer between 0 and m − 1, called the hash
address, to a key.
Solution
303
2.1.3 Hash Tables
There are two types of Hash Tables namely Open-addressed Hash Tables and
Separate-Chained Hash Tables.
An Open-addressed Hash Table is a one-dimensional array indexed by integer
values that are computed by an index function called a hash function.
A Separate-Chained Hash Table is a one-dimensional array of linked lists
indexed by integer values that are computed by an index function called a hash
function.
Hash tables are sometimes referred to as scatter tables. Typical hash table
operations are Initialisation, Insertion, Searching and Deletion.
304
location. This situation is called collision and the colliding keys are called
synonyms.
A good hash function should:
- Minimize collisions.
- Be easy and quick to compute.
- Distribute key values evenly in the hash table.
- Use all the information provided in the key.
We will now highlight some common hashing functions. They are as follows:
1. Division Remainder (using the table size as the divisor)
It Computes hash value from key using the % operator. Table size that is
a power of 2 like 32 and 1024 should be avoided, for it leads to more
collisions. Also, powers of 10 are not good for table sizes when the keys
rely on decimal integers. Prime numbers not close to powers of 2 are
better table size values.
2. Truncation or Digit/Character Extraction
It Works based on the distribution of digits or characters in the key. More
evenly distributed digit positions are extracted and used for hashing
purposes. For instance, students IDs or ISBN codes may contain common
subsequences which may increase the likelihood of collision. It is very
fast but digits/characters distribution in keys may not be very even.
3. Folding
It involves splitting keys into two or more parts and then combining the
parts to form the hash addresses. To map the key 25936715 to a range
between 0 and 9999, we can:
- split the number into two as 2593 and 6715 and
- add these two to obtain 9308 as the hash value.
305
It is very useful if we have keys that are very large. It is also fast and
simple especially with bit patterns. A great advantage is ability to
transform non-integer keys into integer values.
4. Radix Conversion
It transforms a key into another number base to obtain the hash value. It
typically uses number bases other than base 10 and base 2 to calculate the
hash addresses. To map the key 55354 in the range 0 to 9999 using base
11 we have:
5535410 = 3865211
We may truncate the high-order 3 to yield 8652 as our hash address
within 0 to 9999.
5. Mid-Square
This hash function squares the key and the middle part of the result taken
as the hash value. To map the key 3121 into a hash table of size 1000, we
square it 31212 = 9740641 and extract 406 as the hash value. It works
well if the keys do not contain a lot of leading or trailing zeros. Non-
integer keys have to be preprocessed to obtain corresponding integer
values.
6. Use of a Random-Number Generator
Given a seed as parameter, this hash function generates a random
number.
The algorithm must ensure that:
• It always generates the same random value for a given key.
• It is unlikely for two keys to yield the same random value.
The random number produced can be transformed to produce a valid hash
value.
306
- Database systems: Specifically, those that require efficient random
access. Generally, database systems try to optimize between two types of
access methods: sequential and random. Hash tables are an important part
of efficient random access because they provide a way to locate data in a
constant amount of time.
- Symbol tables: The tables used by compilers to maintain information
about symbols from a program. Compilers access information about
symbols frequently. Therefore, it is important that symbol tables be
implemented very efficiently.
- Data dictionaries: Data structures that support adding, deleting, and
searching for data. Although the operations of a hash table and a data
dictionary are similar, other data structures may be used to implement
data dictionaries. Using a hash table is particularly efficient.
- Network processing algorithms: Hash tables are fundamental
components of several network processing algorithms and applications,
including route lookup, packet classification, and network monitoring.
- Browser Cashes: Hash tables are used to implement browser cashes.
In-text Question 1
When is collision said to have occur during hashing?
Answer
Collision is a situation in which different keys hash to the same array location.
308
Figure 4.1.1: Separate Chaining
Retrieval of an item, r, with hash address, i, is simply retrieval from the linked
list at position i.
Deletion of an item, r, with hash address, i, is simply deleting r from the linked
list at position i.
Example: Load the keys 23, 13, 21, 14, 7, 8, and 15 , in this order, in a hash
table of size 7 using separate chaining with the hash function: h(key) = key % 7
Solution
h(23) = 23 % 7 = 2
h(13) = 13 % 7 = 6
h(21) = 21 % 7 = 0
h(14) = 14 % 7 = 0 collision
h(7) = 7 % 7 = 0 collision
h(8) = 8 % 7 = 1
h(15) = 15 % 7 = 1 collision
309
2.2.3 Separate Chaining with String Keys
Recall that search keys can be numbers, strings or some other object. A hash
function for a string s = c0c1c2…cn-1 can be defined as:
hash = (c0 + c1 + c2 + … + cn-1) % tableSize
Solution:
310
hash(salt) = (115 + 97 + 108 + 116) % 13 = 436 % 13 = 7
hash(orange) = (111 + 114 + 97 + 110 + 103 + 101)%13 = 636 %13 = 12
()
- hash = [∑ ∗ ( ) ]
311
2.2.4 Separate Chaining versus Open-Addressing
Separate Chaining has several advantages over open addressing. Some of them
are:
- Collision resolution is simple and efficient.
- The hash table can hold more elements without the large performance
deterioration of open addressing (The load factor can be 1 or greater).
- The performance of chaining declines much more slowly than open
addressing.
- Deletion is easy - no special flag values are necessary.
- Table size need not be a prime number.
- The keys of the objects to be hashed need not be unique.
312
2.2.5 The Class Hierarchy of Hash Tables
Figure 4.1.2 below shows the hierarchy tree for implementing hash tables.
314
where hp(key) is another hash function.
Some advantages of Open Addressing are:
- All items are stored in the hash table itself. There is no need for another
data structure.
- Open addressing is more efficient storage-wise.
Disadvantages of Open Addressing are:
- The keys of the objects to be hashed must be distinct.
- Dependent on choosing a proper table size.
- Requires the use of a three-state (Occupied, Empty, or Deleted) flag in
each cell.
315
2.2.8 Linear Probing
In linear probing, c(i) is a linear function in i of the form c(i) = a*i. Usually c(i)
is chosen as:
c(i) = i for i = 0, 1, . . . , tableSize – 1
The probe sequences are then given by:
hi(key) = [h(key) + i] % tableSize for i = 0, 1, . . . , tableSize – 1
For c(i) = a*i to satisfy Property 2, a and n must be relatively prime.
Example: Perform the operations given below, in the given order, on an
initially empty hash table of size 13 using linear probing with c(i) = i and the
hash function: h(key) = key % 13:
insert(18), insert(26), insert(35), insert(9), find(15), find(48), delete(35),
delete(40), find(9), insert(64), insert(47), find(35)
Solution
The required probe sequences are given by:
hi(key) = (h(key) + i) % 13 i = 0, 1, 2, . . ., 12
316
Disadvantage of Linear Probing: Primary Clustering
Linear probing is subject to a primary clustering phenomenon. Elements tend to
cluster around table locations that they originally hash to. Primary clusters can
combine to form larger clusters. This leads to long probe sequences and hence
deterioration in hash table efficiency.
317
2.3 Collision Resolution: Open Addressing
2.3.1 Quadratic Probing
Quadratic probing eliminates primary clusters suffered by linear probing. c(i) is
a quadratic function in i of the form c(i) = a*i2 + b*i. Usually c(i) is chosen as:
c(i) = i2 for i = 0, 1, . . . , tableSize – 1
or
c(i) = i2 for i = 0, 1, . . . , (tableSize – 1) / 2
The probe sequences are then given by:
hi(key) = [h(key) + i2] % tableSize for i = 0, 1, . . . , tableSize – 1
or
hi(key) = [h(key) i2] % tableSize for i = 0, 1, . . . , (tableSize – 1) / 2
Note for Quadratic Probing however:
- Hashtable size should not be an even number; otherwise Property 2 will
not be satisfied.
- Ideally, table size should be a prime of the form 4j+3, where j is an
integer. This choice of table size guarantees Property 2.
Example: Load the keys 23, 13, 21, 14, 7, 8, and 15, in this order, in a hash
table of size 7 using quadratic probing with c(i) = i2 and the hash function:
h(key) = key % 7
Solution
The required probe sequences are given by:
hi(key) = (h(key) i2) % 7 i = 0, 1, 2, 3
h0(23) = (23 % 7) % 7 = 2
h0(13) = (13 % 7) % 7 = 6
h0(21) = (21 % 7) % 7 = 0
h0(14) = (14 % 7) % 7 = 0 collision
2
h1(14) = (0 + 1 ) % 7 = 1
h0(7) = (7 % 7) % 7 = 0 collision
2
h1(7) = (0 + 1 ) % 7 = 1 collision
h-1(7) = (0 - 12) % 7 = -1
NORMALIZE: (-1 + 7) % 7 = 6 collision
h2(7) = (0 + 22) % 7 = 4
318
h0(8) = (8 % 7)%7 = 1 collision
2
h1(8) = (1 + 1 ) % 7 = 2 collision
h-1(8) = (1 - 12) % 7 = 0 collision
h2(8) = (1 + 22) % 7 = 5
h0(15) = (15 % 7)%7 = 1 collision
2
h1(15) = (1 + 1 ) % 7 = 2 collision
h-1(15) = (1 - 12) % 7 = 0 collision
h2(15) = (1 + 22) % 7 = 5 collision
h-2(15) = (1 - 22) % 7 = -3
NORMALIZE: (-3 + 7) % 7 = 4 collision
h3(15) = (1 + 32)%7 = 3
Secondary Clusters
Quadratic probing is better than linear probing because it eliminates primary
clustering. However, it may result in secondary clustering: if h(k1) = h(k2) the
probing sequences for k1 and k2 are exactly the same. This sequence of
locations is called a secondary cluster. Secondary clustering is less harmful than
primary clustering because secondary clusters do not combine to form large
clusters.
Example of Secondary Clustering: Suppose keys k0, k1, k2, k3, and k4 are
inserted in the given order in an originally empty hash table using quadratic
probing with c(i) = i2. Assuming that each of the keys hashes to the same array
index x. A secondary cluster will develop and grow in size:
319
Figure 4.1.5: Primary Clusters Example
320
Example: Load the keys 18, 26, 35, 9, 64, 47, 96, 36, and 70 in this order, in an
empty hash table of size 13
a. using double hashing with the first hash function: h(key) = key % 13 and
the second hash function: hp(key) = 1 + key % 12
b. using double hashing with the first hash function: h(key) = key % 13 and
the second hash function: hp(key) = 7 - key % 7
Solution
321
h0(96) = (96%13)%13 = 5 collision
hp(96) = 7 - 96%7 = 2
h1(96) = (5 + 1*2)%13 = 7
h0(36) = (36%13)%13 = 10
h0(70) = (70%13)%13 = 5 collision
hp(70) = 7 - 70%7 = 7
h1(70) = (5 + 1*7)%13 = 12 collision
h2(70) = (5 + 2*7)%13 = 6
2.3.3 Rehashing
As noted before, with open addressing, if the hash tables become too full,
performance can suffer a lot. So, what can we do? We can double the hash table
size, modify the hash function, and re-insert the data.
More specifically, the new size of the table will be the first prime that is more
than twice as large as the old table size.
In-text Question 2
What is the main disadvantage of Linear probing?
Answer
Primary Clustering.
322
/* finds the index of the first unoccupied slot
in the probe sequence of obj */
protected int findIndexUnoccupied(Comparable obj){
int hashValue = h(obj);
int tableSize = getLength();
int indexDeleted = -1;
for(int i = 0; i < tableSize; i++){
int index = (hashValue + c(i)) % tableSize;
if(array[index].state == OCCUPIED
&& obj.equals(array[index].object))
throw new IllegalArgumentException(
"Error: Duplicate key");
else if(array[index].state == EMPTY ||
(array[index].state == DELETED &&
obj.equals(array[index].object)))
return indexDeleted ==-1?index:indexDeleted;
else if(array[index].state == DELETED &&
indexDeleted == -1)
indexDeleted = index;
}
if(indexDeleted != -1) return indexDeleted;
throw new IllegalArgumentException(
"Error: Hash table is full");
}
protected int findObjectIndex(Comparable obj){
int hashValue = h(obj);
int tableSize = getLength();
for(int i = 0; i < tableSize; i++){
int index = (hashValue + c(i)) % tableSize;
if(array[index].state == EMPTY
|| (array[index].state == DELETED
&& obj.equals(array[index].object)))
return -1;
else if(array[index].state == OCCUPIED
&& obj.equals(array[index].object))
return index;
}
return -1;
}
public Comparable find(Comparable obj){
int index = findObjectIndex(obj);
if(index >= 0)return array[index].object;
else return null;
}
323
public void insert(Comparable obj){
if(count == getLength()) throw new ContainerFullException();
else {
int index = findIndexUnoccupied(obj);
// throws exception if an UNOCCUPIED slot is not found
array[index].state = OCCUPIED;
array[index].object = obj;
count++;
}
}
324
5. Why do prime numbers generally make a good selection for hash table
sizes?
6. Given that,
c(i) = a*i,
for c(i) in linear probing, we discussed that this equation satisfies
Property 2 only when a and n are relatively prime. Explain what the
requirement of being relatively prime means in simple plain language.
7. Consider the general probe sequence,
hi (r) = (h(r) + c(i))% n.
Are we sure that if c(i) satisfies Property 2, then hi(r) will cover all n
hash table locations, 0,1,...,n-1? Explain.
8. Suppose you are given k records to be loaded into a hash table of size n,
with k < n using linear probing. Does the order in which these records are
loaded matter for retrieval and insertion? Explain.
9. A prime number is always the best choice of a hash table size. Is this
statement true or false? Justify your answer either way.
10.If a hash table is 25% full what is its load factor?
11.Given that,
c(i) = i2,
for c(i) in quadratic probing, we discussed that this equation does not
satisfy Property 2, in general. What cells are missed by this probing
formula for a hash table of size 17? Characterise using a formula, if
possible, the cells that are not examined by using this function for a hash
table of size n.
12. It was mentioned in this session that secondary clusters are less harmful
than primary clusters because the former cannot combine to form larger
secondary clusters. Use an appropriate hash table of records to exemplify
this situation.
325
4.0 Conclusion/Summary
In this study session, we looked at hashing. We started by reviewing some
search techniques and then went on to introduce hashing, hash tables, types of
hashing, hash functions and applications of hashing. You also learnt about
collision resolution techniques in hashing. In the next study session, you will
learn about Lempel-Ziv Compression Techniques.
6.0 Additional Activities (Videos, Animations & Out of Class activities) e.g.
a. Visit U-tube http://bit.ly/2Zpk9lT , http://bit.ly/2L8qZXN , http://bit.ly/32efDZp ,
http://bit.ly/2MFqKqm , http://bit.ly/33Ywd0T . Watch the video & summarise in 1
paragraph
b. View the animation on http://bit.ly/32efDZp and critique it in the discussion
forum.
c. Take a walk and engage any 3 students on the different Open Addressing
collision resolution schemes; In 2 paragraphs summarise their opinion of the
discussed topic. etc.
326
- Open Addressing
327
STUDY SESSION 2
Lempel-Ziv Compression Techniques
Section and Subsection Headings:
Introduction
1.0 Learning Outcomes
2.0 Main Content
2.1 - Lempel-Ziv Compression Techniques
2.1.1 - Classification of Lossless Compression techniques
2.1.2 - Introduction to Lempel-Ziv Encoding: LZ77 & LZ78
2.1.2.1 - LZ78 Compression Algorithm
2.2 - Lempel-Ziv-Welch (LZW) Compression Algorithm
2.2.1 - Introduction to the LZW Algorithm
2.2.2 - LZW Encoding Algorithm
2.2.3 - LZW Decoding Algorithm
2.2.4 - LZW Limitations
3.0 Tutor Marked Assignments (Individual or Group assignments)
4.0 Study Session Summary and Conclusion
5.0 Self-Assessment Questions and Answers
6.0 Additional Activities (Videos, Animations & Out of Class activities)
7.0 Self-Assessment Question Answers
8.0 References/Further Readings
Introduction:
Earlier in the course, we studied lossless compression techniques which are
classified into static, adaptive (or dynamic), and hybrid. We also saw some
examples of these techniques. In this study session, you will be introduced to
the Lempel-Ziv encoding. You will learn that this encoding technique consists
of two different algorithms namely LZ77 and LZ78. We will study these
328
algorithms with some examples. You will also learn about Lempel-Ziv-Welch
(LZW) compression algorithm.
329
different method was introduced in1977 by Abraham Lempel and Jacob Ziv.
This technique (called Lempel-Ziv) actually consists of two considerably
different algorithms, LZ77 and LZ78. Due to patents, LZ77 and LZ78 led to
many variants:
Table 4.2.1: Variants of LZ77 and LZ78
The zip and unzip use the LZH technique while UNIX's compress methods
belong to the LZW and LZC classes.
Note that the dictionary is usually implemented as a hash table. The LZ78
compression algorithm is presented below:
Dictionary empty ; Prefix empty ; DictionaryIndex 1;
while(characterStream is not empty)
{
Char next character in characterStream;
330
if(Prefix + Char exists in the Dictionary)
Prefix Prefix + Char ;
else
{
if(Prefix is empty)
CodeWordForPrefix 0 ;
else
CodeWordForPrefix DictionaryIndex for
Prefix ;
Output: (CodeWordForPrefix, Char) ;
insertInDictionary( ( DictionaryIndex , Prefix +
Char) );
DictionaryIndex++ ;
Prefix empty ;
}
}
if(Prefix is not empty)
{
CodeWordForPrefix DictionaryIndex for Prefix;
Output: (CodeWordForPrefix , ) ;
}
Solution
331
Note: The above is just a representation, the commas and parentheses are not
transmitted; we will discuss the actual form of the compressed message later on.
In-text Question 1
Static compression methods requires a single pass. (True or False)?
Answer
False
Example 2: Encode (i.e., compress) the string BABAABRRRA using the LZ78
algorithm.
Solution
332
Figure 4.2.2: LZ78 Compression example 2
The compressed message is: (0,B)(0,A)(1,A)(2,B)(0,R)(5,R)(2, )
1. B is not in the Dictionary; insert it
2. A is not in the Dictionary; insert it
3. B is in the Dictionary.
BA is not in the Dictionary; insert it.
4. A is in the Dictionary.
AB is not in the Dictionary; insert it.
5. R is not in the Dictionary; insert it.
6. R is in the Dictionary.
RR is not in the Dictionary; insert it.
7. A is in the Dictionary and it is the last input character; output a pair
containing its index: (2, )
Example 3: Encode (i.e., compress) the string AAAAAAAAA using the LZ78
algorithm.
Solution
333
Figure 4.2.3: LZ78 Compression example 3
1. A is not in the Dictionary; insert it
2. A is in the Dictionary
AA is not in the Dictionary; insert it
3. A is in the Dictionary.
AA is in the Dictionary.
AAA is not in the Dictionary; insert it.
4. A is in the Dictionary.
AA is in the Dictionary.
AAA is in the Dictionary and it is the last pattern; output a pair containing its
index:
(3, )
334
Alternatively number of bits required to represent the integer part of the
codeword with index i is the number of significant bits required to represent the
integer i – 1
In summary,
- input: (CW, character) pairs
- output:
if(CW == 0)
output: currentCharacter
else
output: stringAtIndex CW + currentCharacter
- Insert: current output in dictionary
Example 4: Decode (i.e., decompress) the sequence (0, A) (0, B) (2, C) (3, A)
(2, A) (4, A) (6, B)
Solution
336
The decompressed message is: BABAABRRRA
Example 6: Decode (i.e., decompress) the sequence (0, A) (1, A) (2, A) (3, )
Solution
337
The patterns are of the form: C0C1 . . . Cn-1Cn. The prefix of a pattern consists of
all the pattern characters except the last: C0C1 . . . Cn-1
LZW output if the message consists of more than one character:
- If the pattern is not the last one; output: The code for its prefix.
- If the pattern is the last one:
i. if the last pattern exists in the Dictionary; output: The code
for the pattern.
ii. If the last pattern does not exist in the Dictionary; output:
code(lastPrefix) then output: code(lastCharacter)
Note: LZW outputs codewords that are 12-bits each. Since there are 212 = 4096
codeword possibilities, the minimum size of the Dictionary is 4096; however
since the Dictionary is usually implemented as a hash table its size is larger than
4096.
338
Solution
1. BA is not in the Dictionary; insert BA, output the code for its prefix: code(B)
2. AB is not in the Dictionary; insert AB, output the code for its prefix: code(A)
3. BA is in the Dictionary.
BAA is not in Dictionary; insert BAA, output the code for its prefix:
code(BA)
4. AB is in the Dictionary.
ABA is not in the Dictionary; insert ABA, output the code for its prefix:
code(AB)
5. AA is not in the Dictionary; insert AA, output the code for its prefix: code(A)
6. AA is in the Dictionary and it is the last pattern; output its code: code(AA)
339
BAA is not in Dictionary; insert BAA, output the code for its prefix:
code(BA)
4. AB is in the Dictionary.
ABR is not in the Dictionary; insert ABR, output the code for its prefix:
code(AB)
5. RR is not in the Dictionary; insert RR, output the code for its prefix: code(R)
6. RR is in the Dictionary.
RRA is not in the Dictionary and it is the last pattern; insert RRA, output
code for its prefix:
code(RR), then output code for last character: code(A)
Initialize Dictionary with 256 ASCII codes and corresponding single character
strings as their translations;
PreviousCodeWord first input code;
Output: string(PreviousCodeWord) ;
Char character(first input code);
CodeWord 256;
while(not end of code stream){
CurrentCodeWord next input code ;
if(CurrentCodeWord exists in the Dictionary)
String string(CurrentCodeWord) ;
else
String string(PreviousCodeWord) + Char ;
Output: String;
Char first character of String ;
insertInDictionary( (CodeWord ,
string(PreviousCodeWord) + Char ) );
PreviousCodeWord CurrentCodeWord ;
CodeWord++ ;
}
In-text Question 2
Which compression algorithm inserts one- or multi-character, non-overlapping, distinct
patterns of the message to be encoded in a dictionary?
Answer
LZ78 Compression Algorithm
341
Summary of LZW decoding algorithm:
output: string(first CodeWord);
while(there are more CodeWords){
if(CurrentCodeWord is in the Dictionary)
output: string(CurrentCodeWord);
else
output: PreviousOutput + PreviousOutput first
character;
insert in the Dictionary: PreviousOutput + CurrentOutput
first character;
}
Example 9: Use LZW to decompress the output sequence <66> <65> <256>
<257> <65> <260>
Solution
342
Example 10: Decode the sequence <67> <70> <256> <258> <259> <257> by
LZW decode algorithm.
Solution
343
3.0 Tutor Marked Assignments (Individual or Group)
1. Use LZ78 to trace encoding the string SATATASACITASA.
2. Write a Java program that encodes a given string using LZ78.
3. Write a Java program that decodes a given set of encoded codewords
using LZ78.
4. Use LZW to trace encoding the string ABRACADABRA.
5. Write a Java program that encodes a given string using LZW.
6. Write a Java program that decodes a given set of encoded codewords
using LZW.
4.0 Conclusion/Summary
In this study session, you were introduced to the Lempel-Ziv encoding. You
learnt that this encoding technique consists of two different algorithms namely
LZ77 and LZ78. You studied these algorithms with some examples. You also
learnt about Lempel-Ziv-Welch (LZW) compression algorithm in the
concluding part of this study session.
344
6.0 Additional Activities (Videos, Animations & Out of Class activities) e.g.
a. Visit U-tube http://bit.ly/2ZsDDpH , http://bit.ly/2PbTCIJ , http://bit.ly/2ZrEnPW ,
345
STUDY SESSION 3
Garbage Collection
Section and Subsection Headings:
Introduction
1.0 Learning Outcomes
2.0 Main Content
2.1- How Objects are created in Java
2.1.1 - How Java Reclaims Objects Memory
2.2 - What is Garbage?
2.2.1 - what is garbage collection?
2.2.2 - Advantages and disadvantages of garbage collection
2.2.3 - Helping the garbage collector
2.3 - Garbage collection schemes
2.3.1 - Reference Counting
2.3.2 - Mark and Sweep
2.3.3 - Stop and Copy
3.0 Tutor Marked Assignments (Individual or Group assignments)
4.0 Study Session Summary and Conclusion
5.0 Self-Assessment Questions and Answers
6.0 Additional Activities (Videos, Animations & Out of Class activities)
7.0 Self-Assessment Question Answers
8.0 References/Further Readings
346
Introduction:
Have you ever wondered how programing languages (Java in our case) handle
unreferenced objects? This study session hence, is an introduction to garbage
collection, with our focus on programing language being Java. Not only will
you be learning what garbage collection is, its advantages and disadvantage will
also be considered. We shall conclude the study session by learning about
garbage collection schemes.
347
The advantages of these are:
- No dangling reference problem in Java
- Easier programing
- No memory leak problem
348
2.2.1 What is garbage collection?
Garbage Collection is the process of finding garbage and reclaiming memory
allocated to it. The reason why garbage collection is done is that the heap space
occupied by an un-referenced object can be recycled and made available for
subsequent new objects. Garbage Collection process is invoked when the total
memory allocated to a Java program exceeds some threshold. Running a
program is affected by garbage collection because the program suspends during
garbage collection.
349
SomeClass obj= new SomeClass(i);
System.out.println(obj);
}
- By using only one object instead and implementing the setInt() method,
we drastically reduce the garbage generated.
SomeClass obj= new SomeClass();
for (int i=0;i< 1000000; ++i) {
obj.setInt(i);
System.out.println(obj);
}
2. Eliminate all references to objects that are no longer needed
- This can be done by assigning null to every variable that refers to an
object that is no longer needed
350
In-text Question 1
Java provides programrs with a means to destroy objects explicitly. (True or False)?
Answer
False
The update of reference field when we have a reference assignment ( i.e p=q)
can be implemented as follows
Example:
Object p = new Integer(57);
Object q= new Integer(99);
p=q
if (p!=q){
if (p!=null)
--p.refCount;
p=q;
if (p!=null)
++p.refCount;
}
351
Here are some pros and cons of the reference counting approach to garbage
collection.
Advantages
1. Conceptually simple: Garbage is easily identified
2. It is easy to implement.
3. Immediate reclamation of storage
4. Objects are not moved in memory during garbage collection.
Disadvantages
1. Reference counting does not detect garbage with cyclic references.
2. The overhead of incrementing and decrementing the reference count each
time.
3. Extra space: A count field is needed in each object.
4. It may increase heap fragmentation.
The pros and cons of the mark and sweep approach are:
Advantages
1. It is able to reclaim garbage that contains cyclic references.
2. There is no overhead in storing and manipulating reference count fields.
352
3. Objects are not moved during GC – no need to update the references to
objects.
Disadvantages
1. It may increase heap fragmentation.
2. It does work proportional to the size of the entire heap.
3. The program must be halted while garbage collection is being performed.
In-text Question 2
_____________ Garbage collection scheme adds a reference count field for every object and
updates this field whenever the number of references to an object changes.
Answer
Reference Counting
353
Figure 4.3.5: A graphical depiction of a garbage-collected heap using stop and copy
approach
The pros and cons of the stop and copy approach are:
Advantages
1. Only one pass through the data is required.
2. It de-fragments the heap.
3. It does work proportional to the amount of live objects and not to the
memory size.
4. It is able to reclaim garbage that contains cyclic references.
5. There is no overhead in storing and manipulating reference count fields.
Disadvantages
1. Twice as much memory is needed for a given amount of heap space.
2. Objects are moved in memory during garbage collection (i.e., references
need to be updated)
The program must be halted while garbage collection is being performed.
354
4. Describe how objects are created in Java.
5. List and explain the ways in which a programr can help the garbage
collector.
6. List and explain the garbage collection schemes we discussed.
4.0 Conclusion/Summary
In this study session you were introduced to garbage collection, with our focus
programing language being Java. You learnt about what garbage collection is,
its advantages and disadvantage. We concluded the study session by learning
about garbage collections schemes.
6.0 Additional Activities (Videos, Animations & Out of Class activities) e.g.
a. Visit U-tube http://bit.ly/2Zx9yJw , http://bit.ly/33VptRz , http://bit.ly/2Pvg9kf,
356
STUDY SESSION 4
Memory Management
Section and Subsection Headings:
Introduction
1.0 Learning Outcomes
2.0 Main Content
2.1 - Memory Areas and their use
2.2 - Memory Manager Tasks
2.3 - Free List
2.3.1 - Free List Implementations
2.3.1.1 - Singly-linked list implementation of free-list
2.3.1.2 - doubly-linked list implementation of free-list
2.3.1.3 - Buddy Systems implementation of free-list
2.3.1.4 - Binary Buddy System implementation of free-list
3.0 Tutor Marked Assignments (Individual or Group assignments)
4.0 Study Session Summary and Conclusion
5.0 Self-Assessment Questions and Answers
6.0 Additional Activities (Videos, Animations & Out of Class activities)
7.0 Self-Assessment Question Answers
8.0 References/Further Readings
Introduction:
In the last study session of this module and this course, we shall study memory
management. You will learn how memories used by programs are allocated.
You will also be briefly introduced to the memory manager and problems faced
by memory allocation. We will conclude this study session by looking at free
lists and the implementation of free lists with examples using different data
structures.
357
1.0 Study Session Learning Outcomes
After studying this session, I expect you to be able to:
1. Explain memory management
2. Describe memory manager and its problems
3. Explain free lists and some common implementations of free lists
4. Outline allocation policies
358
Figure 4.4.1: Memory area
359
Figure 4.4.2: Memory allocation
2. Overhead: Additional memory that must be allocated, above and beyond
that requested by programs, in order to provide for the management of the
heap.
360
2.3.1 Free List Implementations
2.3.1.1 Singly-linked list implementation of free-list
In the singly-linked list implementation of free lists, each node represents a free
block of memory. Nodes must be sorted according to start addresses of free
blocks so that adjacent free memory blocks can be combined.
The acquire( ) and release( ) operations which are used to allocate and release
memory respectively, are O(n), where n is the number of blocks in the heap. In
order to acquire a block, a node is searched following one of the allocation
policy. If the block is bigger than requested, it is divided into two. One part is
allocated and one remains in the list.
In order to release a block, a new node must be inserted (if the adjacent block is
not on the free list) or a node, which contains the adjacent free block, must be
modified. Searching for the place of the new or existing node has complexity
O(n).
361
In-text Question 1
A memory manager is part of the operating system. (True or False)?
Answer
True
Example:
362
Figure 4.4.7: The node corresponding to the freed block
The operation acquire(600) using the first-fit allocation policy will first result
in the combination of the three adjacent free blocks:
Buddies
If each block is of size 8 bytes (i.e., 23 bytes); then the buddy of a block is
obtained by complementing bit 3 of its starting address. If each block is of size
4 bytes (i.e., 22 bytes); then the buddy of a block is obtained by complementing
bit 2 of its starting address.
Example: What is the starting address of the buddy of a block that starts at
address 1100101010101101 if each block is 16 bytes?
Solution: 16 = 24; the starting address of the buddy is obtained by
complementing bit 4: 1100101010111101
364
Figure 4.4.12: Buddies
365
Figure 4.4.13: Binary Buddy System implementation of free-list
366
Buddy Systems Advantages/Disadvantages
Advantage:
- Both acquire( ) and release( ) operations are fast.
Disadvantages:
- Only memory of size that is a power of 2 can be allocated internal
fragmentation if memory request is not a power of 2.
- When a block is released, its buddy may not be free, resulting in external
fragmentation.
In-text Question 2
Highlight the advantage of buddy systems discussed in the study session.
Answer
Both acquire( ) and release( ) operations are fast.
4.0 Conclusion/Summary
In the last study session of this module and course, you studied memory
management. You learnt how memories used by programs are allocated. You
were also briefly introduced to the memory manager and problems faced by
memory allocation. We concluded this study session by looking at free lists and
the implementation of free lists with examples using different data structures.
367
5.0 Self-Assessment Questions
1. In which implementation of free list must nodes be sorted according to
start addresses of free blocks so that adjacent free memory blocks can be
combined?
2. Highlight the disadvantages of buddy systems discussed in the study
session.
6.0 Additional Activities (Videos, Animations & Out of Class activities) e.g.
a. Visit U-tube http://bit.ly/2ZsSYX8 , http://bit.ly/2ZoSUNj , http://bit.ly/2NwIe7R,
368
Design Patterns in Java”, John Wiley & Sons, Inc., 2000.
GLOSSARY
Classification: Grouping related things together. This is supported through
classes, inheritance and packages.
Encapsulation: Representing data and the set of operations on the data as a
single entity - exactly what classes do.
Information Hiding: An object should be in full control of its data, granting
specific access only to whom it wishes.
Inheritance: Java allows related classes to be organized in a hierarchical
manner using the extends keyword.
Polymorphism: Same code behaves differently at different times during
execution. This is due to dynamic binding.
Abstract classes: These are classes that contain a mix of methods declared with
or without an implementation. However, they cannot be instantiated.
369
Big-O notation, O(g(n)), is used to give an upper bound (worst-case) on a
positive runtime function f(n) where n is the input size.
List data structure: is a sequential data structure, i.e. a collection of items
accessible one after another, beginning at the head and ending at the tail.
Singly linked list: is a data structure in which the data items are chained (linked)
in one direction
Doubly linked list: is a data structure in which the data items are chained
(linked) in two directions.
Stack: is a linear data structure in which all insertions and deletions of data are
made only at one end of the stack, often called the top of the stack.
Queue data structure: is characterized by the fact that additions are made at the
end, or tail, of the queue while removals are made from the front, or head of the
queue.
Tree: A tree is a finite set of nodes together with a finite set of directed edges
that define parent-child relationships.
Tree Traversal: The process of systematically visiting all the nodes in a tree
and performing some computation at each node in the tree is called a tree
traversal.
AVL tree: An AVL tree is a binary search tree with a height balance property.
370
Data compression: Data compression is the representation of an information
source (e.g. a data file, a speech signal, an image, or a video signal) as
accurately as possible using the fewest number of bits.
371