100% found this document useful (5 votes)
64 views

Data Structures and Algorithms Made Easy Data Structure and Algorithmic Puzzles 5th Edition by Careermonk Publications, Narasimha Karumanchi ISBN 9788193245279 - Download the ebook now for an unlimited reading experience

The document provides information on various ebooks related to data structures and algorithms, including titles, authors, and ISBNs, available for instant download at ebookball.com. It emphasizes the importance of these resources for interview preparation and academic studies in computer science. Additionally, it includes a preface and acknowledgments from the author, Narasimha Karumanchi, highlighting the book's focus on problem-solving and analysis rather than theoretical concepts.

Uploaded by

elmodicha
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (5 votes)
64 views

Data Structures and Algorithms Made Easy Data Structure and Algorithmic Puzzles 5th Edition by Careermonk Publications, Narasimha Karumanchi ISBN 9788193245279 - Download the ebook now for an unlimited reading experience

The document provides information on various ebooks related to data structures and algorithms, including titles, authors, and ISBNs, available for instant download at ebookball.com. It emphasizes the importance of these resources for interview preparation and academic studies in computer science. Additionally, it includes a preface and acknowledgments from the author, Narasimha Karumanchi, highlighting the book's focus on problem-solving and analysis rather than theoretical concepts.

Uploaded by

elmodicha
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 88

Instant Ebook Access, One Click Away – Begin at ebookball.

com

Data Structures and Algorithms Made Easy Data


Structure and Algorithmic Puzzles 5th Edition by
Careermonk Publications, Narasimha Karumanchi ISBN
9788193245279
https://ebookball.com/product/data-structures-and-
algorithms-made-easy-data-structure-and-algorithmic-
puzzles-5th-edition-by-careermonk-publications-narasimha-
karumanchi-isbn-9788193245279-15800/

OR CLICK BUTTON

DOWLOAD EBOOK

Get Instant Ebook Downloads – Browse at https://ebookball.com


Your digital treasures (PDF, ePub, MOBI) await
Download instantly and pick your perfect format...

Read anywhere, anytime, on any device!

JavaScript Data Structures and Algorithms An Introduction


to Understanding and Implementing Core Data Structure and
Algorithm Fundamentals 1st Editon by Sammie Bae ISBN
1484239873 9781484239872

https://ebookball.com/product/javascript-data-structures-and-
algorithms-an-introduction-to-understanding-and-implementing-core-
data-structure-and-algorithm-fundamentals-1st-editon-by-sammie-bae-
isbn-1484239873-9781484239872-15798/
ebookball.com

Data Structures and Algorithms 1st Edition by Alfred Aho


ISBN 0201000237 9780201000238

https://ebookball.com/product/data-structures-and-algorithms-1st-
edition-by-alfred-aho-isbn-0201000237-9780201000238-25072/

ebookball.com

Data Structures and Algorithms in Java 1st Edition by


Peter Drake ISBN 0131469142 9780131469143

https://ebookball.com/product/data-structures-and-algorithms-in-
java-1st-edition-by-peter-drake-isbn-0131469142-9780131469143-12422/

ebookball.com

Data Structures and Algorithms in C 1st edition by Adam


Drozdek ASIN B002WLXMBY

https://ebookball.com/product/data-structures-and-algorithms-in-c-1st-
edition-by-adam-drozdek-asin-b002wlxmby-25076/

ebookball.com
Data Structures Algorithms and Applications in C++ 1st
edition by Adam Drozdek ISBN 1133608426 9781133608424

https://ebookball.com/product/data-structures-algorithms-and-
applications-in-c-1st-edition-by-adam-drozdek-
isbn-1133608426-9781133608424-17250/

ebookball.com

The Tomes of Delphi Algorithms and Data Structures 1st


Edition by Julian Bucknall ISBN 1556227361 9781556227363

https://ebookball.com/product/the-tomes-of-delphi-algorithms-and-data-
structures-1st-edition-by-julian-bucknall-
isbn-1556227361-9781556227363-10344/

ebookball.com

Think Data Structures Algorithms and Information Retrieval


in Java 1st Edition by Allen Downey ISBN 9781491972311
1491972319

https://ebookball.com/product/think-data-structures-algorithms-and-
information-retrieval-in-java-1st-edition-by-allen-downey-
isbn-9781491972311-1491972319-15760/

ebookball.com

Problem Solving in Data Structures and Algorithms Using C


1st Edition by Hemant Jain ISBN 9352655915 9789352655915

https://ebookball.com/product/problem-solving-in-data-structures-and-
algorithms-using-c-1st-edition-by-hemant-jain-
isbn-9352655915-9789352655915-15768/

ebookball.com

Problem Solving in Data Structures and Algorithms Using C


1st Edition by Hemant Jain ISBN 1540407306 9781540407306

https://ebookball.com/product/problem-solving-in-data-structures-and-
algorithms-using-c-1st-edition-by-hemant-jain-
isbn-1540407306-9781540407306-15866/

ebookball.com
Data Structures
And
Algorithms
Made Easy

-To All My Readers

By
Narasimha Karumanchi
Copyright© 2017 by CareerMonk.com
All rights reserved.
Designed by Narasimha Karumanchi

Copyright© 2017 CareerMonk Publications. All rights reserved.

All rights reserved. No part of this book may be reproduced in any form or by any electronic or mechanical means, including
information storage and retrieval systems, without written permission from the publisher or author.
Acknowledgements

Mother and Father, it is impossible to thank you adequately for everything you have done, from
loving me unconditionally to raising me in a stable household, where your persistent efforts and
traditional values taught your children to celebrate and embrace life. I could not have asked for
better parents or role-models. You showed me that anything is possible with faith, hard work and
determination.

This book would not have been possible without the help of many people. I would like to express
my gratitude to all of the people who provided support, talked things over, read, wrote, offered
comments, allowed me to quote their remarks and assisted in the editing, proofreading and design.
In particular, I would like to thank the following individuals:
▪ Mohan Mullapudi, IIT Bombay, Architect, dataRPM Pvt. Ltd.
▪ Navin Kumar Jaiswal, Senior Consultant, Juniper Networks Inc.
▪ A. Vamshi Krishna, IIT Kanpur, Mentor Graphics Inc.
▪ Cathy Reed, BA, MA, Copy Editor

–Narasimha Karumanchi
M-Tech, IIT Bombay
Founder, CareerMonk.com
Preface

Dear Reader,

Please hold on! I know many people typically do not read the Preface of a book. But I strongly
recommend that you read this particular Preface.

It is not the main objective of this book to present you with the theorems and proofs on data
structures and algorithms. I have followed a pattern of improving the problem solutions with
different complexities (for each problem, you will find multiple solutions with different, and
reduced, complexities). Basically, it’s an enumeration of possible solutions. With this approach,
even if you get a new question, it will show you a way to think about the possible solutions. You
will find this book useful for interview preparation, competitive exams preparation, and campus
interview preparations.

As a job seeker, if you read the complete book, I am sure you will be able to challenge the
interviewers. If you read it as an instructor, it will help you to deliver lectures with an approach
that is easy to follow, and as a result your students will appreciate the fact that they have opted for
Computer Science / Information Technology as their degree.

This book is also useful for Engineering degree students and Masters degree students during
their academic preparations. In all the chapters you will see that there is more emphasis on
problems and their analysis rather than on theory. In each chapter, you will first read about the
basic required theory, which is then followed by a section on problem sets. In total, there are
approximately 700 algorithmic problems, all with solutions.

If you read the book as a student preparing for competitive exams for Computer Science /
Information Technology, the content covers all the required topics in full detail. While writing
this book, my main focus was to help students who are preparing for these exams.

In all the chapters you will see more emphasis on problems and analysis rather than on theory. In
each chapter, you will first see the basic required theory followed by various problems.

For many problems, multiple solutions are provided with different levels of complexity. We start
with the brute force solution and slowly move toward the best solution possible for that problem.
For each problem, we endeavor to understand how much time the algorithm takes and how much
memory the algorithm uses.
It is recommended that the reader does at least one complete reading of this book to gain a full
understanding of all the topics that are covered. Then, in subsequent readings you can skip
directly to any chapter to refer to a specific topic. Even though many readings have been done for
the purpose of correcting errors, there could still be some minor typos in the book. If any are
found, they will be updated at www.CareerMonk.com. You can monitor this site for any
corrections and also for new problems and solutions. Also, please provide your valuable
suggestions at: [email protected].

I wish you all the best and I am confident that you will find this book useful.

–Narasimha Karumanchi
M-Tech, I IT Bombay
Founder, CareerMonk.com
Other Books by Narasimha Karumanchi
IT Interview Questions

Data Structures and Algorithms for GATE

Data Structures and Aigorithms Made Easy in Java

Coding Interview Questions

Peeling Design Patterns

Elements of Computer Networking

Data Structures and Algorithmic Thinking with Python


Table of Contents

1. Introduction
1.1 Variables
1.2 Data Types
1.3 Data Structures
1.4 Abstract Data Types (ADTs)
1.5 What is an Algorithm?
1.6 Why the Analysis of Algorithms?
1.7 Goal of the Analysis of Algorithms
1.8 What is Running Time Analysis?
1.9 How to Compare Algorithms
1.10 What is Rate of Growth?
1.11 Commonly Used Rates of Growth
1.12 Types of Analysis
1.13 Asymptotic Notation
1.14 Big-O Notation [Upper Bounding Function]
1.15 Omega-Q Notation [Lower Bounding Function]
1.16 Theta-Θ Notation [Order Function]
1.17 Important Notes
1.18 Why is it called Asymptotic Analysis?
1.19 Guidelines for Asymptotic Analysis
1.20 Simplyfying properties of asymptotic notations
1.21 Commonly used Logarithms and Summations
1.22 Master Theorem for Divide and Conquer Recurrences
1.23 Divide and Conquer Master Theorem: Problems & Solutions
1.24 Master Theorem for Subtract and Conquer Recurrences
1.25 Variant of Subtraction and Conquer Master Theorem
1.26 Method of Guessing and Confirming
1.27 Amortized Analysis
1.28 Algorithms Analysis: Problems & Solutions

2. Recursion and Backtracking


2.1 Introduction
2.2 What is Recursion?
2.3 Why Recursion?
2.4 Format of a Recursive Function
2.5 Recursion and Memory (Visualization)
2.6 Recursion versus Iteration
2.7 Notes on Recursion
2.8 Example Algorithms of Recursion
2.9 Recursion: Problems & Solutions
2.10 What is Backtracking?
2.11 Example Algorithms of Backtracking
2.12 Backtracking: Problems & Solutions

3. Linked Lists
3.1 What is a Linked List?
3.2 Linked Lists ADT
3.3 Why Linked Lists?
3.4 Arrays Overview
3.5 Comparison of Linked Lists with Arrays & Dynamic Arrays
3.6 Singly Linked Lists
3.7 Doubly Linked Lists
3.8 Circular Linked Lists
3.9 A Memory-efficient Doubly Linked List
3.10 Unrolled Linked Lists
3.11 Skip Lists
3.12 Linked Lists: Problems & Solutions

4. Stacks
4.1 What is a Stack?
4.2 How Stacks are used
4.3 Stack ADT
4.4 Applications
4.5 Implementation
4.6 Comparison of Implementations
4.7 Stacks: Problems & Solutions

5. Queues
5.1 What is a Queue?
5.2 How are Queues Used?
5.3 Queue ADT
5.4 Exceptions
5.5 Applications
5.6 Implementation
5.7 Queues: Problems & Solutions

6. Trees
6.1 What is a Tree?
6.2 Glossary
6.3 Binary Trees
6.4 Types of Binary Trees
6.5 Properties of Binary Trees
6.6 Binary Tree Traversals
6.7 Generic Trees (N-ary Trees)
6.8 Threaded Binary Tree Traversals (Stack or Queue-less Traversals)
6.9 Expression Trees
6.10 XOR Trees
6.11 Binary Search Trees (BSTs)
6.12 Balanced Binary Search Trees
6.13 AVL (Adelson-Velskii and Landis) Trees
6.14 Other Variations on Trees

