0% found this document useful (0 votes)
15 views20 pages

Unit 1

The document provides an overview of Abstract Data Types (ADTs) and Object-Oriented Programming (OOP) concepts, including classes, objects, constructors, destructors, encapsulation, inheritance, polymorphism, and operator overloading. It explains the features and advantages of ADTs, the structure and purpose of classes and objects, and various methods and principles in OOP. Additionally, it discusses abstract classes, static methods, class methods, and the importance of encapsulation and inheritance in programming.

Uploaded by

Usharani K
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views20 pages

Unit 1

The document provides an overview of Abstract Data Types (ADTs) and Object-Oriented Programming (OOP) concepts, including classes, objects, constructors, destructors, encapsulation, inheritance, polymorphism, and operator overloading. It explains the features and advantages of ADTs, the structure and purpose of classes and objects, and various methods and principles in OOP. Additionally, it discusses abstract classes, static methods, class methods, and the importance of encapsulation and inheritance in programming.

Uploaded by

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

ADT

1. Definition: Abstract Data type (ADT) is a type (or class) for objects whose behavior is defined by a set of values
and a set of operations. It mentions what operations are to be performed but not how these operations will be
implemented. It is called “abstract” because it gives an implementation-independent view.
2. Example: List ADT, Stack ADT, Queue ADT, set, tuple, dict
3. List in python :

4. Features of ADT: Data abstraction, information hiding, Data structure independence, encapsulation, Modularity,
Robustness
5. Advantage of ADT:
 Encapsulation: ADTs provide a way to encapsulate data and operations into a single unit, making it easier
to manage and modify the data structure.
 Abstraction: ADTs allow users to work with data structures without having to know the implementation
details, which can simplify programming and reduce errors.
 Data Structure Independence: ADTs can be implemented using different data structures, which can make it
easier to adapt to changing needs and requirements.
 Information Hiding: ADTs can protect the integrity of data by controlling access and preventing
unauthorized modifications.
 Modularity: ADTs can be combined with other ADTs to form more complex data structures, which can
increase flexibility and modularity in programming.

ADT and Classes

List
Tuple

Dict

Set
Introduction to OOP

Class

1. Class creates a user-defined data structure, which holds its own data members and member functions, which can be
accessed and used by creating an instance of that class.
2. Classes are created by keyword class.
3. Attributes are always public and can be accessed using the dot (.) operator. Eg.: Myclass.Myattribute
4. Syntax:
class ClassName: # Class definition
# Statement
obj = ClassName() #Object Definition
print(obj.atrr)
Object

1. An Object is an instance of a Class.


2. An object consists of :
 State: It is represented by the attributes of an object. It also reflects the properties of an object.
 Behaviour: It is represented by the methods of an object. It also reflects the response of an object to other
objects.
 Identity: It gives a unique name to an object and enables one object to interact with other objects.
3. Declaring Object: When an object of a class is created, the class is said to be instantiated.
All the instances share the attributes and the behavior of the class.
4. A single class may have any number of instances.
Example
class Student:
# attributes
attr1 = "Student of I Year"
attr2 = "Student of CSBS"

# A sample method
def fun(self):
print("I'm a", self.attr1)
print("I'm a", self.attr2)

# Object instantiation
Stud1 = Student()

# Accessing class attributes


# and method through objects
print(Stud1.attr1)
Stud1.fun()

Note: When we call a method of this object as myobject.method(arg1, arg2), this is automatically converted by Python into
MyClass.method(myobject, arg1, arg2)—self

Constructor
1. constructor contains a collection instructions that are executed at the time of Object creation. It runs as soon as an object
of a class is instantiated. The method is useful to do any initialization.
2. syntax:
def __init__(self):
# body of the constructor
3. Types : default constructor and parameterized constructor
default constructor parameterized constructor
class Student: class Student:

def __init__(self): def __init__(self,x,y):


self.attr1 = "Student of I Year" self.attr1 = x
self.attr2 = "Student of CSBS" self.attr2 = y

def fun(self): def fun(self):


print("I'm a", self.attr1) print("I'm a", self.attr1)
print("I'm a", self.attr2) print("I'm a", self.attr2)

Stud1 = Student() a="Student of I Year"


print(Stud1.attr1) b="Student of CSBS"
Stud1.fun() Stud1 = Student(a,b)
print(Stud1.attr1)
Stud1.fun()
Practice : Addition of two numbers (class Add, use constructor)
4. Overloading not supported: Unlike other object-oriented languages, Python does not support method overloading. This
means that you cannot have multiple constructors with different parameters in a single class.

