CSC 402 Lecture Note 2023
CSC 402 Lecture Note 2023
APPLICATION DOMAINS
In this section, we briefly discuss a few of the most common areas of computer applications
and their associated languages.
1. Scientific Applications
2. Data processing Applications
3. Text processing Applications
4. Artificial intelligence Applications
5. Systems Programming Applications
6. Web software
SCIENTIFIC APPLICATIONS can be characterized as those which predominantly
manipulate numbers and arrays of numbers, using mathematical and statistical
principles as a basis for the algorithms. These algorithms encompass such problem as
statistical significance test, linear programming, regression analysis and numerical
approximations for the solution of differential and integral equations. Eg. FORTRAN,
Pascal, Python, R and MAT LAB are programming languages that can be used here.
DATA PROCESSING APPLICATIONS can be characterized as those programming
1|Page
problems whose predominant interest is in the creation, maintenance, extraction and
summarization of data in records and files. COBOL is a programming language that can
be used for data processing applications. Other examples are Spark (Pyspark/Scala
Spark), SQL (Structured Query Language), Scala, Shell Scripting (e.g., Bash) and Ruby.
TEXT PROCESSING APPLICATIONS are characterized as those whose principal
activity involves the manipulation of natural language text, rather than numbers as their
data. SNOBOL and C language have strong text processing capabilities. Python Libraries
like NLTK, spaCy, and TextBlob make it a popular choice for tasks like sentiment analysis, text
summarization, and language translation. JavaScript, Perl, Go (Golang) and Rust.
ARTIFICIAL INTELLIGENCE APPLICATIONS are characterized as those
programs which are designed principally to emulate intelligent behavior. They include
game playing algorithms such as chess, natural language understanding programs,
computer vision, robotics and expert systems. LISP has been the predominant AI
programming language, and also PROLOG using the principle of ‘’Logic programming’’
Lately AI applications are written in Java, c++ and python.
SYSTEMS PROGRAMMING APPLICATIONS involve developing those programs
that interface the computer system (the hardware) with the programmer and the operator.
These programs include compilers, assembles, interpreters, input-output routines,
program management facilities and schedules for utilizing and serving the various
resources that comprise the system. Ada and Modula – 2 are examples of programming
languages used here. Also is C, C++, Rust, Ada, Assembly Language and Swift.
WEB SOFTWARE
Edectio collection of languages which include:
- Markup (e.g. XHTML)
- Scripting for dynamic content under which we have the
o Client side, using scripts embedded in the XHTML documents e.g.
Javascript, PHP
o Server side, using the commonGateway interface e.g. JSP, ASP, PHP
General- purpose, executed on the web server through cGI e.g. Java, C++. Others are
Dart, JavaScript, and Python Frameworks like Django and Flask are popular for building
web applications
Language evaluation criteria and the characteristics that affect them
1. Expressivity
2. Well – refinedness’
3. Data types and structures
4. Modularity
5. Input-Output facilities
6. Portability
7. Efficiency
8. Pedagogy
9. Generality
2|Page
Expressivity means the ability of a language to clearly reflect the meaning intended by the
algorithm designer (the programmer). Thus an “expressive” language permits an utterance to
be compactly stated, and encourages the use of statement forms associated with structured
programming (usually “while “loops and “if – then – else” statements).
By “well-definiteness”, we mean that the language’s syntax and semantics are free of
ambiguity, are internally consistent and complete. Thus the implementer of a well- defined
language should have, within its definition a complete specification of all the language’s
expressive forms and their meanings. The programmer, by the same virtue should be able to
predict exactly the behavior of each expression before it is actually executed.
By “Data types and Structures”, we mean the ability of a language to support a variety of data
values (integers, real, strings, pointers etc.) and non-elementary collections of these.
Modularity has two aspects: the language’s support for sub-programming and the language’s
extensibility in the sense of allowing programmer – defined operators and data types. By sub
programming, we mean the ability to define independent procedures and functions
(subprograms), and communicate via parameters or global variables with the invoking
program.
In evaluating a language’s “Input-Output facilities” we are looking at its support for
sequential, indexed, and random-access files, as well as its support for database and
information retrieval functions.
A language which has “portability” is one which is implemented on a variety of computers.
That is, its design is relatively” machine – independent”. Languages which are well- defined
tend to be more portable than others.
An “efficient” language is one which permits fast compilation and execution on the machines
where it is implemented. Traditionally, FORTRAN and COBOL have been relatively efficient
languages in their respective application areas.
Some languages have better “pedagogy” than others. That is, they are intrinsically easier to
teach and to learn, they have better textbooks; they are implemented in a better program
development environment, they are widely known and used by the best programmers in an
application area.
Generality: Means that a language is useful in a wide range of programming applications. For
instance, APL has been used in mathematical applications involving matrix algebra and in
business applications as well.
INFLUENCES ON LANGUAGE DESIGN
In addition to those factors described above, several other factors influence the basic design of
programming languages. The most important of these are computer architecture and programming
design methodologies.
1. Computer Architecture:
The basic architecture of computers has had a profound effect on language design. Most
of the popular languages of the past 60 years have been designed around the prevalent
computer architecture, called the von Neumann architecture, after one of its originators,
3|Page
John von Neumann (pronounced “von Noyman”). These languages are called imperative
languages. In a von Neumann computer, both data and programs are stored in the same
memory. The central processing unit (CPU), which executes instructions, is separate from
the memory. Therefore, instructions and data
must be transmitted, or piped, from memory to the CPU. Results of operations in the CPU
must be moved back to memory. Nearly all digital computers built since the 1940s have
been based on the von Neumann architecture. The overall structure of a von Neumann
computer is shown below
4|Page
2. Functional
Here, the main means of making computations is by applying functions to parameters. Examples
are LISP, Scheme, ML, Haskell. It may also include OO (Object Oriented) concepts.
3. Logic
This is Rule-based (rules are specified in no particular order). Computations here are made
through a logical inference process. Examples are PROLOG and CLIPS. This may also include
OO concepts.
TRADE-OFFS IN LANGUAGE DESIGN
1. Reliability Vs. Cost of Execution: For example, Java demands that all
references to array elements be checked for proper indexing, which leads to increased
execution costs.
2. Readability vs. Writability: - APL provides many powerful operators land a large
number of new symbols), allowing complex computations to be written in a compact
program but at the cost of poor readability.
3. Writability (Flexibility) vs. reliability: The pointers in c++ for instance are powerful
and very flexible but are unreliable.
IMPLEMENTATION METHODS
1. Compilation – Programs are translated into machine Language & System calls
2. Interpretation – Programs are interpreted by another program (an interpreter)
3. Hybrid – Programs translated into an intermediate language for easy
interpretation
4. Just –in-time – Hybrid implementation, then compile sub programs code the first time
they are called.
COMPILATION
• Explanation: Compilation is a method in which the source code is translated into machine
code or an intermediate representation before it is executed. This translation is performed by a
compiler, which produces a separate executable file. The compiled code can be executed
multiple times without the need for recompilation.
• Example: C and C++ are classic examples of languages that use compilation. When you write
C or C++ code, it is compiled into machine code specific to the target architecture. You then
run the resulting executable file. In summary
- Translated high level program (source language) into machine code (machine
language)
- Slow translation, fast execution
- Compilation process has several phases
o Lexical analysis converts characters in the source program into lexical
units (e.g. identifiers, operators, keywords).
o Syntactic analysis: transforms lexical units into parse trees which represent
the syntactic structure of the program.
5|Page
o Semantics analysis check for errors hard to detect during syntactic analysis;
generate intermediate code.
o Code generation – Machine code is generated
INTERPRETATION
• Explanation: Interpretation is a method in which the source code is executed line by line or
statement by statement by an interpreter. The interpreter reads the source code and performs
the corresponding actions immediately without creating a separate executable file.
Interpretation allows for more dynamic execution and easier debugging.
• Example: Python and JavaScript are interpreted languages. When you run a Python script or
JavaScript code in a browser, the interpreter reads the code and executes it directly. This makes
it possible to change the code and see immediate results without recompiling.
JUST-IN-TIME IMPLEMENTATION
• Explanation: JIT compilation is a method that combines aspects of both compilation and
interpretation. In JIT compilation, source code is initially compiled into an intermediate form
(bytecode), but instead of compiling the entire code ahead of time, the bytecode is compiled
6|Page
into machine code just before execution. This can result in improved performance over pure
interpretation. However, it differs from hybrid in terms of when compilation occurs. In JIT
compilation, source code is initially compiled into an intermediate form (such as bytecode). However,
instead of compiling the entire code ahead of time, the bytecode is compiled into machine code "just in
time," right before execution. This approach aims to achieve improved performance over pure
interpretation while retaining some level of portability.
• Example: C# (C Sharp) and the .NET framework use JIT compilation. C# source code is
compiled into Intermediate Language (IL) bytecode, and the Common Language Runtime
(CLR) performs JIT compilation, translating IL bytecode into machine code as the program
runs.
Data Type
A data type is the most basic and the most common classification of data. It is this through which
the compiler gets to know the form or the type of information that will be used throughout the
code. So basically, data type is a type of information transmitted between the programmer and the
compiler where the programmer informs the compiler about what type of data is to be stored and
also tells how much space it requires in the memory. Some basic examples are int, string etc. It is
the type of any variable used in the code.
Data Structure
A data structure is a collection of different forms and different types of data that has a set of
specific operations that can be performed. It is a collection of data types. It is a way of organizing
the items in terms of memory, and also the way of accessing each item through some defined logic.
Some examples of data structures are stacks, queues, linked lists, binary tree and many more.
Data structures perform some special operations only like insertion, deletion and traversal. For
example, you have to store data for many employees where each employee has his name, employee
id and a mobile number. So, this kind of data requires complex data management, which means it
requires data structure comprised of multiple primitive data types. So, data structures are one of
the most important aspects when implementing coding concepts in real-world applications.
7|Page
Data Types Data Structures
3. Can hold values and not data, so it is data 3. Can hold different kind and types of
less data within one single object
4. The data is assigned to the data
4. Values can directly be assigned to the data structure object using some set of
type variables algorithms and operations like push,
pop and so on.
5. Time complexity comes into play when
5. No problem of time complexity
working with data structures
6. Examples: int, float, double 6. Examples: stacks, queues, tree
ANALYSIS OF BASIC DATA TYPES IN PYTHON
Data types are the classification or categorization of data items. It represents the kind of value that
tells what operations can be performed on a particular data. Since everything is an object in Python
programming, data types are actually classes and variables are instances (object) of these classes.
The following are the standard or built-in data types in Python:
1. Numeric
2. Sequence Type
3. Boolean
4. Set
5. Dictionary
6. Binary Types( memoryview, bytearray, bytes)
The numeric data type in Python represents the data that has a numeric value. A numeric value
can be an integer, a floating number, or even a complex number. These values are defined as
Python int, Python float, and Python complex classes in Python.
8|Page
• Integers – This value is represented by int class. It contains positive or negative whole
numbers (without fractions or decimals). In Python, there is no limit to how long an
integer value can be.
• Float – This value is represented by the float class. It is a real number with a floating-
point representation. It is specified by a decimal point. Optionally, the character e or E
followed by a positive or negative integer may be appended to specify scientific notation.
• Complex Numbers – Complex number is represented by a complex class. It is specified
as (real part) + (imaginary part)j. For example – 2+3j
# Python program to
# demonstrate numeric value
a = 5
print("Type of a: ", type(a))
b = 5.0
print("\nType of b: ", type(b))
c = 2 + 4j
print("\nType of c: ", type(c))
9|Page
# Python Program for
# Creation of String
# Creating a String
# with single Quotes
String1 = 'Welcome to the Geeks World'
print("String with the use of Single Quotes: ")
print(String1)
# Creating a String
# with double Quotes
String1 = "I'm a Geek"
print("\nString with the use of Double Quotes: ")
print(String1)
print(type(String1))
# Creating a String
# with triple Quotes
String1 = '''I'm a Geek and I live in a world of "Geeks"'''
print("\nString with the use of Triple Quotes: ")
print(String1)
print(type(String1))
10 | P a g e
Accessing elements of String
In Python, individual characters of a String can be accessed by using the method of Indexing.
Negative Indexing allows negative address references to access characters from the back of the
String, e.g. -1 refers to the last character, -2 refers to the second last character, and so on.
# Python Program to Access
# characters of String
String1 = "GeeksForGeeks"
print("Initial String: ")
print(String1)
11 | P a g e
List Data Type
Lists are just like arrays, declared in other languages which is an ordered collection of data. It is
very flexible as the items in a list do not need to be of the same type.
Creating List
Lists in Python can be created by just placing the sequence inside the square brackets[].
# Creating a List
List = []
print("Initial blank List: ")
print(List)
12 | P a g e
Python Access List Items
In order to access the list items refer to the index number. Use the index operator [ ] to access an
item in a list. In Python, negative sequence indexes represent positions from the end of the array.
Instead of having to compute the offset as in List[len(List)-3], it is enough to just write List[-3].
Negative indexing means beginning from the end, -1 refers to the last item, -2 refers to the
second-last item, etc.
13 | P a g e
# print the last element of list
print(List[-1])
14 | P a g e
Tuple1 = tuple('Geeks')
print("\nTuple with the use of function: ")
print(Tuple1)
# Creating a Tuple
# with nested tuples
Tuple1 = (0, 1, 2, 3)
Tuple2 = ('python', 'geek')
Tuple3 = (Tuple1, Tuple2)
print("\nTuple with nested tuples: ")
print(Tuple3)
Note – The creation of a Python tuple without the use of parentheses is known as Tuple Packing.
Access Tuple Items
In order to access the tuple items refer to the index number. Use the index operator [ ] to access
an item in a tuple. The index must be an integer. Nested tuples are accessed using nested
indexing.
# Python program to
# demonstrate accessing tuple
15 | P a g e
# Accessing element using indexing
print("First element of tuple")
print(tuple1[0])
print(type(True))
print(type(False))
print(type(true))
16 | P a g e
Set Data Type in Python
In Python, a Set is an unordered collection of data types that is iterable, mutable and has no
duplicate elements. The order of elements in a set is undefined though it may consist of various
elements.
Create a Set in Python
Sets can be created by using the built-in set() function with an iterable object or a sequence by
placing the sequence inside curly braces, separated by a ‘comma’. The type of elements in a set
need not be the same, various mixed-up data type values can also be passed to the set.
# Creating a Set
set1 = set()
print("Initial blank Set: ")
print(set1)
17 | P a g e
# (Having numbers and strings)
set1 = set([1, 2, 'Geeks', 4, 'For', 6, 'Geeks'])
print("\nSet with the use of Mixed Values")
print(set1)
Set items cannot be accessed by referring to an index, since sets are unordered the items has no
index. But you can loop through the set items using a for loop, or ask if a specified value is
present in a set, by using the in the keyword.
# Creating a set
set1 = set(["Geeks", "For", "Geeks"])
print("\nInitial set")
print(set1)
18 | P a g e
# using in keyword
print("Geeks" in set1)
# Creating a Dictionary
# with Integer Keys
Dict = {1: 'Geeks', 2: 'For', 3: 'Geeks'}
print("\nDictionary with the use of Integer Keys: ")
print(Dict)
# Creating a Dictionary
# with Mixed keys
Dict = {'Name': 'Geeks', 1: [1, 2, 3, 4]}
print("\nDictionary with the use of Mixed Keys: ")
print(Dict)
# Creating a Dictionary
# with dict() method
19 | P a g e
Dict = dict({1: 'Geeks', 2: 'For', 3: 'Geeks'})
print("\nDictionary with the use of dict(): ")
print(Dict)
# Creating a Dictionary
# with each item as a Pair
Dict = dict([(1, 'Geeks'), (2, 'For')])
print("\nDictionary with each item as a pair: ")
print(Dict)
In order to access the items of a dictionary refer to its key name. Key can be used inside square
brackets. There is also a method called get() that will also help in accessing the element from a
dictionary.
# Creating a Dictionary
Dict = {1: 'Geeks', 'name': 'For', 3: 'Geeks'}
20 | P a g e
print("Accessing a element using key:")
print(Dict['name'])
In this section, you will learn about tree data structure. Also, you will learn about different types
of trees and the terminologies used in tree.
A tree is a nonlinear hierarchical data structure that consists of nodes connected by edges.
21 | P a g e
Different tree data structures allow quicker and easier access to the data as it is a non-linear data
structure.
Tree Terminologies
Node
A node is an entity that contains a key or value and pointers to its child nodes.
The last nodes of each path are called leaf nodes or external nodes that do not contain a
link/pointer to child nodes.
The node having at least a child node is called an internal node.
Edge
It is the link between any two nodes.
Root
It is the topmost node of a tree.
Height of a Node
The height of a node is the number of edges from the node to the deepest leaf (ie. the longest
path from the node to a leaf node).
Depth of a Node
The depth of a node is the number of edges from the root to the node.
Height of a Tree
The height of a Tree is the height of the root node or the depth of the deepest node.
22 | P a g e
Degree of a Node
The degree of a node is the total number of branches of that node.
Forest
A collection of disjoint trees is called a forest.
23 | P a g e
Tree Applications
• Binary Search Trees (BSTs) are used to quickly check whether an element is present in a
set or not.
• Heap is a kind of tree that is used for heap sort.
• A modified version of a tree called Tries is used in modern routers to store routing
information.
• Most popular databases use B-Trees and T-Trees, which are variants of the tree structure
we learned above to store their data
• Compilers use a syntax tree to validate the syntax of every program you write.
Binary Tree
In this section, you will learn about binary tree and its different types. Also, you will find
working examples of binary tree in C, C++, Java and Python.
A binary tree is a tree data structure in which each parent node can have at most two children.
Each node of a binary tree consists of three items:
• data item
• address of left child
• address of right child
24 | P a g e
To learn more, please visit full binary tree.
25 | P a g e
3. The last leaf element might not have a right sibling i.e. a complete binary tree doesn't
have to be a full binary tree.
26 | P a g e
6. Balanced Binary Tree
It is a type of binary tree in which the difference between the height of the left and the right
subtree for each node is either 0 or 1.
struct node
int data;
27 | P a g e
struct node *right;
};
Python implementation
class Node:
def __init__(self, key):
self.left = None
self.right = None
self.val = key
# Traverse preorder
def traversePreOrder(self):
print(self.val, end=' ')
if self.left:
self.left.traversePreOrder()
if self.right:
self.right.traversePreOrder()
# Traverse inorder
def traverseInOrder(self):
if self.left:
self.left.traverseInOrder()
print(self.val, end=' ')
if self.right:
28 | P a g e
self.right.traverseInOrder()
# Traverse postorder
def traversePostOrder(self):
if self.left:
self.left.traversePostOrder()
if self.right:
self.right.traversePostOrder()
print(self.val, end=' ')
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
Java Implementation
// Binary Tree in Java
// Node creation
class Node {
int key;
Node left, right;
class BinaryTree {
Node root;
BinaryTree(int key) {
root = new Node(key);
}
29 | P a g e
BinaryTree() {
root = null;
}
// Traverse Inorder
public void traverseInOrder(Node node) {
if (node != null) {
traverseInOrder(node.left);
System.out.print(" " + node.key);
traverseInOrder(node.right);
}
}
// Traverse Postorder
public void traversePostOrder(Node node) {
if (node != null) {
traversePostOrder(node.left);
traversePostOrder(node.right);
System.out.print(" " + node.key);
}
}
// Traverse Preorder
public void traversePreOrder(Node node) {
if (node != null) {
System.out.print(" " + node.key);
traversePreOrder(node.left);
traversePreOrder(node.right);
}
}
30 | P a g e
}
C implementation
// Tree traversal in C
#include <stdio.h>
#include <stdlib.h>
struct node {
int item;
struct node* left;
struct node* right;
};
// Inorder traversal
void inorderTraversal(struct node* root) {
if (root == NULL) return;
inorderTraversal(root->left);
printf("%d ->", root->item);
inorderTraversal(root->right);
}
// Preorder traversal
void preorderTraversal(struct node* root) {
if (root == NULL) return;
printf("%d ->", root->item);
preorderTraversal(root->left);
preorderTraversal(root->right);
}
// Postorder traversal
void postorderTraversal(struct node* root) {
if (root == NULL) return;
postorderTraversal(root->left);
postorderTraversal(root->right);
printf("%d ->", root->item);
}
return newNode;
31 | P a g e
}
int main() {
struct node* root = createNode(1);
insertLeft(root, 2);
insertRight(root, 3);
insertLeft(root->left, 4);
C++ implementation
// Binary Tree in C++
#include <stdlib.h>
#include <iostream>
struct node {
int data;
struct node *left;
struct node *right;
};
32 | P a g e
struct node *newNode(int data) {
struct node *node = (struct node *)malloc(sizeof(struct
node));
node->data = data;
node->left = NULL;
node->right = NULL;
return (node);
}
// Traverse Preorder
void traversePreOrder(struct node *temp) {
if (temp != NULL) {
cout << " " << temp->data;
traversePreOrder(temp->left);
traversePreOrder(temp->right);
}
}
// Traverse Inorder
void traverseInOrder(struct node *temp) {
if (temp != NULL) {
traverseInOrder(temp->left);
cout << " " << temp->data;
traverseInOrder(temp->right);
}
}
// Traverse Postorder
void traversePostOrder(struct node *temp) {
if (temp != NULL) {
traversePostOrder(temp->left);
traversePostOrder(temp->right);
cout << " " << temp->data;
}
}
int main() {
struct node *root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
33 | P a g e
traverseInOrder(root);
cout << "\nPostorder traversal: ";
traversePostOrder(root);
}
In this section, you will learn how Binary Search Tree works. Also, you will find working
examples of Binary Search Tree in C, C++, Java and Python.
Binary search tree is a data structure that quickly allows us to maintain a sorted list of numbers.
• It is called a binary tree because each tree node has a maximum of two children.
• It is called a search tree because it can be used to search for the presence of a number in
O(log(n)) time.
The properties that separate a binary search tree from a regular binary tree is
1. All nodes of left subtree are less than the root node
2. All nodes of right subtree are more than the root node
3. Both subtrees of each node are also BSTs i.e. they have the above two properties
The binary tree on the right isn't a binary search tree because the right subtree of the node "3"
contains a value smaller than it.
There are two basic operations that you can perform on a binary search tree:
34 | P a g e
Search Operation
The algorithm depends on the property of BST that if each left subtree has values below root and
each right subtree has values above the root.
If the value is below the root, we can say for sure that the value is not in the right subtree; we
need to only search in the left subtree and if the value is above the root, we can say for sure that
the value is not in the left subtree; we need to only search in the right subtree.
Algorithm:
Insert Operation
Inserting a value in the correct position is similar to searching because we try to maintain the rule
that the left subtree is lesser than root and the right subtree is larger than root.
We keep going to either right subtree or left subtree depending on the value and when we reach a
point left or right subtree is null, we put the new node there.
Algorithm:
Deletion Operation
There are three cases for deleting a node from a binary search tree.
Case I
In the first case, the node to be deleted is the leaf node. In such a case, simply delete the node
from the tree.
35 | P a g e
Case II
In the second case, the node to be deleted lies has a single child node. In such a case follow the
steps below:
1. Replace that node with its child node.
2. Remove the child node from its original position.
Case III
In the third case, the node to be deleted has two children. In such a case follow the steps below:
36 | P a g e
Binary Search Tree Complexities
Time Complexity
Operation Best Case Complexity Average Case Complexity Worst Case Complexity
Search O(log n) O(log n) O(n)
Insertion O(log n) O(log n) O(n)
Deletion O(log n) O(log n) O(n)
Here, n is the number of nodes in the tree.
Space Complexity
The space complexity for all the operations is O(n).
Binary Search Tree Applications
1. In multilevel indexing in the database
2. For dynamic sorting
3. For managing virtual memory areas in Unix kernel
B-tree
In this section, you will learn what a B-tree is. Also, you will find working examples of search
operation on a B-tree in C, C++, Java and Python.
B-tree is a special type of self-balancing search tree in which each node can contain more than
one key and can have more than two children. It is a generalized form of the binary search tree.
It is also known as a height-balanced m-way tree.
37 | P a g e
Why do you need a B-tree data strcuture?
The need for B-tree arose with the rise in the need for lesser time in accessing the physical
storage media like a hard disk. The secondary storage devices are slower with a larger capacity.
There was a need for such types of data structures that minimize the disk accesses.
Other data structures such as a binary search tree, avl tree, red-black tree, etc can store only one
key in one node. If you have to store a large number of keys, then the height of such trees
becomes very large and the access time increases.
However, B-tree can store many keys in a single node and can have multiple child nodes. This
decreases the height significantly allowing faster disk accesses.
B-tree Properties
1. For each node x, the keys are stored in increasing order.
2. In each node, there is a boolean value x.leaf which is true if x is a leaf.
3. If n is the order of the tree, each internal node can contain at most n - 1 keys along with a
pointer to each child.
4. Each node except root can have at most n children and at least n/2 children.
5. All leaves have the same depth (i.e. height-h of the tree).
6. The root has at least 2 children and contains a minimum of 1 key.
7. If n ≥ 1, then for any n-key B-tree of height h and minimum degree t ≥ 2, h ≥ logt (n+1)/2.
B Tree Applications
• databases and file systems
• to store blocks of data (secondary storage media)
• multilevel indexing
Control Structures are just a way to specify flow of control in programs. Any algorithm or
program can be clearer and more understood if they use self-contained modules called as logic or
control structures. It basically analyzes and chooses in which direction a program flows based on
certain parameters or conditions. There are three basic types of logic, or flow of control, known
as:
1. Sequence logic, or sequential flow
2. Selection logic, or conditional flow
38 | P a g e
3. Iteration logic, or repetitive flow
Let us see them in detail:
1. Sequential Logic (Sequential Flow)
Sequential logic as the name suggests follows a serial or sequential flow in which the flow
depends on the series of instructions given to the computer. Unless new instructions are
given, the modules are executed in the obvious sequence. The sequences may be given, by
means of numbered steps explicitly. Also, implicitly follows the order in which modules
are written. Most of the processing, even some complex problems, will generally follow
this elementary flow pattern.
39 | P a g e
Decision Making in C/C++ helps to write decision driven statements and execute a particular set
of code based on certain conditions.
The C/C++ if statement is the most simple decision making statement. It is used to decide whether
a certain statement or block of statements will be executed or not based on a certain type of
condition.
Note: If we do not provide the curly braces ‘{‘ and ‘}’ after if( condition ) then by default if
statement will consider the immediate one statement to be inside its block. For example,
if(condition)
statement1;
statement2;
C++ implementation
40 | P a g e
using namespace std;
int main()
{
int i = 10;
if (i < 15) {
cout << "10 is less than 15 \n";
}
cout << "I am Not in if";
}
Output:
10 is less than 15
I am Not in if
Dry-Running Example 1:
1. Program starts.
2. i is initialized to 10.
3. if-condition is checked. 10 < 15, yields true.
3.a) "10 is less than 15" gets printed.
4. "I am Not in if" is printed.
Decision Making in Java helps to write decision driven statements and execute a particular set of
code based on certain conditions.
The Java if statement is the most simple decision-making statement. It is used to decide whether
a certain statement or block of statements will be executed or not i.e if a certain condition is true
then a block of statement is executed otherwise not.
Operation:
The condition after evaluation of if-statement will be either true or false. The if statement in Java
accepts boolean values and if the value is true then it will execute the block of statements under it.
Note: If we do not provide the curly braces ‘{‘ and ‘}’ after if( condition ) then by default if
statement will consider the immediate one statement to be inside its block. For example,
if(condition)
statement1;
statement2;
Example 1:
// Java program to illustrate If statement
class IfDemo {
public static void main(String args[])
{
int i = 10;
if (i < 15)
41 | P a g e
System.out.println("10 is less than 15");
// This statement will be executed
// as if considers one statement by default
System.out.println("Outside if-block");
}
}
Output:
10 is less than 15
Outside if-block
Dry-Running Example 1:
1. Program starts.
2. i is initialized to 10.
3. if-condition is checked. 10<15, yields true.
3.a) "10 is less than 15" gets printed.
4. "Outside if-block" is printed.
Example 2:
// if block
if (i == 4) {
i++;
System.out.println(str);
}
// Executed by default
System.out.println("i = " + i);
}
}
Output:
GeeksforGeeks
i=5
42 | P a g e
C/C++ if else statement with Examples
Decision Making in C/C++ helps to write decision driven statements and execute a particular set
of code based on certain conditions.
The if statement alone tells us that if a condition is true it will execute a block of statements and
if the condition is false it won’t. But what if we want to do something else if the condition is
false. Here comes the C/C++ else statement. We can use the else statement with if statement to
execute a block of code when the condition is false.
Syntax:
if (condition)
{
// Executes this block if
// condition is true
}
else
{
// Executes this block if
// condition is false
}
Example 1:
C implementation
#include <stdio.h>
int main()
{
int i = 20;
// Check if i is 10
if (i == 10)
printf("i is 10");
// Since is not 10
// Then execute the else statement
else
printf("i is 20");
return 0;
}
Output:
i is 20
Outside if-else block
43 | P a g e
C++ implementation
int main()
{
int i = 20;
// Check if i is 10
if (i == 10)
cout << "i is 10";
// Since is not 10
// Then execute the else statement
else
cout << "i is 20\n";
return 0;
}
Output:
i is 20
Outside if-else block
Dry-Running Example 1:
1. Program starts.
2. i is initialized to 20.
3. if-condition is checked. i == 10, yields false.
4. flow enters the else block.
4.a) "i is 20" is printed
5. "Outside if-else block" is printed.
Example 2:
C implementation
#include <stdio.h>
int main()
{
int i = 25;
44 | P a g e
if (i > 15)
printf("i is greater than 15");
else
printf("i is smaller than 15");
return 0;
}
Output:
i is greater than 15
C++ implementation
#include <iostream>
using namespace std;
int main()
{
int i = 25;
if (i > 15)
cout << "i is greater than 15";
else
cout << "i is smaller than 15";
return 0;
}
Output:
i is greater than 15
45 | P a g e
bypassed. If none of the conditions is true, then the final else statement will be executed.
Syntax:
if (condition)
statement 1;
else if (condition)
statement 2;
.
.
else
statement;
Example 1:
C implementation
#include <stdio.h>
int main()
{
int i = 20;
// Check if i is 10
if (i == 10)
printf("i is 10");
// Since i is not 10
// Check if i is 15
else if (i == 15)
printf("i is 15");
// Since i is not 15
// Check if i is 20
else if (i == 20)
printf("i is 20");
return 0;
}
Output:
i is 20
46 | P a g e
C++ implementation
int main()
{
int i = 20;
// Check if i is 10
if (i == 10)
cout << "i is 10";
// Since i is not 10
// Check if i is 15
else if (i == 15)
cout << "i is 15";
// Since i is not 15
// Check if i is 20
else if (i == 20)
cout << "i is 20";
return 0;
}
Output:
i is 20
Dry running Example 1:
1. Program starts.
2. i is initialized to 20.
3. condition 1 is checked. 20 == 10, yields false.
4. condition 2 is checked. 20 == 15, yields false.
5. condition 3 is checked. 20 == 20, yields true.
5.a) "i is 20" gets printed.
6. "Outside if-else-if" gets printed.
7. Program ends.
Example 2:
C implementation
47 | P a g e
#include <stdio.h>
int main()
{
int i = 25;
C++ implementation
int main()
{
int i = 25;
48 | P a g e
// Check if i is between 16 and 20
else if (i >= 16 && i <= 20)
cout << "i is between 16 and 20" << endl;
Example 1: Java
import java.io.*;
class GFG {
public static void main(String[] args)
{
// initializing expression
int i = 20;
// condition 1
if (i == 10)
System.out.println("i is 10\n");
// condition 2
else if (i == 15)
49 | P a g e
System.out.println("i is 15\n");
// condition 3
else if (i == 20)
System.out.println("i is 20\n");
else
System.out.println("i is not present\n");
System.out.println("Outside if-else-if");
}
}
Output:
i is 20
Outside if-else-if
1. Program starts.
2. i is initialized to 20.
3. condition 1 is checked. 20 == 10, yields false.
4. condition 2 is checked. 20 == 15, yields false.
5. condition 3 is checked. 20 == 20, yields true.
5.a) "i is 20" gets printed.
6. "Outside if-else-if" gets printed.
7. Program ends.
import java.io.*;
class GFG {
public static void main(String[] args)
{
// initializing expression
int i = 20;
// condition 1
if (i < 10)
System.out.println("i is less than 10\n");
// condition 2
else if (i < 15)
System.out.println("i is less than 15\n");
50 | P a g e
// condition 3
else if (i < 20)
System.out.println("i is less than 20\n");
else
System.out.println("i is greater than "
+ "or equal to 20\n");
System.out.println("Outside if-else-if");
}
}
Output:
i is greater than or equal to 20
Outside if-else-if
Repeat for i = A to N by I:
[Module]
[End of loop]
Here, A is the initial value, N is the end value and I is the increment. The loop ends when
A>B. K increases or decreases according to the positive and negative value of I
respectively.
Syntax:
for (initialization expr; test expr; update expr)
{
// body of the loop
// statements we want to execute
}
The various parts of the For loop are:
1. Initialization Expression: In this expression we have to initialize the loop counter to some
value.
Example:
int i=1;
51 | P a g e
2. Condition: In this expression we have to test the condition. If the condition evaluates to
true then we will execute the body of the loop and go to update expression. Otherwise, we
will exit from the for loop.
Example:
i <= 10
3. Update Expression: After executing the loop body, this expression increments/decrements
the loop variable by some value.
Example:
i++;
Example 1: This program will try to print “Hello World” 5 times. The program will execute in the
following manner:
#include <stdio.h>
int main()
{
int i = 0;
return 0;
}
Output:
Hello World
Hello World
Hello World
Hello World
Hello World
C++ implementation
#include <iostream>
using namespace std;
int main()
{
52 | P a g e
// Writing a for loop
// to print Hello World 5 times
for (int i = 1; i <= 5; i++) {
cout << "Hello World\n";
}
return 0;
}
Output:
Hello World
Hello World
Hello World
Hello World
Hello World
Example 2: C implementation
// C program to illustrate for loop
#include <stdio.h>
int main()
{
int i = 0;
return 0;
}
Output:
1
3
5
7
9
C++ implementation
#include <iostream>
using namespace std;
int main()
{
int i = 0;
53 | P a g e
// Writing a for loop
// to print odd numbers upto N
for (i = 1; i <= 10; i += 2) {
cout << i << "\n";
}
return 0;
}
Output:
1
3
5
7
9
Java For loop with Examples
Loops in Java come into use when we need to repeatedly execute a block of statements.
Java for loop provides a concise way of writing the loop structure. The for statement consumes
the initialization, condition and increment/decrement in one line thereby providing a shorter,
easy to debug structure of looping.
Syntax:
1. Initialization Expression: In this expression, we have to initialize the loop counter to some
value.
Example:
int i=1;
2. Test Expression: In this expression, we have to test the condition. If the condition evaluates
to true then, we will execute the body of the loop and go to update expression. Otherwise, we
will exit from the for loop.
Example:
i <= 10
3. Update Expression: After executing the loop body, this expression increments/decrements
the loop variable by some value.
Example:
i++;
54 | P a g e
// Java program to illustrate for loop
class forLoopDemo {
public static void main(String args[])
{
// Writing a for loop
// to print Hello World 5 times
for (int i = 1; i <= 5; i++)
System.out.println("Hello World");
}
}
Output:
Hello World
Hello World
Hello World
Hello World
Hello World
Example 2: The following program prints the sum of x ranging from 1 to 20.
Repeat-While Structure
It also uses a condition to control the loop. This structure has the form:
Repeat while condition:
[Module]
[End of Loop]
C/C++ while loop with Examples
Loops in C/C++ come into use when we need to repeatedly execute a block of statements.
During the study of ‘for’ loop in C or C++, we have seen that the number of iterations is known
beforehand, i.e. the number of times the loop body is needed to be executed is known to us. The while
loop in C/C++ is used in situations where we do not know the exact number of iterations of loop
beforehand. The loop execution is terminated on the basis of the test condition.
55 | P a g e
Syntax:
while (test_expression)
{
// statements
update_expression;
}
C implementation
#include <stdio.h>
int main()
{
// initialization expression
int i = 1;
// test expression
while (i < 6) {
printf("Hello World\n");
// update expression
i++;
}
return 0;
}
Output:
Hello World
Hello World
Hello World
Hello World
Hello World
C++ implementation
#include <iostream>
using namespace std;
int main()
{
56 | P a g e
// initialization expression
int i = 1;
// test expression
while (i < 6) {
cout << "Hello World\n";
// update expression
i++;
}
return 0;
}
Output:
Hello World
Hello World
Hello World
Hello World
Hello World
Example 2: C implementation
#include <stdio.h>
int main()
{
// initialization expression
int i = 1;
// test expression
while (i > -5) {
printf("%d\n", i);
// update expression
i--;
}
return 0;
}
Output:
1
0
-1
-2
-3
-4
57 | P a g e
C++ implementation
#include <iostream>
using namespace std;
int main()
{
// initialization expression
int i = 1;
// test expression
while (i > -5) {
cout << i << "\n";
// update expression
i--;
}
return 0;
}
Output:
1
0
-1
-2
-3
-4
Loops in Java come into use when we need to repeatedly execute a block of statements.
Java while loop is a control flow statement that allows code to be executed repeatedly based on
a given Boolean condition. The while loop can be thought of as a repeating if statement.
Syntax:
while (test_expression)
{
// statements
update_expression;
}
Example 1: This program will try to print “Hello World” 5 times.
// Java program to illustrate while loop.
58 | P a g e
class whileLoopDemo {
public static void main(String args[])
{
// initialization expression
int i = 1;
// test expression
while (i < 6) {
System.out.println("Hello World");
// update expression
i++;
}
}
}
Output:
Hello World
Hello World
Hello World
Hello World
Hello World
Example 2: This program will find the summation of numbers from 1 to 10.
class whileLoopDemo {
public static void main(String args[])
{
int x = 1, sum = 0;
59 | P a g e
Java do-while loop with Examples
Loops in Java come into use when we need to repeatedly execute a block of statements.
Java do-while loop is an Exit control loop. Therefore, unlike for or while loop, a do-while
check for the condition after executing the statements or the loop body.
Syntax:
do
{
// loop body
update_expression
}
while (test_expression);
class dowhileloopDemo {
public static void main(String args[])
{
// initialisation expression
int i = 1;
do {
// update expression
i++;
}
// test expression
while (i < 6);
}
}
Output:
Hello World
Hello World
Hello World
Hello World
Hello World
Example 2:
class dowhileloopDemo {
60 | P a g e
public static void main(String args[])
{
do {
Output:
Summation: 176
61 | P a g e