7. Priority Queues and Heaps


7.1 What is a Priority Queue?
7.2 Priority Queue ADT
7.3 Priority Queue Applications
7.4 Priority Queue Implementations
7.5 Heaps and Binary Heaps
7.6 Binary Heaps
7.7 Heapsort
7.8 Priority Queues [Heaps]: Problems & Solutions

8. Disjoint Sets ADT


8.1 Introduction
8.2 Equivalence Relations and Equivalence Classes
8.3 Disjoint Sets ADT
8.4 Applications
8.5 Tradeoffs in Implementing Disjoint Sets ADT
8.8 Fast UNION Implementation (Slow FIND)
8.9 Fast UNION Implementations (Quick FIND)
8.10 Summary
8.11 Disjoint Sets: Problems & Solutions

9. Graph Algorithms
9.1 Introduction
9.2 Glossary
9.3 Applications of Graphs
9.4 Graph Representation
9.5 Graph Traversals
9.6 Topological Sort
9.7 Shortest Path Algorithms
9.8 Minimal Spanning Tree
9.9 Graph Algorithms: Problems & Solutions

10. Sorting
10.1 What is Sorting?
10.2 Why is Sorting Necessary?
10.3 Classification of Sorting Algorithms
10.4 Other Classifications
10.5 Bubble Sort
10.6 Selection Sort
10.7 Insertion Sort
10.8 Shell Sort
10.9 Merge Sort
10.10 Heap Sort
10.11 Quick Sort
10.12 Tree Sort
10.13 Comparison of Sorting Algorithms
10.14 Linear Sorting Algorithms
10.15 Counting Sort
10.16 Bucket Sort (or Bin Sort)
10.17 Radix Sort
10.18 Topological Sort
10.19 External Sorting
10.20 Sorting: Problems & Solutions

11. Searching
11.1 What is Searching?
11.2 Why do we need Searching?
11.3 Types of Searching
11.4 Unordered Linear Search
11.5 Sorted/Ordered Linear Search
11.6 Binary Search
11.7 Interpolation Search
11.8 Comparing Basic Searching Algorithms
11.9 Symbol Tables and Hashing
11.10 String Searching Algorithms
11.11 Searching: Problems & Solutions

12. Selection Algorithms [Medians]


12.1 What are Selection Algorithms?
12.2 Selection by Sorting
12.3 Partition-based Selection Algorithm
12.4 Linear Selection Algorithm - Median of Medians Algorithm
12.5 Finding the K Smallest Elements in Sorted Order
12.6 Selection Algorithms: Problems & Solutions
13. Symbol Tables
13.1 Introduction
13.2 What are Symbol Tables?
13.3 Symbol Table Implementations
13.4 Comparison Table of Symbols for Implementations

14. Hashing
14.1 What is Hashing?
14.2 Why Hashing?
14.3 HashTable ADT
14.4 Understanding Hashing
14.5 Components of Hashing
14.6 Hash Table
14.7 Hash Function
14.8 Load Factor
14.9 Collisions
14.10 Collision Resolution Techniques
14.11 Separate Chaining
14.12 Open Addressing
14.13 Comparison of Collision Resolution Techniques
14.14 How Hashing Gets O(1) Complexity?
14.15 Hashing Techniques
14.16 Problems for which Hash Tables are not suitable
14.17 Bloom Filters
14.18 Hashing: Problems & Solutions

15. String Algorithms


15.1 Introduction
15.2 String Matching Algorithms
15.3 Brute Force Method
15.4 Rabin-Karp String Matching Algorithm
15.5 String Matching with Finite Automata
15.6 KMP Algorithm
15.7 Boyer-Moore Algorithm
15.8 Data Structures for Storing Strings
15.9 Hash Tables for Strings
15.10 Binary Search Trees for Strings
15.11 Tries
15.12 Ternary Search Trees
15.13 Comparing BSTs, Tries and TSTs
15.14 Suffix Trees
15.15 String Algorithms: Problems & Solutions

16. Algorithms Design Techniques


16.1 Introduction
16.2 Classification
16.3 Classification by Implementation Method
16.4 Classification by Design Method
16.5 Other Classifications

17. Greedy Algorithms


17.1 Introduction
17.2 Greedy Strategy
17.3 Elements of Greedy Algorithms
17.4 Does Greedy Always Work?
17.5 Advantages and Disadvantages of Greedy Method
17.6 Greedy Applications
17.7 Understanding Greedy Technique
17.8 Greedy Algorithms: Problems & Solutions

18. Divide and Conquer Algorithms


18.1 Introduction
18.2 What is the Divide and Conquer Strategy?
18.3 Does Divide and Conquer Always Work?
18.4 Divide and Conquer Visualization
18.5 Understanding Divide and Conquer
18.6 Advantages of Divide and Conquer
18.7 Disadvantages of Divide and Conquer
18.8 Master Theorem
18.9 Divide and Conquer Applications
18.10 Divide and Conquer: Problems & Solutions

19. Dynamic Programming


19.1 Introduction
19.2 What is Dynamic Programming Strategy?
19.3 Properties of Dynamic Programming Strategy
19.4 Can Dynamic Programming Solve All Problems?
19.5 Dynamic Programming Approaches
19.6 Examples of Dynamic Programming Algorithms
19.7 Understanding Dynamic Programming
19.8 Longest Common Subsequence
19.9 Dynamic Programming: Problems & Solutions

20. Complexity Classes


20.1 Introduction
20.2 Polynomial/Exponential Time
20.3 What is a Decision Problem?
20.4 Decision Procedure
20.5 What is a Complexity Class?
20.6 Types of Complexity Classes
20.7 Reductions
20.8 Complexity Classes: Problems & Solutions

21. Miscellaneous Concepts


21.1 Introduction
21.2 Hacks on Bit-wise Programming
21.3 Other Programming Questions

References
The objective of this chapter is to explain the importance of the analysis of algorithms, their
notations, relationships and solving as many problems as possible. Let us first focus on
understanding the basic elements of algorithms, the importance of algorithm analysis, and then
slowly move toward the other topics as mentioned above. After completing this chapter, you
should be able to find the complexity of any given algorithm (especially recursive functions).

1.1 Variables

Before going to the definition of variables, let us relate them to old mathematical equations. All of
us have solved many mathematical equations since childhood. As an example, consider the below
equation:
We don’t have to worry about the use of this equation. The important thing that we need to
understand is that the equation has names (x and y), which hold values (data). That means the
names (x and y) are placeholders for representing data. Similarly, in computer science
programming we need something for holding data, and variables is the way to do that.

1.2 Data Types

In the above-mentioned equation, the variables x and y can take any values such as integral
numbers (10, 20), real numbers (0.23, 5.5), or just 0 and 1. To solve the equation, we need to
relate them to the kind of values they can take, and data type is the name used in computer science
programming for this purpose. A data type in a programming language is a set of data with
predefined values. Examples of data types are: integer, floating point, unit number, character,
string, etc.

Computer memory is all filled with zeros and ones. If we have a problem and we want to code it,
it’s very difficult to provide the solution in terms of zeros and ones. To help users, programming
languages and compilers provide us with data types. For example, integer takes 2 bytes (actual
value depends on compiler), float takes 4 bytes, etc. This says that in memory we are combining
2 bytes (16 bits) and calling it an integer. Similarly, combining 4 bytes (32 bits) and calling it a
float. A data type reduces the coding effort. At the top level, there are two types of data types:
• System-defined data types (also called Primitive data types)
• User-defined data types

System-defined data types (Primitive data types)

Data types that are defined by system are called primitive data types. The primitive data types
provided by many programming languages are: int, float, char, double, bool, etc. The number of
bits allocated for each primitive data type depends on the programming languages, the compiler
and the operating system. For the same primitive data type, different languages may use different
sizes. Depending on the size of the data types, the total available values (domain) will also
change.

For example, “int” may take 2 bytes or 4 bytes. If it takes 2 bytes (16 bits), then the total possible
values are minus 32,768 to plus 32,767 (-215 to 215-1). If it takes 4 bytes (32 bits), then the
possible values are between -2,147,483,648 and +2,147,483,647 (-231 to 231-1). The same is the
case with other data types.

User defined data types

If the system-defined data types are not enough, then most programming languages allow the users
to define their own data types, called user – defined data types. Good examples of user defined
data types are: structures in C/C + + and classes in Java. For example, in the snippet below, we
are combining many system-defined data types and calling the user defined data type by the name
“newType”. This gives more flexibility and comfort in dealing with computer memory.

1.3 Data Structures

Based on the discussion above, once we have data in variables, we need some mechanism for
manipulating that data to solve problems. Data structure is a particular way of storing and
organizing data in a computer so that it can be used efficiently. A data structure is a special
format for organizing and storing data. General data structure types include arrays, files, linked
lists, stacks, queues, trees, graphs and so on.

Depending on the organization of the elements, data structures are classified into two types:
1) Linear data structures: Elements are accessed in a sequential order but it is not
compulsory to store all elements sequentially. Examples: Linked Lists, Stacks and
Queues.
2) Non – linear data structures: Elements of this data structure are stored/accessed in a
non-linear order. Examples: Trees and graphs.

1.4 Abstract Data Types (ADTs)

Before defining abstract data types, let us consider the different view of system-defined data
types. We all know that, by default, all primitive data types (int, float, etc.) support basic
operations such as addition and subtraction. The system provides the implementations for the
primitive data types. For user-defined data types we also need to define operations. The
implementation for these operations can be done when we want to actually use them. That means,
in general, user defined data types are defined along with their operations.

To simplify the process of solving problems, we combine the data structures with their operations
and we call this Abstract Data Types (ADTs). An ADT consists of two parts:
1. Declaration of data
2. Declaration of operations

Commonly used ADTs include: Linked Lists, Stacks, Queues, Priority Queues, Binary Trees,
Dictionaries, Disjoint Sets (Union and Find), Hash Tables, Graphs, and many others. For
example, stack uses LIFO (Last-In-First-Out) mechanism while storing the data in data structures.
The last element inserted into the stack is the first element that gets deleted. Common operations
of it are: creating the stack, pushing an element onto the stack, popping an element from stack,
finding the current top of the stack, finding number of elements in the stack, etc.

While defining the ADTs do not worry about the implementation details. They come into the
picture only when we want to use them. Different kinds of ADTs are suited to different kinds of
applications, and some are highly specialized to specific tasks. By the end of this book, we will
go through many of them and you will be in a position to relate the data structures to the kind of
problems they solve.

1.5 What is an Algorithm?

Let us consider the problem of preparing an omelette. To prepare an omelette, we follow the
steps given below:
1) Get the frying pan.
2) Get the oil.
a. Do we have oil?
i. If yes, put it in the pan.
ii. If no, do we want to buy oil?
1. If yes, then go out and buy.
2. If no, we can terminate.
3) Turn on the stove, etc...

What we are doing is, for a given problem (preparing an omelette), we are providing a step-by-
step procedure for solving it. The formal definition of an algorithm can be stated as:

An algorithm is the step-by-step unambiguous instructions to solve a given problem.

In the traditional study of algorithms, there are two main criteria for judging the merits of
algorithms: correctness (does the algorithm give solution to the problem in a finite number of
steps?) and efficiency (how much resources (in terms of memory and time) does it take to execute
the).

Note: We do not have to prove each step of the algorithm.

1.6 Why the Analysis of Algorithms?


To go from city “A” to city “B”, there can be many ways of accomplishing this: by flight, by bus,
by train and also by bicycle. Depending on the availability and convenience, we choose the one
that suits us. Similarly, in computer science, multiple algorithms are available for solving the
same problem (for example, a sorting problem has many algorithms, like insertion sort, selection
sort, quick sort and many more). Algorithm analysis helps us to determine which algorithm is
most efficient in terms of time and space consumed.

1.7 Goal of the Analysis of Algorithms