Destructor
1. Destructors are called when an object gets destroyed. In Python, destructors are not needed as much as in C++ because
Python has a garbage collector that handles memory management automatically.
2. syntax:
def __del__(self):
# body of destructor
3.Example:
class Employee: Output:
def __init__(self):
print('Employee created') Calling Create_obj() function...
Making Object...
def __del__(self): Employee created
print("Destructor called") function end...
Program End...
Destructor called
def Create_obj():
print('Making Object...')
obj = Employee()
print('function end...')
return obj

print('Calling Create_obj() function...')


obj = Create_obj()
print('Program End...')

Class and Instance Variable


1. Instance variables are unique to each instance and class variables are for shared by all instances of the class.
2. Instance variables are variables whose value is assigned inside a constructor or method with self whereas class variables
are variables whose value is assigned in the class.
3.Example:
class Student:
department='CSBS' #class variable
def __init__(self,a,b):
self.ID = a #instance variables ID , name
self.name = b
def fun(self):
print("I'm a student of", self.department)
print("My ID is", self.ID,'My name is',self.name)

Stud1 = Student(12,'AB')
Stud1.fun()
Stud2=Student(13,'BC')
Stud2.fun()

Static variable
1. In Python, a static variable is a variable that is shared among all instances of a class, rather than being unique to each
instance. It is also sometimes referred to as a class variable, because it belongs to the class itself rather than any particular
instance of the class.
2. Static variables are defined inside the class definition, but outside of any method definitions.
3. Static variables are allocated memory once when the object for the class is created for the first time.
4. They are typically initialized with a value, just like an instance variable, but they can be accessed and modified through
the class itself, rather than through an instance.
5. Example
class Student:
TotalStudents=0
department='CSBS'
def __init__(self,a,b):
Student.TotalStudents+=1
self.ID = a
self.name = b

def fun(self):
print("I'm a student of", self.department)
print("My ID is", self.ID,'My name is',self.name)

Stud1 = Student(12,'AB')
Stud1.fun()
print('Total Students count =',Student.TotalStudents)
Stud2=Student(13,'BC')
Stud2.fun()
print('Total Students count =',Student.TotalStudents)

Class method and Static method


1.A class method takes cls as the first parameter while a static method needs no specific parameters.
2. @classmethod decorator in python to create a class method and @staticmethod decorator to create a static method in
python.
3. A class method can access or modify the class state while a static method can’t access or modify it.
4. Example
class Person:
def __init__(self, name, age):
self.name = name
self.age = age

@classmethod
def fromBirthYear(cls, name, year):
return cls(name, 2023 - year)

@staticmethod
def isAdult(age):
return age > 18

person1 = Person('mayank', 21)


person2 = Person.fromBirthYear('mayank', 1996)
print(person1.age)
print(person2.age)
print(Person.isAdult(21))

Inheritance
1. One of the core concepts in object-oriented programming (OOP) languages is inheritance.
2. Inheritance is the capability of one class to derive or inherit the properties from another class.
3.Syntax:
Class BaseClass:
{Body}
Class DerivedClass(BaseClass):
{Body}
4. Example:
class Person(object):
def __init__(self, name, idnumber):
self.name = name
self.idnumber = idnumber

def display(self):
print(self.name)
print(self.idnumber)

class Employee(Person):
def __init__(self, name, idnumber, salary, post):
self.salary = salary
self.post = post
Person.__init__(self, name, idnumber)

a = Employee('Rahul', 886012, 200000, "Intern")


a.display()
5. Types:

6.Example:
Single- Person->Employee, Hierarchial – Shape->Cir, Rec, Squ , Multilevel- Vehicle->Four wheeler->Car
Hybrid- CollegeFaculty, StudentBook Multiple-> Mammal,WingedAnimal->Bat
7. Benefits:
 It represents real-world relationships well.
 It provides the reusability of a code.
 Inheritance offers a simple, understandable model structure.Less development and maintenance expenses