The goal of the analysis of algorithms is to compare algorithms (or solutions) mainly in terms of
running time but also in terms of other factors (e.g., memory, developer effort, etc.)

1.8 What is Running Time Analysis?

It is the process of determining how processing time increases as the size of the problem (input
size) increases. Input size is the number of elements in the input, and depending on the problem
type, the input may be of different types. The following are the common types of inputs.
• Size of an array
• Polynomial degree
• Number of elements in a matrix
• Number of bits in the binary representation of the input
• Vertices and edges in a graph.

1.9 How to Compare Algorithms

To compare algorithms, let us define a few objective measures:

Execution times? Not a good measure as execution times are specific to a particular computer.

Number of statements executed? Not a good measure, since the number of statements varies
with the programming language as well as the style of the individual programmer.

Ideal solution? Let us assume that we express the running time of a given algorithm as a function
of the input size n (i.e., f(n)) and compare these different functions corresponding to running
times. This kind of comparison is independent of machine time, programming style, etc.

1.10 What is Rate of Growth?

The rate at which the running time increases as a function of input is called rate of growth. Let us
assume that you go to a shop to buy a car and a bicycle. If your friend sees you there and asks
what you are buying, then in general you say buying a car. This is because the cost of the car is
high compared to the cost of the bicycle (approximating the cost of the bicycle to the cost of the
car).

For the above-mentioned example, we can represent the cost of the car and the cost of the bicycle
in terms of function, and for a given function ignore the low order terms that are relatively
insignificant (for large value of input size, n). As an example, in the case below, n4, 2n2, 100n
and 500 are the individual costs of some function and approximate to n4 since n4 is the highest
rate of growth.

1.11 Commonly Used Rates of Growth

The diagram below shows the relationship between different rates of growth.
Below is the list of growth rates you will come across in the following chapters.
1.12 Types of Analysis

To analyze the given algorithm, we need to know with which inputs the algorithm takes less time
(performing wel1) and with which inputs the algorithm takes a long time. We have already seen
that an algorithm can be represented in the form of an expression. That means we represent the
algorithm with multiple expressions: one for the case where it takes less time and another for the
case where it takes more time.

In general, the first case is called the best case and the second case is called the worst case for
the algorithm. To analyze an algorithm we need some kind of syntax, and that forms the base for
asymptotic analysis/notation. There are three types of analysis:
• Worst case
○ Defines the input for which the algorithm takes a long time (slowest
time to complete).
○ Input is the one for which the algorithm runs the slowest.
• Best case
○ Defines the input for which the algorithm takes the least time (fastest
time to complete).
○ Input is the one for which the algorithm runs the fastest.
• Average case
○ Provides a prediction about the running time of the algorithm.
○ Run the algorithm many times, using many different inputs that come
from some distribution that generates these inputs, compute the total
running time (by adding the individual times), and divide by the
number of trials.
○ Assumes that the input is random.

Lower Bound <= Average Time <= Upper Bound


For a given algorithm, we can represent the best, worst and average cases in the form of
expressions. As an example, let f(n) be the function which represents the given algorithm.

Similarly for the average case. The expression defines the inputs with which the algorithm takes
the average running time (or memory).

1.13 Asymptotic Notation

Having the expressions for the best, average and worst cases, for all three cases we need to
identify the upper and lower bounds. To represent these upper and lower bounds, we need some
kind of syntax, and that is the subject of the following discussion. Let us assume that the given
algorithm is represented in the form of function f(n).

1.14 Big-O Notation [Upper Bounding Function]

This notation gives the tight upper bound of the given function. Generally, it is represented as f(n)
= O(g(n)). That means, at larger values of n, the upper bound of f(n) is g(n). For example, if f(n)
= n4 + 100n2 + 10n + 50 is the given algorithm, then n4 is g(n). That means g(n) gives the
maximum rate of growth for f(n) at larger values of n.
Let us see the O–notation with a little more detail. O–notation defined as O(g(n)) = {f(n): there
exist positive constants c and n0 such that 0 ≤ f(n) ≤ cg(n) for all n > n0}. g(n) is an asymptotic
tight upper bound for f(n). Our objective is to give the smallest rate of growth g(n) which is
greater than or equal to the given algorithms’ rate of growth /(n).

Generally we discard lower values of n. That means the rate of growth at lower values of n is not
important. In the figure, n0 is the point from which we need to consider the rate of growth for a
given algorithm. Below n0, the rate of growth could be different. n0 is called threshold for the
given function.

Big-O Visualization

O(g(n)) is the set of functions with smaller or the same order of growth as g(n). For example;
O(n2) includes O(1), O(n), O(nlogn), etc.

Note: Analyze the algorithms at larger values of n only. What this means is, below n0 we do not
care about the rate of growth.

Big-O Examples

Example-1 Find upper bound for f(n) = 3n + 8


Solution: 3n + 8 ≤ 4n, for all n ≥ 8
∴ 3n + 8 = O(n) with c = 4 and n0 = 8
Example-2 Find upper bound for f(n) = n2 + 1
Solution: n2 + 1 ≤ 2n2, for all n ≥ 1
∴ n2 + 1 = O(n2) with c = 2 and n0 = 1

Example-3 Find upper bound for f(n) = n4 + 100n2 + 50


Solution: n4 + 100n2 + 50 ≤ 2n4, for all n ≥ 11
∴ n4 + 100n2 + 50 = O(n4 ) with c = 2 and n0 = 11

Example-4 Find upper bound for f(n) = 2n3 – 2n2


Solution: 2n3 – 2n2 ≤ 2n3, for all n > 1
∴ 2n3 – 2n2 = O(n3 ) with c = 2 and n0 = 1
Example-5 Find upper bound for f(n) = n
Solution: n ≤ n, for all n ≥ 1
∴ n = O(n) with c = 1 and n0 = 1
Example-6 Find upper bound for f(n) = 410
Solution: 410 ≤ 410, for all n > 1
∴ 410 = O(1) with c = 1 and n0 = 1

No Uniqueness?

There is no unique set of values for n0 and c in proving the asymptotic bounds. Let us consider,
100n + 5 = O(n). For this function there are multiple n0 and c values possible.
Solution1: 100n + 5 ≤ 100n + n = 101n ≤ 101n, for all n ≥ 5, n0 = 5 and c = 101 is a solution.
Solution2: 100n + 5 ≤ 100n + 5n = 105n ≤ 105n, for all n > 1, n0 = 1 and c = 105 is also a
solution.

1.15 Omega-Q Notation [Lower Bounding Function]

Similar to the O discussion, this notation gives the tighter lower bound of the given algorithm and
we represent it as f(n) = Ω(g(n)). That means, at larger values of n, the tighter lower bound of
f(n) is g(n). For example, if f(n) = 100n2 + 10n + 50, g(n) is Ω(n2).
The Ω notation can be defined as Ω(g(n)) = {f(n): there exist positive constants c and n0 such that
0 ≤ cg(n) ≤ f(n) for all n ≥ n0}. g(n) is an asymptotic tight lower bound for f(n). Our objective is
to give the largest rate of growth g(n) which is less than or equal to the given algorithm’s rate of
growth f(n).

Ω Examples

Example-1 Find lower bound for f(n) = 5n2.


Solution: ∃ c, n0 Such that: 0 ≤ cn2≤ 5n2 ⇒ cn2 ≤ 5n2 ⇒ c = 5 and n0 = 1
∴ 5n2 = Ω(n2) with c = 5 and n0 = 1

Example-2 Prove f(n) = 100n + 5 ≠ Ω(n2).


Solution: ∃ c, n0 Such that: 0 ≤ cn2 ≤ 100n + 5
100n + 5 ≤ 100n + 5n(∀n ≥ 1) = 105n
cn2 ≤ 105n ⇒ n(cn - 105) ≤ 0
Since n is positive ⇒cn - 105 ≤0 ⇒ n ≤105/c
⇒ Contradiction: n cannot be smaller than a constant

Example-3 2n = Q(n), n3 = Q(n3), = O(logn).


1.16 Theta-Θ Notation [Order Function]

This notation decides whether the upper and lower bounds of a given function (algorithm) are the
same. The average running time of an algorithm is always between the lower bound and the upper
bound. If the upper bound (O) and lower bound (Ω) give the same result, then the Θ notation will
also have the same rate of growth.

As an example, let us assume that f(n) = 10n + n is the expression. Then, its tight upper bound
g(n) is O(n). The rate of growth in the best case is g(n) = O(n).

In this case, the rates of growth in the best case and worst case are the same. As a result, the
average case will also be the same. For a given function (algorithm), if the rates of growth
(bounds) for O and Ω are not the same, then the rate of growth for the Θ case may not be the same.
In this case, we need to consider all possible time complexities and take the average of those (for
example, for a quick sort average case, refer to the Sorting chapter).

Now consider the definition of Θ notation. It is defined as Θ(g(n)) = {f(n): there exist positive
constants c1,c2 and n0 such that 0 ≤ c1g(n) ≤ f(n) ≤ c2g(n) for all n ≥ n0}. g(n) is an asymptotic
tight bound for f(n). Θ(g(n)) is the set of functions with the same order of growth as g(n).

Θ Examples
Example 1 Find Θ bound for

Solution: for all, n ≥ 2


∴ with c1 = 1/5,c2 = 1 and n0 = 2

Example 2 Prove n ≠ Θ(n2)


Solution: c1 n2 ≤ n ≤ c2n2 ⇒ only holds for: n ≤ 1/c1
∴ n ≠ Θ(n2)

Example 3 Prove 6n3 ≠ Θ(n2)


Solution: c1 n2≤ 6n3 ≤ c2 n2 ⇒ only holds for: n ≤ c2 /6
∴ 6n3 ≠ Θ(n2)

Example 4 Prove n ≠ Θ(logn)


Solution: c1logn ≤ n ≤ c2logn ⇒ c2 ≥ , ∀ n ≥ n0 – Impossible

1.17 Important Notes

For analysis (best case, worst case and average), we try to give the upper bound (O) and lower
bound (Ω) and average running time (Θ). From the above examples, it should also be clear that,
for a given function (algorithm), getting the upper bound (O) and lower bound (Ω) and average
running time (Θ) may not always be possible. For example, if we are discussing the best case of
an algorithm, we try to give the upper bound (O) and lower bound (Ω) and average running time
(Θ).

In the remaining chapters, we generally focus on the upper bound (O) because knowing the lower
bound (Ω) of an algorithm is of no practical importance, and we use the Θ notation if the upper
bound (O) and lower bound (Ω) are the same.

1.18 Why is it called Asymptotic Analysis?

From the discussion above (for all three notations: worst case, best case, and average case), we
can easily understand that, in every case for a given function f(n) we are trying to find another
function g(n) which approximates f(n) at higher values of n. That means g(n) is also a curve
which approximates f(n) at higher values of n.

In mathematics we call such a curve an asymptotic curve. In other terms, g(n) is the asymptotic
curve for f(n). For this reason, we call algorithm analysis asymptotic analysis.

1.19 Guidelines for Asymptotic Analysis

There are some general rules to help us determine the running time of an algorithm.

1) Loops: The running time of a loop is, at most, the running time of the statements
inside the loop (including tests) multiplied by the number of iterations.

Total time = a constant c × n = c n = O(n).

2) Nested loops: Analyze from the inside out. Total running time is the product of the
sizes of all the loops.

Total time = c × n × n = cn2 = O(n2).

3) Consecutive statements: Add the time complexities of each statement.


Total time = c0 + c1n + c2n2 = O(n2).

4) If-then-else statements: Worst-case running time: the test, plus either the then part
or the else part (whichever is the larger).

Total time = c0 + c1 + (c2 + c3) * n = O(n).

5) Logarithmic complexity: An algorithm is O(logn) if it takes a constant time to cut