Encapsulation
1. one of the fundamental concepts in object-oriented programming (OOP).
2. It is the concept of binding fields (object state) and methods (behavior) together as a single unit and preventing
unwanted access.
3. A class is an example of encapsulation as it encapsulates all the data that is member functions, variables, etc.
4. The goal of information hiding is to ensure that an object’s state is always valid by controlling access to attributes
that are hidden from the outside world.
5.
Private Protected Public
1. neither be accessed outside the class nor 1. cannot be accessed outside the class but can be In Python, there is
by any base class accessed from within the class and its subclasses. no existence of
2. In python, no existence of Private 2. It is convention but not a rule to not access the “Public” instance
instance variables protected out the class body. variables.
prefix the member name with double prefix the member name with single underscore
underscore “__”. “_”.
Example class Base:
class Base: def __init__(self):
def __init__(self): self.a = "InstVar"
self.a = "InstVar" self._c = "ProVar"
self.__c = "PriVar"
class Derived(Base):
class Derived(Base): def __init__(self):
def __init__(self): Base.__init__(self)
Base.__init__(self) print(self._c)
print(self.__c)
obj1 = Base()
obj1 = Base() print(obj1.a)
print(obj1.a)
obj2 = Derived()
# print(obj1.__c) # print(obj1._c)
# raise an AttributeError # Can be accessed but should not be
# obj2 = Derived() done due to convention
# raise an AttributeError

Polymorphism

1. polymorphism means having many forms. In programming, polymorphism means the same function name (but different
signatures) being used for different types. The key difference is the data types and number of arguments used in function.
2. Example Built-in Function –
print(len("geeks"))
print(len([10, 20, 30]))
User-defined polymorphic functions: def add(x, y, z = 0):
return x + y+z