the problem size by a fraction (usually by ½). As an example let us consider the
following program:
If we observe carefully, the value of i is doubling every time. Initially i = 1, in next step i
= 2, and in subsequent steps i = 4,8 and so on. Let us assume that the loop is executing
some k times. At kth step 2k = n, and at (k + 1)th step we come out of the loop. Taking
logarithm on both sides, gives

Total time = O(logn).

Note: Similarly, for the case below, the worst case rate of growth is O(logn). The same
discussion holds good for the decreasing sequence as well.

Another example: binary search (finding a word in a dictionary of n pages)


• Look at the center point in the dictionary
• Is the word towards the left or right of center?
• Repeat the process with the left or right part of the dictionary until the word is found.

1.20 Simplyfying properties of asymptotic notations

• Transitivity: f(n) = Θ(g(n)) and g(n) = Θ(h(n)) ⇒ f(n) = Θ(h(n)). Valid for O and Ω
as well.
• Reflexivity: f(n) = Θ(f(n)). Valid for O and Ω.
• Symmetry: f(n) = Θ(g(n)) if and only if g(n) = Θ(f(n)).
• Transpose symmetry: f(n) = O(g(n)) if and only if g(n) = Ω(f(n)).
• If f(n) is in O(kg(n)) for any constant k > 0, then f(n) is in O(g(n)).
• If f1(n) is in O(g1(n)) and f2(n) is in O(g2(n)), then (f1 + f2)(n) is in O(max(g1(n)),
(g1(n))).
• If f1(n) is in O(g1(n)) and f2(n) is in O(g2(n)) then f1(n) f2(n) is in O(g1(n) g1(n)).

1.21 Commonly used Logarithms and Summations

Logarithms
Arithmetic series

Geometric series

Harmonic series

Other important formulae

1.22 Master Theorem for Divide and Conquer Recurrences

All divide and conquer algorithms (also discussed in detail in the Divide and Conquer chapter)
divide the problem into sub-problems, each of which is part of the original problem, and then
perform some additional work to compute the final answer. As an example, a merge sort
algorithm [for details, refer to Sorting chapter] operates on two sub-problems, each of which is
half the size of the original, and then performs O(n) additional work for merging. This gives the
running time equation:

The following theorem can be used to determine the running time of divide and conquer
algorithms. For a given program (algorithm), first we try to find the recurrence relation for the
problem. If the recurrence is of the below form then we can directly give the answer without fully
solving it. If the recurrence is of the form , where a ≥ 1,b >
1,k ≥ 0 and p is a real number, then:
1) If a > bk , then
2) If a= bk
a. If p > –1, then
b. If p = –1, then
c. If p < –1, then
3) If a < bk
a. If p ≥ 0, then T(n) = Θ(nk logpn)
b. If p < 0, then T(n) = O(nk )

1.23 Divide and Conquer Master Theorem: Problems & Solutions

For each of the following recurrences, give an expression for the runtime T(n) if the recurrence
can be solved with the Master Theorem. Otherwise, indicate that the Master Theorem does not
apply.

Problem-1 T(n) = 3T (n/2) + n2


Solution: T(n) = 3T (n/2) + n2 => T (n) =Θ(n2) (Master Theorem Case 3.a)

Problem-2 T(n) = 4T (n/2) + n2


Solution: T(n) = 4T (n/2) + n2 => T (n) = Θ(n2logn) (Master Theorem Case 2.a)

Problem-3 T(n) = T(n/2) + n2


Solution: T(n) = T(n/2) + n2 => Θ(n2) (Master Theorem Case 3.a)

Problem-4 T(n) = 2nT(n/2) + nn


Solution: T(n) = 2nT(n/2) + nn => Does not apply (a is not constant)
Problem-5 T(n) = 16T(n/4) + n
Solution: T(n) = 16T (n/4) + n => T(n) = Θ(n2) (Master Theorem Case 1)
Problem-6 T(n) = 2T(n/2) + nlogn
Solution: T(n) = 2T(n/2) + nlogn => T(n) = Θ(nlog2n) (Master Theorem Case 2.a)
Problem-7 T(n) = 2T(n/2) + n/logn
Solution: T(n) = 2T(n/2)+ n/logn =>T(n) = Θ(nloglogn) (Master Theorem Case 2. b)

Problem-8 T(n) = 2T (n/4) + n051


Solution: T(n) = 2T(n/4) + n051 => T (n) = Θ(n0.51) (Master Theorem Case 3.b)
Problem-9 T(n) = 0.5T(n/2) + 1/n
Solution: T(n) = 0.5T(n/2) + 1/n => Does not apply (a < 1)

Problem-10 T (n) = 6T(n/3)+ n2 logn


Solution: T(n) = 6T(n/3) + n2logn => T(n) = Θ(n2logn) (Master Theorem Case 3.a)

Problem-11 T(n) = 64T(n/8) – n2logn


Solution: T(n) = 64T(n/8) – n2logn => Does not apply (function is not positive)

Problem-12 T(n) = 7T(n/3) + n2


Solution: T(n) = 7T(n/3) + n2 => T(n) = Θ(n2) (Master Theorem Case 3.as)
Problem-13 T(n) = 4T(n/2) + logn
Solution: T(n) = 4T(n/2) + logn => T(n) = Θ(n2) (Master Theorem Case 1)
Problem-14 T(n) = 16T (n/4) + n!
Solution: T(n) = 16T (n/4) + n! => T(n) = Θ(n!) (Master Theorem Case 3.a)
Problem-15 T(n) = T(n/2) + logn
Solution: T(n) = T(n/2) + logn => T(n) = Θ( ) (Master Theorem Case 1)

Problem-16 T(n) = 3T(n/2) + n


Solution: T(n) = 3T(n/2) + n =>T(n) = Θ(nlog3) (Master Theorem Case 1)
Problem-17 T(n) = 3T(n/3) +
Solution: T(n) = 3T(n/3) + => T(n) = Θ(n) (Master Theorem Case 1)

Problem-18 T(n) = 4T(n/2) + cn


Solution: T(n) = 4T(n/2) + cn => T(n) = Θ(n2) (Master Theorem Case 1)
Problem-19 T(n) = 3T(n/4) + nlogn
Solution: T(n) = 3T(n/4) + nlogn => T(n) = Θ(nlogn) (Master Theorem Case 3.a)
Problem-20 T (n) = 3T(n/3) + n/2
Solution: T(n) = 3T(n/3)+ n/2 => T (n) = Θ(nlogn) (Master Theorem Case 2.a)

1.24 Master Theorem for Subtract and Conquer Recurrences


Let T(n) be a function defined on positive n, and having the property

for some constants c,a > 0,b ≥ 0,k ≥ 0, and function f(n). If f(n) is in O(nk ), then

1.25 Variant of Subtraction and Conquer Master Theorem

The solution to the equation T(n) = T(α n) + T((1 – α)n) + βn, where 0 < α < 1 and β > 0 are
constants, is O(nlogn).

1.26 Method of Guessing and Confirming

Now, let us discuss a method which can be used to solve any recurrence. The basic idea behind
this method is:

guess the answer; and then prove it correct by induction.

In other words, it addresses the question: What if the given recurrence doesn’t seem to match with
any of these (master theorem) methods? If we guess a solution and then try to verify our guess
inductively, usually either the proof will succeed (in which case we are done), or the proof will
fail (in which case the failure will help us refine our guess).

As an example, consider the recurrence . This doesn’t fit into the form
required by the Master Theorems. Carefully observing the recurrence gives us the impression that
it is similar to the divide and conquer method (dividing the problem into subproblems each
with size ). As we can see, the size of the subproblems at the first level of recursion is n. So,
let us guess that T(n) = O(nlogn), and then try to prove that our guess is correct.

Let’s start by trying to prove an upper bound T(n) < cnlogn:


The last inequality assumes only that 1 ≤ c. .logn. This is correct if n is sufficiently large and for
any constant c, no matter how small. From the above proof, we can see that our guess is correct
for the upper bound. Now, let us prove the lower bound for this recurrence.

The last inequality assumes only that 1 ≥ k. .logn. This is incorrect if n is sufficiently large and
for any constant k. From the above proof, we can see that our guess is incorrect for the lower
bound.

From the above discussion, we understood that Θ(nlogn) is too big. How about Θ(n)? The lower
bound is easy to prove directly:

Now, let us prove the upper bound for this Θ(n).

From the above induction, we understood that Θ(n) is too small and Θ(nlogn) is too big. So, we
need something bigger than n and smaller than nlogn. How about ?

Proving the upper bound for :


Proving the lower bound for :

The last step doesn’t work. So, Θ( ) doesn’t work. What else is between n and nlogn?
How about nloglogn? Proving upper bound for nloglogn:

Proving lower bound for nloglogn:

From the above proofs, we can see that T(n) ≤ cnloglogn, if c ≥ 1 and T(n) ≥ knloglogn, if k ≤ 1.
Technically, we’re still missing the base cases in both proofs, but we can be fairly confident at
this point that T(n) = Θ(nloglogn).

1.27 Amortized Analysis


Amortized analysis refers to determining the time-averaged running time for a sequence of
operations. It is different from average case analysis, because amortized analysis does not make
any assumption about the distribution of the data values, whereas average case analysis assumes
the data are not “bad” (e.g., some sorting algorithms do well on average over all input orderings
but very badly on certain input orderings). That is, amortized analysis is a worst-case analysis,
but for a sequence of operations rather than for individual operations.

The motivation for amortized analysis is to better understand the running time of certain
techniques, where standard worst case analysis provides an overly pessimistic bound. Amortized
analysis generally applies to a method that consists of a sequence of operations, where the vast
majority of the operations are cheap, but some of the operations are expensive. If we can show
that the expensive operations are particularly rare we can change them to the cheap operations,
and only bound the cheap operations.

The general approach is to assign an artificial cost to each operation in the sequence, such that the
total of the artificial costs for the sequence of operations bounds the total of the real costs for the
sequence. This artificial cost is called the amortized cost of an operation. To analyze the running
time, the amortized cost thus is a correct way of understanding the overall running time – but note
that particular operations can still take longer so it is not a way of bounding the running time of
any individual operation in the sequence.

When one event in a sequence affects the cost of later events:


• One particular task may be expensive.
• But it may leave data structure in a state that the next few operations become easier.

Example: Let us consider an array of elements from which we want to find the kth smallest
element. We can solve this problem using sorting. After sorting the given array, we just need to
return the kth element from it. The cost of performing the sort (assuming comparison based sorting
algorithm) is O(nlogn). If we perform n such selections then the average cost of each selection is
O(nlogn/n) = O(logn). This clearly indicates that sorting once is reducing the complexity of
subsequent operations.

1.28 Algorithms Analysis: Problems & Solutions

Note: From the following problems, try to understand the cases which have different
complexities (O(n), O(logn), O(loglogn) etc.).
Problem-21 Find the complexity of the below recurrence:
Solution: Let us try solving this function with substitution.
T(n) = 3T(n – 1)

T(n) = 3(3T(n – 2)) = 32T(n – 2)

T(n) = 32(3T(n – 3))


.
.

T(n) = 3nT(n – n) = 3nT(0) = 3n

This clearly shows that the complexity of this function is O(3n).

Note: We can use the Subtraction and Conquer master theorem for this problem.
Problem-22 Find the complexity of the below recurrence:

Solution: Let us try solving this function with substitution.


T(n) = 2T(n – 1) – 1

T(n) = 2(2T(n – 2) – 1) – 1 = 22T(n – 2) – 2 – 1

T(n) = 22(2T(n – 3) – 2 – 1) – 1 = 23T(n – 4) – 22 – 21 – 20

T(n) = 2nT(n – n) – 2n–1 – 2n–2 – 2n–3 .... 22 – 21 – 20

T(n) =2n – 2n–1 – 2n–2 – 2n – 3 .... 22 – 21 – 20

T(n) =2n – (2n – 1) [note: 2n–1 + 2n–2 + ··· + 20 = 2n]


T(n) = 1

∴ Time Complexity is O(1). Note that while the recurrence relation looks exponential, the
solution to the recurrence relation here gives a different result.
Problem-23 What is the running time of the following function?
Solution: Consider the comments in the below function:

We can define the ‘s’ terms according to the relation si = si–1 + i. The value oft’ increases by 1
for each iteration. The value contained in ‘s’ at the ith iteration is the sum of the first ‘(‘positive
integers. If k is the total number of iterations taken by the program, then the while loop terminates
if:

Problem-24 Find the complexity of the function given below.


Solution:

In the above-mentioned function the loop will end, if i2 > n ⇒ T(n) = O( ). This is similar to
Problem-23.
Problem-25 What is the complexity of the program given below:

Solution: Consider the comments in the following function.

The complexity of the above function is O(n2logn).


Problem-26 What is the complexity of the program given below:
Solution: Consider the comments in the following function.

The complexity of the above function is O(nlog2n).


Problem-27 Find the complexity of the program below.

Solution: Consider the comments in the function below.


The complexity of the above function is O(n). Even though the inner loop is bounded by n, due to
the break statement it is executing only once.
Problem-28 Write a recursive function for the running time T(n) of the function given below.
Prove using the iterative method that T(n) = Θ(n3).

Solution: Consider the comments in the function below:


The recurrence for this code is clearly T(n) = T(n – 3) + cn2 for some constant c > 0 since each
call prints out n2 asterisks and calls itself recursively on n – 3. Using the iterative method we get:
T(n) = T(n – 3) + cn2. Using the Subtraction and Conquer master theorem, we get T(n) = Θ(n3).

Problem-29 Determine Θ bounds for the recurrence relation:

Solution: Using Divide and Conquer master theorem, we get O(nlog2n).


Problem-30 Determine Θ bounds for the recurrence:

Solution: Substituting in the recurrence equation, we get:


, where k is a constant. This clearly
says Θ(n).
Problem-31 Determine Θ bounds for the recurrence relation: T(n) = T(⌈n/2⌉) + 7.
Solution: Using Master Theorem we get: Θ(logn).
Problem-32 Prove that the running time of the code below is Ω(logn).

Solution: The while loop will terminate once the value of ‘k’ is greater than or equal to the value
of ‘n’. In each iteration the value of ‘k’ is multiplied by 3. If i is the number of iterations, then ‘k’
has the value of 3i after i iterations. The loop is terminated upon reaching i iterations when 3i ≥ n
↔ i ≥ log3 n, which shows that i = Ω(logn).

Problem-33 Solve the following recurrence.

Solution: By iteration:

Note: We can use the Subtraction and Conquer master theorem for this problem.
Problem-34 Consider the following program:

Solution: The recurrence relation for the running time of this program is: T(n) = T(n – 1) + T(n –
2) + c. Note T(n) has two recurrence calls indicating a binary tree. Each step recursively calls the
program for n reduced by 1 and 2, so the depth of the recurrence tree is O(n). The number of
leaves at depth n is 2n since this is a full binary tree, and each leaf takes at least O(1)
computations for the constant factor. Running time is clearly exponential in n and it is O(2n).
Problem-35 Running time of following program?
Solution: Consider the comments in the function below:

In the above code, inner loop executes n/i times for each value of i. Its running time is
.
Problem-36 What is the complexity of
Solution: Using the logarithmic property, logxy = logx + logy, we can see that this problem is
equivalent to

This shows that the time complexity = O(nlogn).


Problem-37 What is the running time of the following recursive function (specified as a
function of the input value n)? First write the recurrence formula and then find its
complexity.

Solution: Consider the comments in the below function:


We can assume that for asymptotical analysis k = ⌈k⌉ for every integer k ≥ 1. The recurrence for
this code is . Using master theorem, we get T(n) = Θ(n).

Problem-38 What is the running time of the following recursive function (specified as a
function of the input value n)? First write a recurrence formula, and show its solution using
induction.

Solution: Consider the comments in the function below:

The if statement requires constant time [O(1)]. With the for loop, we neglect the loop overhead
and only count three times that the function is called recursively. This implies a time complexity
recurrence:

Using the Subtraction and Conquer master theorem, we get T(n) = Θ(3n).
Problem-39 Write a recursion formula for the running time T(n) of the function whose code
is below.

Solution: Consider the comments in the function below:

The recurrence for this piece of code is T(n) = T(.8n) + O(n) = T(4/5n) + O(n) =4/5 T(n) + O(n).
Applying master theorem, we get T(n) = O(n).
Problem-40 Find the complexity of the recurrence: T(n) = 2T( ) + logn
Solution: The given recurrence is not in the master theorem format. Let us try to convert this to the
master theorem format by assuming n = 2m. Applying the logarithm on both sides gives, logn =
mlogl ⇒ m = logn. Now, the given function becomes:

To make it simple we assume


.

Applying the master theorem format would result in S(m) = O(mlogm).


If we substitute m = logn back, T(n) = S(logn) = O((logn) loglogn).
Problem-41 Find the complexity of the recurrence: T(n) = T( )+1

Solution: Applying the logic of Problem-40 gives . Applying the master


theorem would result in S(m) = O(logm). Substituting m = logn, gives T(n) = S(logn) =
O(loglogn).
Problem-42 Find the complexity of the recurrence: T(n) = 2T( )+1

Solution: Applying the logic of Problem-40 gives: . Using the master


theorem results S(m) = . Substituting m = logn gives T(n) =O(logn).
Problem-43 Find the complexity of the below function.

Solution: Consider the comments in the function below:

For the above code, the recurrence function can be given as: T(n) = T( ) + 1. This is same as
that of Problem-41.
Problem-44 Analyze the running time of the following recursive pseudo-code as a function of
n.

Solution: Consider the comments in below pseudo-code and call running time of function(n) as
T(n).
Another Random Document on
Scribd Without Any Related Topics
They arrived at the broad gulley that Bambi had never been across.
The elder climbed down into it, Bambi tried to follow but it took him
a lot of effort to climb up the steep slope on the other side.

The fierce pain he felt began once more to go through him. He fell
over, pulled himself back up, fell over again and began to gasp for
breath.

“I can’t help you here,” said the elder, “you’ve got to get up here
yourself!” And Bambi did get up to the top. He began once more to
feel the hot band of pain that shot down his shoulder and felt for the
second time that he was losing his strength.

“You’re bleeding again,” said the elder, “that’s what I expected. It’s
not too much, though ... and ...,” he added in a whisper, “it doesn’t
matter any more.”

They made their way very slowly through a grove of beech trees, as
high as the sky. The ground was soft and smooth. It did not take too
much effort to go through it. Bambi yearned to just lay himself down
here, to stretch himself out and not to move a finger. He just could
not go any further. His head hurt, there was a buzzing in his ears,
his nerves were quivering and his fever began to shake him. His
eyes went dim. There was nothing more inside him than the
yearning for rest and a vague astonishment at how his life had
suddenly been interrupted and altered, at how he had once used to
go through the forest in good health and without injury ... just that
morning ... just an hour earlier ... it seemed to him now like the
happiness of a distant time that had long since vanished.

They passed through a low thicket of oaks and dogwood. The fallen
trunk of a beech tree lay across their path, deeply embedded in the
bushes. It was very big and they could see no way of getting past it.

“Now we’ve got there ...” Bambi heard the elder say. He walked the
length of the beech trunk and Bambi followed him, nearly falling into
a hole in the ground.
“Alright!” said the elder. “You can lie down here.”

Bambi sank down and did not try to move any more.

He saw that the hole in the ground under the fallen beech trunk was
deeper than it had seemed, creating a small chamber. The bushes at
the edge of it closed over him as he entered so that nobody could
see in. Once he was down there it was as if he had disappeared.

“You’ll be safe here,” said the elder. “Stay here and don’t go
anywhere.”

Days went by.

Bambi lay in the warm earth, the bark of the fallen tree slowly
rotting above him, it listened to his pain as it grew inside his body,
became stronger, then abated, became weaker and went down,
steadily softer and softer. Sometimes he would struggle outside
where he would stand, weak and unsteady, on his tired and
unreliable legs, and take a few steps to look for food. He began to
eat herbs that he had never before noticed. Now they had suddenly
begun to offer themselves to him, called to him with their scent that
had a strange and tempting sharpness. What he had until then
despised, what he would have thrown away if he inadvertently got it
between his lips, now seemed tasty and spicy. Many little leaves,
many short stalks continued to seem unappetizing even now, but he
nonetheless ate them under some kind of compulsion, and his
wounds healed more quickly and he could feel how his strength was
coming back to him.

He had been saved. But he still did not leave his chamber. He would
only come out at night and take a few steps around, but in the
daytime he would remain quietly in his bed. It was only now, when
his body was feeling no more pain, that Bambi realized all that had
happened to him, he was able to think once more, and a feeling of
great horror arose within him, his character had been shattered. He
was not able to simply wipe it away, not able to stand up and run
about as he had before. He lay there and felt many emotions,
alternately disgusted, ashamed, astonished, disheartened, but soon
afterwards full of melancholy, soon afterwards full of happiness.

The elder was nearby at all times. At first he was at Bambi’s side day
and night. Then there were times when he left him alone for short
periods, especially when he saw that Bambi was lost in his thoughts.
But there was no time when he was not close by.

One day there had been storm and thunder and lightning, the sky
had been swept clean and that evening the sun, as it went down,
shone over a sky that was blue. The blackbirds sang out loudly from
the tree tops, the finches flapped their wings, the tits whispered in
the undergrowth, in the grass and under the bushes close to the
ground the metallic bursts of the pheasants’ cries could be heard,
the woodpecker laughed in loud celebration and the pigeons cooed
from the yearning for love that was inside them.

Bambi stepped out from his underground chamber. Life was good.
The elder was standing there as if he had been waiting.

The wandered slowly off together.

But Bambi never went back across that gulley, never went back to
see the others.
CHAPTER 23
One night, when the autumn leaves were falling and whispering
through the whole of the forest, the tawny owl gave his shrill cry
through the tree tops. Then he waited.

But Bambi had already seen him in the distance through the now
sparse foliage and now he kept still.

The owl flew closer and gave his shrill cry even louder. Then he
waited. But this time too, Bambi said nothing.

The owl could not hold back any longer. “Aren’t you startled, then?”
he asked discontentedly.

“Oh, yes,” Bambi answered gently. “A little bit.”

“Well ...,” the owl grumbled, “only a little bit? You always used to be
terribly shocked. It was always such a pleasure to see how shocked
you were. What’s happened then, what’s happened that means your
only a little bit shocked ...?”

He was annoyed and repeated, “just a little bit ...”

The owl had grown old, and that had made him even more vain and
even more sensitive than he had been.

Bambi wanted to answer; I was never startled before, either, but I


just said I was because I knew you liked it. But he decided he would
rather keep this information to himself. He felt sorry for the good old
owl, as he sat there being cross. He did his best to calm him down.
“Maybe it’s because I was just thinking about you,” he said.
“What?” The owl became cheerful again. “What? You were thinking
about me?”

“Yes,” answered Bambi hesitantly, “just when began to screech.


Otherwise, of course, I would have been just as startled as ever.”

“Really?” the owl purred.

Bambi could not resist. What harm could there be in it? Let the little
old boy have some pleasure.

“Really,” he confirmed and went on .”.. it pleases me ... it goes


through all my limbs when I suddenly hear you like that.”

The owl puffed up his feathers, turned himself into a soft, brown and
light grey, fluffy ball, and he was very pleased. “That’s very nice of
you to have been thinking about me ... very nice indeed ...” he
cooed gently. “It’s such a long time since we saw each other.”

“A very long time,” said Bambi.

“Maybe it’s that you don’t go along the same old paths any more?”
enquired the owl.

“No ...,” Bambi spoke slowly, “I don’t go along the same old paths
any more.”

“I’ve been seeing a lot more of the world too lately,” remarked the
owl, puffing his chest out. He did not tell Bambi that he had been
driven out of the old territory he had inherited from his ancestors by
a young and reckless lad. “You can’t always stay on the same spot,”
he added. Then he waited for Bambi’s reply.

But Bambi had gone. By now he had learned the art of disappearing
in silence almost as well as the elder.
The owl was dismayed. “Shameless ...” he grumbled. He shook
himself, buried his beak into his plumage and philosophized to
himself; “You should never think you could make friends with these
posh types. They might seem ever so likeable ... but one day they’ll
shamelessly ... and then you sit there looking stupid, just like I am
now ...”

Suddenly he fell vertically down to the ground like a stone. He had


seen a mouse, which then, caught in his talons, had the time to
squeal just once. He tore the mouse into pieces because he was so
angry. He pulled the head off this mouthful quicker than he normally
would. And then he flew away. “What does Bambi matter to me?” he
thought. “What does any of those posh people matter to me?
Nothing. They don’t matter at all!” He started to screech. So shrill,
so long, that a pair of wood pigeons he passed by were woken up
and, with much loud flapping of wings, they fell out of where they
had been sleeping.

The storm blew through the woods for many days, tearing the last
of the leaves from the twigs and branches. The trees now stood
there naked.

In the grey of morning twilight Bambi was making his way home in
order to sleep together with the elder in their chamber.

A thin voice called to him, two times, three times in quick


succession. He stayed where he was. Then the squirrel swooped
down from the tree like lightning and sat on the ground in front of
him.

“It really is you, then!” he piped with respectful astonishment. “I


recognized you straight away when you passed by me, I didn’t really
want to believe it ...”

“How come you’re here ...?” Bambi asked.


The cheerful, little face in front of him took on a worried expression.
“The oak tree is gone ...” the squirrel began to complain, “my lovely
old oak tree ... do you remember? It’s terrible ... He’s cut it down.”

Bambi lowered his head in sadness. It really did hurt his soul to hear
about the wonderful ancient tree.

“It all happened so quickly,” the squirrel told him. “All of us who lived
on the old tree, we all ran away and we could only watch as He bit
through it with an enormous blinking tooth. The tree screamed out
loud from his wound. He just kept on screaming, and the tooth
screamed too ... it was horrible to hear it. Then that poor, lovely tree
fell over. Out onto the meadow ... it made all of us cry.”

Bambi was silent.

“Yes ...” said the squirrel with a sigh, “He can do anything ... He’s
omnipotent ...” He looked at Bambi with eyes wide open and pricked
up his ears, but Bambi was silent.

“We’ve all got nowhere to live now ...” the squirrel continued, “I
don’t even have any idea of where the others have got to ... I came
over here ... but it’ll take me ages to find another tree like that.”

“The old oak tree ...,” muttered Bambi to himself, “I’ve known it
since I was a child.”

“No ... but it’s good to see that it’s really you!” The squirrel became
quite contented. “We all thought you must have died a long time
ago. But there were some who said you were still alive ... some said
that someone or other had seen you ... but we couldn’t find out
anything definite, so we just supposed it was an empty rumour ...”
The squirrel looked at him searchingly. “Well, that was ... that was
because you didn’t come back.”

He sat there waiting for an answer, you could see that he was very
keen to know what had happened.
Bambi was silent. But he, too, felt a slight, anxious curiosity. He
wanted to ask. About Faline, about Aunt Ena, about Ronno and
Karus, about everyone he had known as a child. But he was silent.

The squirrel continued to sit in front of Bambi and examined him.


“Look at that crown!” he exclaimed in admiration. “What a crown!
Apart from the old prince, no-one has a crown like that, no-one
anywhere in the forest!”

Earlier, Bambi would have felt very pleased and flattered by an


observation like this. Now he just said wearily, “Yes ... I suppose so
...”

The squirrel nodded his head vigorously. “It really is!” he said in
astonishment. “Really. You’re beginning to go grey.”

Bambi walked away.

The squirrel saw that the discussion was at an end and swung up
into the branches. “Bye then,” he called down. “Look after yourself! I
enjoyed seeing you again. If I see any of your old friends I’ll tell
them you’re still alive ... they’ll all be glad to hear it.”

Bambi heard this and once again felt those slight stirrings in his
heart. But it said nothing. You have to stay alone, the elder had
taught him when Bambi was still a child. And the elder had shown
him many things, told him many secrets, and continued doing so up
to the present day. But of all the things he had been taught, this was
the most important: You have to stay alone. If you’re going to
preserve your life, if you want to understand existence, if you want
to become wise, you have to stay alone!

“But,” asked Bambi one time, “but what about the two of us, we’re
always together nowadays ...?”

“We soon won’t be,” the elder had retorted.


That had only been a few weeks earlier.

Now, it again occurred to Bambi, and it occurred to him very


suddenly, that the very first thing the elder had said to him had been
that he had to stay alone. That had been when Bambi was still a
child and was calling for his mother. Then the elder had come up to
him and asked, “Are you not able to be alone?”

Bambi walked on.


CHAPTER 24
The forest lay once more under snow and was silent under its thick,
white coat. All that could be heard was the cawing of the crows, only
now and then came the anxious croaking of a magpie or the shy,
gentle, twittering conversations of the tits. Then the frost became
harder, and everything was silent. Now, the coldness made the air
itself ring.

One morning the deep quiet was torn apart by the barking of dogs.

It was an incessant, hurried barking that drove its way quickly


through the forest, a sharp, curt and belligerent yapping that made
him sound insane.

In the chamber under the fallen beech trunk Bambi raised his head
and looked at the elder who was lying next to him.

The elder answered Bambi’s look. “It’s nothing, nothing that need
concern us.”

The two of them nonetheless listened.

They lay in their chamber, they had the old beech trunk as a
protective roof over them, icy draughts were kept out by the height
of the snow, and the tangle of bushes hid them like a dense grid
from any spying eye.

The barking came nearer, angry, breathless, heated. It could only


have been a small dog.

It came ever nearer. Now they could hear the gasping for breath at
twice the speed, and through the angry barking they heard a gentle
growling, as if from pain. Bambi became uneasy, but the elder again
said, “It’s nothing that need concern us.”

They remained still and quiet in the warmth of their chamber,


peering out to see what was happening outside.

The rustling in the twigs came ever nearer, snow fell from the
boughs as they were suddenly run past, a dust of snow was kicked
up from the ground.

Now it was possible to see who was coming.

Through snow and bushes, through roots and twigs there came,
jumping and creeping and sliding, the old fox.

Immediately after him the dog broke through. It was a very small
dog on short legs.

One of the fox’s front legs was broken and just above the break his
fur was ripped open. He held the broken leg high up in front of him,
blood was spurting from his wounds, his breath was wheezy, his
eyes were staring far ahead because of his horror and the efforts he
was having to make. He was beside himself with terror and panic, he
was confused and exhausted. He swung round in a swiping
movement, which startled the dog so that he stepped back a few
paces.

The fox sat down on his hind legs. He could go no further. He held
the shot foreleg up in a way that was pitiful, his mouth was open,
sucking in his cheeks he spat at the dog.

He, though, was not quiet for a moment. His high, shrill voice now
became fuller and deeper. “Here!” he shouted. Here! Here he is!
Here! Here! Here!” He was not shouting at the fox, at that moment
he was not speaking to him at all but was clearly calling to
somebody else who was still a long way away.
Bambi and the elder were both aware that it was Him whom the dog
was calling.

The fox knew it too. The blood was now gushing down from his
breast and into the snow and built up a gently steaming, scarlet
stain on the icy-white layer.

The fox seemed to be having a mild fit. His shattered foreleg had no
strength in it and it sank down, but when it touched the cold snow a
burning pain shot through it. Arduously, he raised it up and held it,
jittering, in the air in front of him.

“Leave me alone ...” he began to say. “Leave me alone ...”. He spoke


quietly and imploringly. He was very dull and disheartened.

“No! No! No!” the dog threw back at him in a malevolent howl.

“I beg of you ...” said the fox, “I can’t go any further ... I’ve had it ..
just let me go ... let me go home ... at least let me die in peace ...”

“No! No! No!” the dog howled.

The fox begged him even harder. “But we’re related ...” he lamented,
“we’re almost brothers ... let me go home ... let me die among my
own folk ... we ... we’re almost brothers ... you and me ...”.

“No! No! No!” the dog said excitedly.

Now the fox sat upright. His lovely pointed snout sank down to his
bloodied breast, his eyes rose up and stared at the dog right into his
face . In a quite different voice, in control of himself, sad and bitter,
he snarled, “Aren’t you ashamed of yourself ...? You traitor!”

“No! No! No!” the dog yelled.

The fox, however went on. “You turncoat ... you defector!” His
lacerated body became stiff with hatred and contempt. “You’re just
His henchman,” he hissed. “You miserable ... you seek us out where
He couldn’t find us ... you persecute us in places that He can’t get to
... you turn us in ..., and all of us are your relatives ... you turn me
in, and you and I are nearly brothers ... and you just stand there
...are you not ashamed of yourself?”

Suddenly many loud, new voices were heard around them.

“Traitor!” called the magpies from the trees.

“Henchman!” screeched the jays.

“Miserable!” squealed the weasel.

“Defector!” spat the polecat.

Shrill hisses and screeches came out from all the trees and bushes,
and from the air came the screeching of the crows, “henchman!” All
had hurried close, all had listened to the quarrel from the trees
above or from a safe hiding place on the ground. The disgust
expressed by the fox released the old, bitter disgust that they all felt,
and the blood steaming in sight of them on the snow made them
furious and made them lose all their reserve.

The dog looked around him. “You!” he called. “What do you want?
What do you know about it? What are you talking about? All o’ you
belong to ‘Im, just like I belong to ‘Im! But me ... well I love ‘Im, I
pray to ‘Im! I serve ‘Im! But you, you don’t know that ‘E’s in charge
‘ere. You’re pitiful you are, you can’t rebel against ‘Im? ‘E’s the
almighty! ‘E’s above all of us! Ev’rything you’ve got comes from ‘Im!
E’vrything that grows and lives, it all comes from ‘Im.” The dog was
shaking in his outrage.

“Traitor!” the squirrel screamed.

“Yes!” hissed the fox. “You’re a traitor. Nobody but you ... you’re the
only one ...!”
They danced about in self-righteous anger. “I’m the only one ...? You
liar! D’you think there aren’t loads and loads of others who are with
‘Im ...? The ‘orse ... the cows ... the lamb ... the chickens ... and
some of all of you, all your species, there are loads who are with
‘Im, who pray to ‘im ... and serve ‘Im!”

“Rabble!” hissed the fox, full of boundless contempt.

The dog could control himself no longer and hurled himself at the
fox’s throat. A snarling, spitting, gasping bundle, wild and whirring
they rolled in the snow, snapping at each other, hair flew up, snow
flew up, fine drops of blood flew up. But the fox was not able to
maintain the fight for long. After just a few seconds he lay there on
his back, showed his pale belly, twitched, stretched himself out, and
died.

The dog shook him a few more times, then dropped him into the
churned up snow, stood there with his legs wide apart and once
more called out in a full, deep voice, “There! There! There he is!”

The others were disgusted and fled away in all directions.

“Horrible ...” said Bambi in his chamber to the elder.

“Worst of all,” the elder replied, “is that they believe in what the dog
just said. They believe it, they live a life full of fear, they hate Him
and they hate themselves ... and they kill themselves for his sake.”
CHAPTER 25
There came a break in the cold and a pause in the middle of winter.
The Earth drank in the melting snow in great draughts, so that broad
stretches of naked earth could be seen everywhere. The blackbirds
were not singing yet but when they flew up from the ground where
they had been hunting for worms, or when they flapped from tree to
tree, they let out a long, shrill, cheerful cry which was almost like
birdsong. The woodpecker began to laugh here and there, magpies
and crows became more chatty, the tits talked gaily with each other,
and the pheasants, when they had swung down from the trees
where they had been sleeping, now remained in one spot for almost
as long as they would in the good times, they would shake their
plumage in the morning sunshine and continually burst out with
their metallic cry.

On mornings like this Bambi would range out further afield than he
normally would. When the sun had barely risen he arrived at his
chamber under the beech tree. Over on the other side, there where
he had used to live, there was something moving. Bambi remained
hidden in the undergrowth and watched. He was right, someone of
his own species was moving about there, seeking out the patches
that were free of snow and setting about the early-risen grasses.

At first, Bambi wanted to turn round and go away, but then he saw
that it was Faline. His first urge was to jump forward and call to her.
But he stayed where he was as if rooted to the spot. It was so long
since he had last seen Faline. His heart began to beat hotly. Faline
was walking slowly, as if she were tired or sad. She looked like her
mother now, looked like Aunt Ena, and when Bambi noticed this it
was with painful astonishment.
Faline raised her head and looked in his direction, as if she could feel
that he was near.

Again, Bambi felt the urge to go toward her, but, again, he stayed
where he was, powerless and lame, he was unable to move.

He saw that Faline had become old and grey.

Gay and audacious little Faline, he thought, she used to be so


beautiful, so nimble. His entire childhood suddenly shimmered up in
him. The meadow, the paths his mother led him along, the happy
games with Gobo and Faline, the good grasshopper and the
butterfly, the struggle with Karus and Ronno by which he had won
Faline for himself. He suddenly felt happy again, but nonetheless
shaken.

Over there, Faline was walking away with her head sunk down to the
ground, slow, tired and sad. At that moment Bambi loved her with a
gush of tender pity, he wanted to cross through the hole under the
beech trunk, which for so long had separated him from her and from
the others, wanted to fetch her back, to talk to her about the time
when they had been children, above all to talk about the past.

As he thought this he watched her as she went on through the bare


bushes and finally disappeared from sight.

He stood there for a long time, looking in her direction.

A clap of thunder crashed. Bambi was startled.

That was here, on this side of the hole. Not very close, but here, on
the side where he was.

Another crash of thunder came, and then another.

Bambi made a few steps deeper back into the thicket, where he kept
still and listened. Everything was quiet. He crept carefully home.
The elder was already there, but had not gone down into their
chamber, he just stood next to the fallen beech trunk as if he had
been waiting.

“Where have you been all this time?” he asked, and he was so
serious that Bambi remained silent. “Did you hear that, just now?”
the elder went on after a pause.

“Yes,” Bambi answered. “Three times. He’s in the forest.”

“Clearly ...,” the elder nodded, and he repeated, with a strange


inflexion, “He is in the forest ... we need to go.”

“Where?” Bambi could not stop himself from asking.

“Over there,” said the elder, and his voice was heavy. “Over there
where He is now.”

Bambi was alarmed.

“Don’t be frightened,” the elder went on. “Come with me now and
don’t be afraid. I’m glad I’ve got the chance to take you there and
let you see it ...” He hesitated and gently added, “before I go.”

Bambi was taken aback at this and stared at the elder. He suddenly
became aware of how frail he looked; his head was now entirely
white, his face had become very gaunt, his beautiful eyes had lost
their sparkle, they had taken on a dull green appearance and
seemed to be somehow broken.

Bambi and the elder did not go far, they could feel the first winds of
a heavy storm blowing at them, a storm that was capable of putting
so much threat and dread into their hearts.

Bambi stopped, but the elder carried on walking, directly towards


the storm. Bambi hesitantly followed behind him.
The scent of the storm came at them in ever stronger waves and
drew them forward. The elder went straight on. Thoughts of flight
had sprung into Bambi, he could feel tension in his breast which
boiled through his head and all his limbs. They nearly tore him away
from the place. He stayed strong and continued to walk behind the
elder.

Now this malevolent storm had swollen up into something so mighty


that there was nothing else it was possible to feel, and so that it was
now barely possible to breathe.

“There!” said the elder, and he stepped to one side.

Two steps away from them, He lay there on the ground on bent and
broken bushes and in churned up snow.

Bambi half-suppressed a scream of horror, and with a sudden jump


he fled, as he had already been wishing to do . He was nearly out of
his senses in terror.

“Stop!” he heard the elder call. He looked back and saw that the
elder was calmly standing there where He was lying on the ground.
Beside himself in astonishment, Bambi stepped closer, compelled by
his obedience, by his boundless curiosity, by his quaking anticipation.

“Come closer ... don’t be afraid,” the elder said.

There He lay, his pale uncovered face looking upwards, His hat a
little to the side of him in the snow, and Bambi, who knew nothing
about hats, thought that that awful head had been struck into two
pieces.

The hunter’s neck was exposed and showed a wound as if it had


been cut through. It lay open like a little red mouth. There was still a
gentle flow of blood from it, blood was in His hair, under His nose,
and had formed a large pool in the snow, melting it with its warmth.
“Here we are then,” the elder quietly began, “we’re standing right
beside Him ... and where’s the danger now?”

Bambi looked down at Him as he lay there, His form, His limbs, His
hair all seemed to Bambi to be something gruesome but puzzling.
He looked into those broken eyes that stared sightlessly back up at
him, and he did not understand.

“Bambi,” the elder continued, “do you remember what Gobo said,
what the dog said, about what everyone believed ... do you
remember?”

Bambi was incapable of giving an answer.

“You can see him there, Bambi,” the elder went on, “you can see
Him lying there like any one of us. Listen to me, Bambi, He is not
almighty like they say he is. He is not the source from which
everything comes, everything that grows and lives. He is not our
superior! He is beside us, He is like us, and just like us He knows
fear and need and sorrow. He can be overcome just like us and now
He lies helpless on the ground, just like the rest of us, just as you
see Him now.”

They remained silent.

“Do you understand me, Bambi?” the elder asked.

Bambi answered in a whisper, “I think ...”

“Tell me what you think, then!” the elder ordered him.

Bambi blushed and quaked and said, “There’s someone else who is
above all of us, ... above us and above Him.”

“The time has come, then, when I can go,” the elder said.

He turned round and the two of them wandered on for a little while.
At a tall ash tree the elder stopped. “Don’t come with me any more,
Bambi,” he began, in a calm voice, “my time is up. Now I need to
find a place for the end ...”

Bambi was about to say something.

“No,” the elder stopped him. “No ... at the time I am now
approaching each of us is alone. Fare well, my son ... I have loved
you very much.”

The summer’s day started being hot as soon as the sun had risen,
no wind, no chill of twilight. The sun seemed to be in more of a
hurry that day. It rose quickly into the sky and broke out its dazzling
flames like a dreadful blaze.

The dew on the meadow and on the bushes quickly evaporated; the
earth became very dry and crumbly. In the woods it became quiet
before its usual time. Only the woodpecker could be heard laughing
here and there, and only the pigeons cooed in tireless, fervent
tenderness.

Deep in a thicket there was a little, hidden clearing, giving a little


free space, and that is where Bambi was standing. Around his head
a swarm of midges danced and sang in the sunshine. From the
leaves of the hazel bush beside him came a quiet buzzing, it came
closer, and a big cockchafer flew slowly past him, straight through
the swarm of midges, higher and higher up to the top of a tree
where he intended to sleep until evening. His elegant wing covers
stuck out from him and his wings were bursting with power.

“Did you see him ...?” the midges asked each other. “That’s the
elder,” said one of them. And the others sang, “All of his relatives are
already dead, but he’s still alive.”

A couple of very small midges asked, “How long do you think he’s
going to live?” The others sang their answer, “We don’t know. He’s
outlived all of his family ... he’s very old ... very old.”
Bambi walked on. The song of midges, he thought, song of midges
... A tender, anxious call came through to him. The voice of
somebody of his own species. “Mother! ... mother!”

Before they understood what was happening, Bambi was standing


there before them. Speechless, they stared at him. “Your mother
does not have the time now,” Bambi told them sternly. He looked in
the little one’s eye. “Can’t you be by yourself for a while?”

The little one and his sister remained silent.

Bambi turned away, slipped into the nearest bush and disappeared,
even before two of them could understand what had happened. He
walked on. “I like that lad ...” he thought. “Maybe I’ll meet him again
when he’s a bit bigger ...” He walked on. “And the little lass,” he
thought,” she’s nice too ... that’s what Faline looked like when she
was a child.”

He walked on and disappeared into the woods.


*** END OF THE PROJECT GUTENBERG EBOOK BAMBI ***

Updated editions will replace the previous one—the old editions will
be renamed.

Creating the works from print editions not protected by U.S.


copyright law means that no one owns a United States copyright in
these works, so the Foundation (and you!) can copy and distribute it
in the United States without permission and without paying
copyright royalties. Special rules, set forth in the General Terms of
Use part of this license, apply to copying and distributing Project
Gutenberg™ electronic works to protect the PROJECT GUTENBERG™
concept and trademark. Project Gutenberg is a registered trademark,
and may not be used if you charge for an eBook, except by following
the terms of the trademark license, including paying royalties for use
of the Project Gutenberg trademark. If you do not charge anything
for copies of this eBook, complying with the trademark license is
very easy. You may use this eBook for nearly any purpose such as
creation of derivative works, reports, performances and research.
Project Gutenberg eBooks may be modified and printed and given
away—you may do practically ANYTHING in the United States with
eBooks not protected by U.S. copyright law. Redistribution is subject
to the trademark license, especially commercial redistribution.

START: FULL LICENSE


THE FULL PROJECT GUTENBERG LICENSE
PLEASE READ THIS BEFORE YOU DISTRIBUTE OR USE THIS WORK

To protect the Project Gutenberg™ mission of promoting the free


distribution of electronic works, by using or distributing this work (or
any other work associated in any way with the phrase “Project
Gutenberg”), you agree to comply with all the terms of the Full
Project Gutenberg™ License available with this file or online at
www.gutenberg.org/license.

Section 1. General Terms of Use and


Redistributing Project Gutenberg™
electronic works
1.A. By reading or using any part of this Project Gutenberg™
electronic work, you indicate that you have read, understand, agree
to and accept all the terms of this license and intellectual property
(trademark/copyright) agreement. If you do not agree to abide by all
the terms of this agreement, you must cease using and return or
destroy all copies of Project Gutenberg™ electronic works in your
possession. If you paid a fee for obtaining a copy of or access to a
Project Gutenberg™ electronic work and you do not agree to be
bound by the terms of this agreement, you may obtain a refund
from the person or entity to whom you paid the fee as set forth in
paragraph 1.E.8.

1.B. “Project Gutenberg” is a registered trademark. It may only be


used on or associated in any way with an electronic work by people
who agree to be bound by the terms of this agreement. There are a
few things that you can do with most Project Gutenberg™ electronic
works even without complying with the full terms of this agreement.
See paragraph 1.C below. There are a lot of things you can do with
Project Gutenberg™ electronic works if you follow the terms of this
agreement and help preserve free future access to Project
Gutenberg™ electronic works. See paragraph 1.E below.
1.C. The Project Gutenberg Literary Archive Foundation (“the
Foundation” or PGLAF), owns a compilation copyright in the
collection of Project Gutenberg™ electronic works. Nearly all the
individual works in the collection are in the public domain in the
United States. If an individual work is unprotected by copyright law
in the United States and you are located in the United States, we do
not claim a right to prevent you from copying, distributing,
performing, displaying or creating derivative works based on the
work as long as all references to Project Gutenberg are removed. Of
course, we hope that you will support the Project Gutenberg™
mission of promoting free access to electronic works by freely
sharing Project Gutenberg™ works in compliance with the terms of
this agreement for keeping the Project Gutenberg™ name associated
with the work. You can easily comply with the terms of this
agreement by keeping this work in the same format with its attached
full Project Gutenberg™ License when you share it without charge
with others.

This particular work is one of the few individual works protected by


copyright law in the United States and most of the remainder of the
world, included in the Project Gutenberg collection with the
permission of the copyright holder. Information on the copyright
owner for this particular work and the terms of use imposed by the
copyright holder on this work are set forth at the beginning of this
work.

1.D. The copyright laws of the place where you are located also
govern what you can do with this work. Copyright laws in most
countries are in a constant state of change. If you are outside the
United States, check the laws of your country in addition to the
terms of this agreement before downloading, copying, displaying,
performing, distributing or creating derivative works based on this
work or any other Project Gutenberg™ work. The Foundation makes
no representations concerning the copyright status of any work in
any country other than the United States.
1.E. Unless you have removed all references to Project Gutenberg:

1.E.1. The following sentence, with active links to, or other


immediate access to, the full Project Gutenberg™ License must
appear prominently whenever any copy of a Project Gutenberg™
work (any work on which the phrase “Project Gutenberg” appears,
or with which the phrase “Project Gutenberg” is associated) is
accessed, displayed, performed, viewed, copied or distributed:

This eBook is for the use of anyone anywhere in the United


States and most other parts of the world at no cost and with
almost no restrictions whatsoever. You may copy it, give it away
or re-use it under the terms of the Project Gutenberg License
included with this eBook or online at www.gutenberg.org. If you
are not located in the United States, you will have to check the
laws of the country where you are located before using this
eBook.

1.E.2. If an individual Project Gutenberg™ electronic work is derived


from texts not protected by U.S. copyright law (does not contain a
notice indicating that it is posted with permission of the copyright
holder), the work can be copied and distributed to anyone in the
United States without paying any fees or charges. If you are
redistributing or providing access to a work with the phrase “Project
Gutenberg” associated with or appearing on the work, you must
comply either with the requirements of paragraphs 1.E.1 through
1.E.7 or obtain permission for the use of the work and the Project
Gutenberg™ trademark as set forth in paragraphs 1.E.8 or 1.E.9.

1.E.3. If an individual Project Gutenberg™ electronic work is posted


with the permission of the copyright holder, your use and distribution
must comply with both paragraphs 1.E.1 through 1.E.7 and any
additional terms imposed by the copyright holder. Additional terms
will be linked to the Project Gutenberg™ License for all works posted
with the permission of the copyright holder found at the beginning
of this work.
1.E.4. Do not unlink or detach or remove the full Project
Gutenberg™ License terms from this work, or any files containing a
part of this work or any other work associated with Project
Gutenberg™.

1.E.5. Do not copy, display, perform, distribute or redistribute this


electronic work, or any part of this electronic work, without
prominently displaying the sentence set forth in paragraph 1.E.1
with active links or immediate access to the full terms of the Project
Gutenberg™ License.

1.E.6. You may convert to and distribute this work in any binary,
compressed, marked up, nonproprietary or proprietary form,
including any word processing or hypertext form. However, if you
provide access to or distribute copies of a Project Gutenberg™ work
in a format other than “Plain Vanilla ASCII” or other format used in
the official version posted on the official Project Gutenberg™ website
(www.gutenberg.org), you must, at no additional cost, fee or
expense to the user, provide a copy, a means of exporting a copy, or
a means of obtaining a copy upon request, of the work in its original
“Plain Vanilla ASCII” or other form. Any alternate format must
include the full Project Gutenberg™ License as specified in
paragraph 1.E.1.

1.E.7. Do not charge a fee for access to, viewing, displaying,


performing, copying or distributing any Project Gutenberg™ works
unless you comply with paragraph 1.E.8 or 1.E.9.

1.E.8. You may charge a reasonable fee for copies of or providing


access to or distributing Project Gutenberg™ electronic works
provided that:

• You pay a royalty fee of 20% of the gross profits you derive
from the use of Project Gutenberg™ works calculated using the
method you already use to calculate your applicable taxes. The
fee is owed to the owner of the Project Gutenberg™ trademark,
but he has agreed to donate royalties under this paragraph to
the Project Gutenberg Literary Archive Foundation. Royalty
payments must be paid within 60 days following each date on
which you prepare (or are legally required to prepare) your
periodic tax returns. Royalty payments should be clearly marked
as such and sent to the Project Gutenberg Literary Archive
Foundation at the address specified in Section 4, “Information
about donations to the Project Gutenberg Literary Archive
Foundation.”

• You provide a full refund of any money paid by a user who


notifies you in writing (or by e-mail) within 30 days of receipt
that s/he does not agree to the terms of the full Project
Gutenberg™ License. You must require such a user to return or
destroy all copies of the works possessed in a physical medium
and discontinue all use of and all access to other copies of
Project Gutenberg™ works.

• You provide, in accordance with paragraph 1.F.3, a full refund of


any money paid for a work or a replacement copy, if a defect in
the electronic work is discovered and reported to you within 90
days of receipt of the work.

• You comply with all other terms of this agreement for free
distribution of Project Gutenberg™ works.

1.E.9. If you wish to charge a fee or distribute a Project Gutenberg™


electronic work or group of works on different terms than are set
forth in this agreement, you must obtain permission in writing from
the Project Gutenberg Literary Archive Foundation, the manager of
the Project Gutenberg™ trademark. Contact the Foundation as set
forth in Section 3 below.

1.F.

1.F.1. Project Gutenberg volunteers and employees expend


considerable effort to identify, do copyright research on, transcribe
and proofread works not protected by U.S. copyright law in creating
the Project Gutenberg™ collection. Despite these efforts, Project
Gutenberg™ electronic works, and the medium on which they may
be stored, may contain “Defects,” such as, but not limited to,
incomplete, inaccurate or corrupt data, transcription errors, a
copyright or other intellectual property infringement, a defective or
damaged disk or other medium, a computer virus, or computer
codes that damage or cannot be read by your equipment.

1.F.2. LIMITED WARRANTY, DISCLAIMER OF DAMAGES - Except for


the “Right of Replacement or Refund” described in paragraph 1.F.3,
the Project Gutenberg Literary Archive Foundation, the owner of the
Project Gutenberg™ trademark, and any other party distributing a
Project Gutenberg™ electronic work under this agreement, disclaim
all liability to you for damages, costs and expenses, including legal
fees. YOU AGREE THAT YOU HAVE NO REMEDIES FOR
NEGLIGENCE, STRICT LIABILITY, BREACH OF WARRANTY OR
BREACH OF CONTRACT EXCEPT THOSE PROVIDED IN PARAGRAPH
1.F.3. YOU AGREE THAT THE FOUNDATION, THE TRADEMARK
OWNER, AND ANY DISTRIBUTOR UNDER THIS AGREEMENT WILL
NOT BE LIABLE TO YOU FOR ACTUAL, DIRECT, INDIRECT,
CONSEQUENTIAL, PUNITIVE OR INCIDENTAL DAMAGES EVEN IF
YOU GIVE NOTICE OF THE POSSIBILITY OF SUCH DAMAGE.

1.F.3. LIMITED RIGHT OF REPLACEMENT OR REFUND - If you


discover a defect in this electronic work within 90 days of receiving
it, you can receive a refund of the money (if any) you paid for it by
sending a written explanation to the person you received the work
from. If you received the work on a physical medium, you must
return the medium with your written explanation. The person or
entity that provided you with the defective work may elect to provide
a replacement copy in lieu of a refund. If you received the work
electronically, the person or entity providing it to you may choose to
give you a second opportunity to receive the work electronically in
lieu of a refund. If the second copy is also defective, you may
demand a refund in writing without further opportunities to fix the
problem.

1.F.4. Except for the limited right of replacement or refund set forth
in paragraph 1.F.3, this work is provided to you ‘AS-IS’, WITH NO
OTHER WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR ANY PURPOSE.

1.F.5. Some states do not allow disclaimers of certain implied


warranties or the exclusion or limitation of certain types of damages.
If any disclaimer or limitation set forth in this agreement violates the
law of the state applicable to this agreement, the agreement shall be
interpreted to make the maximum disclaimer or limitation permitted
by the applicable state law. The invalidity or unenforceability of any
provision of this agreement shall not void the remaining provisions.

1.F.6. INDEMNITY - You agree to indemnify and hold the Foundation,


the trademark owner, any agent or employee of the Foundation,
anyone providing copies of Project Gutenberg™ electronic works in
accordance with this agreement, and any volunteers associated with
the production, promotion and distribution of Project Gutenberg™
electronic works, harmless from all liability, costs and expenses,
including legal fees, that arise directly or indirectly from any of the
following which you do or cause to occur: (a) distribution of this or
any Project Gutenberg™ work, (b) alteration, modification, or
additions or deletions to any Project Gutenberg™ work, and (c) any
Defect you cause.

Section 2. Information about the Mission


of Project Gutenberg™
Project Gutenberg™ is synonymous with the free distribution of
electronic works in formats readable by the widest variety of
computers including obsolete, old, middle-aged and new computers.
It exists because of the efforts of hundreds of volunteers and
donations from people in all walks of life.

Volunteers and financial support to provide volunteers with the


assistance they need are critical to reaching Project Gutenberg™’s
goals and ensuring that the Project Gutenberg™ collection will
remain freely available for generations to come. In 2001, the Project
Gutenberg Literary Archive Foundation was created to provide a
secure and permanent future for Project Gutenberg™ and future
generations. To learn more about the Project Gutenberg Literary
Archive Foundation and how your efforts and donations can help,
see Sections 3 and 4 and the Foundation information page at
www.gutenberg.org.

Section 3. Information about the Project


Gutenberg Literary Archive Foundation
The Project Gutenberg Literary Archive Foundation is a non-profit
501(c)(3) educational corporation organized under the laws of the
state of Mississippi and granted tax exempt status by the Internal
Revenue Service. The Foundation’s EIN or federal tax identification
number is 64-6221541. Contributions to the Project Gutenberg
Literary Archive Foundation are tax deductible to the full extent
permitted by U.S. federal laws and your state’s laws.

The Foundation’s business office is located at 809 North 1500 West,


Salt Lake City, UT 84116, (801) 596-1887. Email contact links and up
to date contact information can be found at the Foundation’s website
and official page at www.gutenberg.org/contact

Section 4. Information about Donations to


the Project Gutenberg Literary Archive
Foundation
Project Gutenberg™ depends upon and cannot survive without
widespread public support and donations to carry out its mission of
increasing the number of public domain and licensed works that can
be freely distributed in machine-readable form accessible by the
widest array of equipment including outdated equipment. Many
small donations ($1 to $5,000) are particularly important to
maintaining tax exempt status with the IRS.

The Foundation is committed to complying with the laws regulating


charities and charitable donations in all 50 states of the United
States. Compliance requirements are not uniform and it takes a
considerable effort, much paperwork and many fees to meet and
keep up with these requirements. We do not solicit donations in
locations where we have not received written confirmation of
compliance. To SEND DONATIONS or determine the status of
compliance for any particular state visit www.gutenberg.org/donate.

While we cannot and do not solicit contributions from states where


we have not met the solicitation requirements, we know of no
prohibition against accepting unsolicited donations from donors in
such states who approach us with offers to donate.

International donations are gratefully accepted, but we cannot make


any statements concerning tax treatment of donations received from
outside the United States. U.S. laws alone swamp our small staff.

Please check the Project Gutenberg web pages for current donation
methods and addresses. Donations are accepted in a number of
other ways including checks, online payments and credit card
donations. To donate, please visit: www.gutenberg.org/donate.

Section 5. General Information About


Project Gutenberg™ electronic works
Welcome to Our Bookstore - The Ultimate Destination for Book Lovers
Are you passionate about books and eager to explore new worlds of
knowledge? At our website, we offer a vast collection of books that
cater to every interest and age group. From classic literature to
specialized publications, self-help books, and children’s stories, we
have it all! Each book is a gateway to new adventures, helping you
expand your knowledge and nourish your soul
Experience Convenient and Enjoyable Book Shopping Our website is more
than just an online bookstore—it’s a bridge connecting readers to the
timeless values of culture and wisdom. With a sleek and user-friendly
interface and a smart search system, you can find your favorite books
quickly and easily. Enjoy special promotions, fast home delivery, and
a seamless shopping experience that saves you time and enhances your
love for reading.
Let us accompany you on the journey of exploring knowledge and
personal growth!

ebookball.com

You might also like