print(add(2, 3))
print(add(2, 3, 4))
Polymorphism with class methods: class India():
def capital(self):
print("New Delhi”)
class USA():
def capital(self):
print("Washington, D.C.”)
obj_ind = India()
obj_usa = USA()
for country in (obj_ind, obj_usa):
country.capital()
Polymorphism with Inheritance and class Bird:
method overriding: def intro(self):
print("There are many types of birds.")

def flight(self):
print("Most of the birds can fly but some cannot.")
class sparrow(Bird):
def flight(self):
print("Sparrows can fly.")

class ostrich(Bird):
def flight(self):
print("Ostriches cannot fly.")

obj_bird = Bird()
obj_spr = sparrow()
obj_ost = ostrich()
obj_bird.intro()
obj_bird.flight()
obj_spr.intro()
obj_spr.flight()
obj_ost.intro()
obj_ost.flight()
Polymorphism with a Function and def func(obj):
objects: obj.capital()

obj_ind = India()
obj_usa = USA()
func(obj_ind)
func(obj_usa)

Abstract Base Class


1. An abstract class can be considered as a blueprint for other classes. It allows you to create a set of methods that must be
created within any child classes built from the abstract class.
2. A class which contains one or more abstract methods is called an abstract class.
3. An abstract method is a method that has a declaration but does not have an implementation.
4. Purpose : While we are designing large functional units we use an abstract class. When we want to provide a common
interface for different implementations of a component, we use an abstract class.
5. By default, Python does not provide abstract classes.
6. Python comes with a module that provides the base for defining Abstract Base classes(ABC).
7. A method becomes abstract when decorated with the keyword @abstractmethod.
8. Example:
from abc import ABCMeta,abstractmethod from abc import ABC,abstractmethod

class Polygon(metaclass=ABCMeta): class Polygon(ABC):


@abstractmethod @abstractmethod
def noofsides(self): def noofsides(self):
pass pass

class Triangle(Polygon): class Triangle(Polygon):


def noofsides(self): def noofsides(self):
print("I have 3 sides") print("I have 3 sides")

class Quadrilateral(Polygon): class Quadrilateral(Polygon):


def noofsides(self): def noofsides(self):
print("I have 4 sides") print("I have 4 sides")

R = Triangle() R = Triangle()
R.noofsides() R.noofsides()

K = Quadrilateral() K = Quadrilateral()
K.noofsides() K.noofsides()
#p=Polygon() Can’t instantiate an abstract class #p=Polygon() Can’t instantiate an abstract class

9. Abstract Class can’t be Instantiated


 an abstract class is not a concrete class, it cannot be instantiated. When we create an object for the abstract class it
raises an error.
 Abstract classes are incomplete because they have methods that have nobody. we use an abstract class as a
template and according to the need, we extend it and build on it before we can use it.

10. Concrete method in abstract class


from abc import ABC,abstractmethod class Quadrilateral(Polygon):

class Polygon(ABC): def noofsides(self):


print("I have 4 sides")
@abstractmethod
def noofsides(self): def printShape(self):
pass super().printShape()
print('Quadrilateral')
def printShape(self):
print('Polygon -', end='') R = Triangle()
R.noofsides()
class Triangle(Polygon): R.printShape()

def noofsides(self): K = Quadrilateral()


print("I have 3 sides") K.noofsides()
K.printShape()
def printShape(self):
super().printShape()
print('Triangle')

Operator Overloading
1. Same built-in operator or function shows different behavior for objects of different classes, this is called Operator
Overloading.
2. Example : + is used to add two integers as well as join two strings and merge two lists.
Overloading binary + operator class A:
def __init__(self, a):
self.a = a

# adding two objects


def __add__(self, o):
return self.a + o.a
ob1 = A(1)
ob2 = A(2)
ob3 = A("Geeks")
ob4 = A("For")

print(ob1 + ob2)
print(ob3 + ob4)
# Actual working when Binary Operator is used.
print(A.__add__(ob1 , ob2))
print(A.__add__(ob3,ob4))
#And can also be Understand as :
print(ob1.__add__(ob2))
print(ob3.__add__(ob4))
class complex:
def __init__(self, a, b):
self.a = a
self.b = b

# adding two objects


def __add__(self, other):
return self.a + other.a, self.b + other.b

Ob1 = complex(1, 2)
Ob2 = complex(2, 3)
Ob3 = Ob1 + Ob2
print(Ob3)
Overloading comparison operators class A:
def __init__(self, a):
self.a = a
def __gt__(self, other):
if(self.a>other.a):
return True
else:
return False
ob1 = A(2)
ob2 = A(3)
if(ob1>ob2):
print("ob1 is greater than ob2")
else:
print("ob2 is greater than ob1")

Binary Compa Assig Unary


-rison -
-=
+ <
+= +
– >
*= ~
* <=
/= Itera
/ >=
== //= Len
//
!= %= Next
%
** **=
>> >>=
<< <<=
& &=
| |=
^

^=

Namespace
1. Whenever an identifier is assigned to a value, that definition is made with a specific scope.
2. Each distinct scope in Python is represented using an abstraction known as a namespace.
3. A namespace manages all identifiers that are currently defined in a given scope.
4. dir() - reports the names of the identifiers in a given namespace (i.e., the keys of the dictionary)
vars()- returns the full dictionary.
5. Types of namespaces : The built-in namespace encompasses the global namespace and the global namespace
encompasses the local namespace.
6. Ex. print(), id() are built-in namespaces. Depending on the version of Python, there are approximately 130–150
definitions that were deemed significant enough to be included in that built-in namespace.
7. same object name can be present in multiple namespaces as isolation between the same name is maintained by their
namespace.

count = 5 #global namespace


def some_method():
a=1 #local namespace
global count
print(dir())

some_method()
print(dir())

Modules
1. Attributes, functions, and classes that are organized as modules, that can be imported from within a program.
2. Example: math module  mathematical functions (e.g., abs, min, max, round) , mathematical constants, pi and e
3. import statement loads definitions from a module into the current
namespace. Ex: from math import pi, sqrt
4. from math import * => danger is that some of the names defined in the module may conflict with names already in the
current namespace (or being imported from another module)
5. import math => individual definitions from the module can be accessed using a fully-qualified name, such as math.pi
or math.sqrt(2).
6. creating New module: if we were to put the definition of our count function into a file named utility.py, we could
import that function using the syntax, from utility import count.

Shallow and Deep copying

1. palatte = warmtones

2. palette = list(warmtones)

3. Deepcopy?

1. Python’s copy Module : Shallowcopy => palette = copy. copy(warmtones)


Deepcopy => palette = copy.deepcopy(warmtones)
2. Example:
import copy

# initializing list 1
li1 = [1, 2, [3, 5], 4]
print("li1 ID: ", id(li1), "Value: ", li1)
print("li1 ID: ", id(li1), "Value: ", li1)
# using copy for shallow copy
li2 = copy.copy(li1)
print("li2 ID: ", id(li2), "Value: ", li2)
# using deepcopy for deepcopy
li3 = copy.deepcopy(li1)
print("li3 ID: ", id(li3), "Value: ", li3)

li2[2][0]=10
print("li1 ID: ", id(li1), "Value: ", li1)
print("li2 ID: ", id(li2), "Value: ", li2)
print("li3 ID: ", id(li3), "Value: ", li3)
li3[2][0]=15
print("li1 ID: ", id(li1), "Value: ", li1)
print("li2 ID: ", id(li2), "Value: ", li2)
print("li3 ID: ", id(li3), "Value: ", li3)
Mutable, Immutable Objects
1. Whenever an object is instantiated, it is assigned a unique object id. The type of the object is defined at the runtime and
it can’t be changed afterwards. However, it’s state can be changed if it is a mutable object.

Immutable int, float, bool, string, unicode, tuple. tuple1 = (0, 1, 2, 3)


tuple1[0] = 4
TypeError: 'tuple' object does not
support item assignment
Mutable list, dict, set color = ["red", "blue",
"green"]
color[0] = "pink"
color[-1] = "orange"
2. Note: Here tup is immutable but element in tup is mutable.
tup = ([3, 4, 5], 'name') Output:
tup[0][1]=10 ([3,10,5],’name’)
print(tup)

Object-Oriented Design Goals


 Robustness - capable of handling unexpected inputs that are not explicitly defined for its application.
 Adaptability/evolvability/ portability - ability of software to run with minimal change on different hardware and
operating system platforms. An advantage of writing software in Python is the portability provided by the language
itself.
 Reusability - same code should be usable as a component of different systems in various applications. Developing
quality software can be an expensive.

Object-Oriented Design Principles


 Modularity - Modularity refers to an organizing principle in which different components of a software system are
divided into separate functional units.
 Abstraction - what each operation does, but not how it does it. ADT, ABC
 Encapsulation - Different components of a software system should not reveal the internal details of their
respective implementations.
Note : Python provides only loose support for encapsulation. By convention, names of members of a class (both
data members and member functions) that start with a single underscore character (e.g., secret) are assumed to be
nonpublic and should not be relied upon.

Introduction to analysis of algorithms


1. An algorilhm is step-by-step instructions to solve a given problem.
2. Algorithm analysis helps us to determine which algorithm is most efficient in terms of time and space consumed. Other
factors memory, developer effort, etc.,
3. Running Time Analysis : It is the process of determining how processing time increases as the size of the problem
(input size) increases.
4. How to compare ? – execution time varies by compter, No.of statementsvaries by language. So, ideal solution is
running time interms of input size.
5. The rate at which the running time increases as a function of input is called rate of growth.

2^2^n > n! > 4^n > 2^n > n^2 > nlogn > log(n!) > n > 2^log n > (log n )^2 > sqrt(log n) > log log n >1

6. Three Types of Analysis


 Worst case - Defines the input for which the algorithm takes a long time - slowest.
 Best case - Defines the input for which the algorithm takes the least time. - fastest.
 Average case- Provides a prediction about the running time of the algorithm. Assumes that the input is random.
lower Bound <= Average Time <= Upper Bound
Ex : Sorting a list of elements. Bestcase – already sorted list. worst case- sorted in reverse order.
7. Advantages:
 Asymptotic analysis provides a high-level understanding of how an algorithm performs with respect to input size.
 It is a useful tool for comparing the efficiency of different algorithms and selecting the best one for a specific
problem.
 It helps in predicting how an algorithm will perform on larger input sizes, which is essential for real-world
applications.
 Asymptotic analysis is relatively easy to perform and requires only basic mathematical skills.
Asymptotic Notation
1. Let us assume that the given algorithm is represented in the form of function f(n).
Big – Oh (Worst case) O Omega (Best case) Ω Theta ( Average case) Θ
f(n) is O(g(n)) if there exist a positive The function f is said to be Ω(g), if The function f is said to be Θ(g), if
constant C and n0 such that, there is a constant c > 0 and a natural there are constants c1, c2 > 0 and a
0 ≤ f(n) ≤ cg(n) for all n ≥ n0 number n0 such that natural number n0 such that
c*g(n) ≤ f(n) for all n ≥ n0 c1* g(n) ≤ f(n) ≤ c2 * g(n) for all n ≥
n0

Properties of Asymptotic Notations


1. Transitive Properties: If f(n) is O(g(n)) and g(n) is O(h(n)) then f(n) = O(h(n)). Valid for both Omega and Theta.
2. Reflexive Properties: f(n)= O(f(n)) Valid for both Omega and Theta.
3. Symmetric Properties: If f(n) is Θ(g(n)) then g(n) is Θ(f(n)). Not satisfies Big-Oh and Theta
4. Transpose Symmetric Properties: If f(n) is O(g(n)) then g(n) is Ω (f(n)). This property only satisfies O and Ω notations.
5. Other Properties:
 If f(n) = O(g(n)) and f(n) = Ω(g(n)) then f(n) = Θ(g(n)).
 If f(n) = O(g(n)) and d(n)=O(e(n)) then f(n) + d(n) = O( max( g(n), e(n) ))
 If f(n)=O(g(n)) and d(n)=O(e(n)) then f(n) * d(n) = O( g(n) * e(n))

Guidelines for Asymptotic Analysis


Loops for i in rangc(O,n): # executes n times Total time = a constant c x n = cn =
print 'Current Number:'. i #constant time O(n).
Nested Loops # outer loop executed n times Cn^2= O(n^2)
for i in range(O,n):
#inner loop executes n times
for j in rangc(O,n):
print 'i value %.d and j value %d' % (i,j)
#constant time
Consecutive n = 100 C0 +C1 n+ C2 n^2 = O(n^2)
Statements #executes n times
for i in range(O,n):
print 'Current Number:', i
#outer loop executed n times
for i in range(O,n):
ff in ner loop excculcs n times
for j in ra ngc(O,n):
print 'i value %d and j value o/od' % (i,j)
If else if n ==1: C0 + C1 n = O(n)
print "Wrong Value"
print n
else:
for i in range(O,n):
print 'Current Number:', i
Logarithmic def Logarithms(n): At kth step 2^k = n then loop ends.
complexity i =1 Take log on both sides,
while i <= n: Log 2^k = Log n
i= i * 2 K Log 2 = Log n (assume base 2)
print i K= Log n
Logarithms(100)

n^2 log n N log^2 n

Recursion
1. It is a process in which a function calls itself directly or indirectly.
2. Advantages of using recursion
 A complicated function can be split down into smaller sub-problems utilizing recursion.
 Sequence creation is simpler through recursion than utilizing any nested iteration.
 Recursive functions render the code look simple and effective.
3. Disadvantages of using recursion
 A lot of memory and time is taken through recursive calls which makes it expensive for use.
 Recursive functions are challenging to debug.
4. Syntax : def fn():
fn() //recursive call
5. Example:
def recursive_factorial(n):
if n == 1:
return n
else:
return n * recursive_factorial(n-1)

6. • Terminates when a base case is reached.


• Each recursive call requires extra space on slack frame (memory).
• If we get infinite recursion, the program may run out of memory and result in stack overflow.
• Solutions to some problems are easier to formulate recursively
7.Examples : Fibonacci, Factorial, Merge and quick sort, Binary search, Tree and Graph traversals, Tower of
Hanoi, dynamic programming, divide and conquer, backtracking
Linear Recursion Binary Recursion Multiple Recursion
1. Sum of n elements 1. Binary sum //S=[1,2,3,4,5] Combinatorial Puzzles
def sum(n): def bisum(S,start,stop): //(S,0,5)
if n==0: if start>=stop:
return 0 return 0
else: elif start==stop-1:
return sum(n-1)+n return S[start]
2.Reverse a sequence else:
def reverse(S,start, stop): mid=start+stop //2
if start<stop-1: return bisum(S,start,mid)+ bisum(S,
S[start],S[stop-1]=S[stop-1],S[start] mid,stop)
reverse(S, start+1, stop-1)
3. Power of a number
def pow(x,n):
if n==1:
return x
else:
return pow(x,n-1)*x

Analyzing recursive Algorithms


1. The analysis of the complexity of a recurrence relation involves finding the asymptotic upper bound on the
running time of a recursive algorithm.
2. Reasons for solving recurrences: Algorithm Analysis, Performance comparison, Optimization
3. Three ways of solving recurrences:
 Substitution method
 Recurrence Tree method
 Master method
Substitution Method
Recurrence Tree method
Practice: 1. T(n)=3T(n/4) +cn^2  O(n^2)
2. T(n)=2T(n/2)+cn  O(nlogn)
For Answer refer :
1. https://youtu.be/zeVYepdQ9lY
2. https://youtu.be/bJg_sv7PV-g
Master method for divide and conquer
Note: https://www.youtube.com/watch?v=6CX7s7JnXs0

Master method for subtract and conquer

T(n)=T(n-3)+n^2  O(n^k+1)  O(n^3)

You might also like