# Data Structures and Algorithms

## Presentation on theme: "Data Structures and Algorithms"— Presentation transcript:

Data Structures and Algorithms
Lecture (Recursion) Instructor: Quratulain

Outline A definition of recursion How recursion works
How recursion helps simplify some hard problem

Introduction to Recursion
Looping being one of the cornerstones of programming it is in fact possible to create programs without an explicit loop construct. Some languages, such as Scheme, do not in fact have an explicit loop construct like For, While, etc. Instead they use a technique known as recursion . This turns out to be a very powerful technique for some types of problem

Definition Recursion simply means applying a function as a part of the definition of that same function. The key to making this work is there must be a terminating condition

Example The mathematical factorial function is defined as
the product of all the numbers up to and including the argument, and the factorial of 1 is 1. The factorial of N is equal to N times the factorial of (N-1). 1! = 1 2! = 1 x 2 = 2 3! = 1 x 2 x 3 = 2! x 3 = 6 N! = 1 x 2 x 3 x .... (N-2) x (N-1) x N = (N-1)! x N

Pseudocode Integer factorial(n) if n == 1 return 1 ……(base case) else
return n * factorial(n-1) ……. (recursive case) There is a small bug in this definition however, if you try to call it with a number less than 1 it goes into an infinite loop! To fix that change the test to use "<=" instead of "==". This goes to show how easy it is to make mistakes with terminating conditions, this is probably the single most common cause of bugs in recursive functions.

Recursive steps in factorial function
Let's see how that works when we execute it. we get: factorial(4) = 4 * factorial(3) factorial(3) = 3 * factorial(2) factorial(2) = 2 * factorial(1) factorial(1) = 1

Recursion Writing the factorial function without recursion actually isn't that difficult However as we'll see some functions are much harder to write without recursion. Functional Programming tries to focus on the what rather than the how of problem solving. That is, a functional program should describe the problem to be solved rather than focus on the mechanism of solution.

Recursion For some types of problem it is a natural and powerful technique. Unfortunately for many other problems it requires a fairly abstract thinking style, heavily influenced by mathematical principles. The resultant code is often far from readable to the layman programmer. The resultant code is also very often much shorter than the equivalent imperative code and more reliable.

Applications Permutation means a combination of certain units in all possible orderings. Recursion can be effectively used to find all possible combinations of a given set of elements. This has applications in anagrams, scheduling and, of course, Magic Squares. And if you're interested, Recursion can also be used for cracking passwords. Polynomial arithmetics Storage management

what is a magic square? A magic square is a 'matrix' or a 2-dimensional grid of numbers. Take the simple case of a 3x3 magic square. A Magic Square contains a certain bunch of numbers, in this case, 1..9, each of which has to be filled once into the grid. The 'magic' property of a Magic Square is that the sum of the numbers in the rows and columns and diagonals should all be same, in this case, 15. 3x3 magic square , what about 5X5 and more 8 1 6 3 5 7 4 9 2

Concept of magic square
how do we accomplish permuting a set of numbers (or objects) using recursion? For simplicity sake, we work with a 1- dimensional array. In the case of a 3x3 square, let's have a 9-length single- dimensional array. So we have numbers 1 to 9 and 9 locations to put them into.

As a preliminary exercise, try to program the following sequence...
111,112,113,121,122,123,131,132,133, 211,212,213,221,222,223,231,232,233, 311,312,313,321,322,323,331,332, using For loops. Hint: for loop 1 to 3, in each iteration first two terms are same.

for i = 1 to 3 for j = 1 to 3 for k = 1 to 3 print i,j,k Now, try it using recursion.

Answer: Think of it this way: i loops from 1 to 3
Answer: Think of it this way: i loops from 1 to 3. For every value of i, j loops from 1 to 3. For every value of j, k loops from 1 to 3. For every value of k, the values are displayed. So, basically, these three loops perform very similar functions, which can therefore be reduced to a single recursive function with a single loop. void Func(n) { for i = 1 to 3 { A[n] = i if (n<3) Func(n+1) else print A[1],A[2],A[3] }

Homework Write a recursive function that has one parameter which is a size_t value called x. The function prints x asterisks, followed by x exclamation points. Do NOT use any loops. Do NOT use any variables other than x.

Homework Let us consider the problem of computing the kth Fibonacci number. A series contain addition of two previous numbers. 0, 1, 1, 2, 3, 5, 8,13,... The Fibonacci numbers are recursively defined as follows: Base cases: F(0) = 0, F(1) = 1 Recursive call: Fi = Fi−1 + Fi−2 Develop java program for k numbers series and manually trace each step to understand the internal working.

To have an analogy, suppose you are given two identical photos.
It would take you just a glance of the eye to agree that they're same. The computer, on the other hand, would compare them dot by dot, pixel by pixel, and then agree that they're same. In the process, both you and the computer accomplish the same task in pretty much the same time, but in very different ways.

Tower of Hanoi In the great temple at Benares beneath the dome which marks the center of the world, rests a brass plate in which are fixed three diamond needles, each a cubit high and as thick as the body of a bee. On one of these needles, at the creation, God placed sixty-four disks of pure gold, the largest disk resting on the brass plate and the others getting smaller and smaller up to the top one. This is the Tower of Brahma. Day and Night unceasingly, the priests transfer the disks from one diamond needle to another according to the fixed and immutable laws of Brahma, which require that the priest on duty must not move more than one disk at a time and that he must place this disk on a needle so that there is no smaller disk below it. When all the sixty-four disks shall have been thus transferred from the needle on which at the creation God placed them to one of the other needles, tower, temple and Brahmins alike will crumble into dust, and with a thunderclap the world will vanish.

Example Suppose the problem is to move the stack of six disks from needle 1 to needle 2. Part of the solution will be to move the bottom disk from needle 1 to needle 2, as a single move. Before we can do that, we need to move the five disks on top of it out of the way. After we have moved the large disk, we then need to move the five disks back on top of it to complete the solution.

process Move the top five disks to stack 3

process Move the disk on stack 1 to stack 2

process Move the disks on stack 3 to stack 2

Recursive solution If n==1 move the single disk from A to C and stop
Move the top n-1 disks from A to B using C as auxiliary Move the remaining disk from A to C Move the n-1 disks from B to C using A as auxiliary

Pseudo-code Call tower (n, ‘A’, ‘C’, ‘B’);
Function Tower (int n, char frompeg, char topeg, char auxpeg) { If (n==1) print(“from “+frompeg+” +”to “+ topeg) return } Tower(n-1, frompeg, auxpeg, topeg) print(“from “+frompeg+” +”to “+ topeg) Tower (n-1,auxpeg,topeg,frompeg)

Recursive function Each time a recursive function calls itself, an entirely new data area for that particular call must be allocated. This data area contains all parameters, local variables, temporaries, and a return address. Each return causes the current data area to be freed.

Recursion Versus Iteration
There are similarities between recursion and iteration In iteration, a loop repetition condition determines whether to repeat the loop body or exit from the loop In recursion, the condition usually tests for a base case You can always write an iterative solution to a problem that is solvable by recursion Recursive code may be simpler than an iterative algorithm and thus easier to write, read, and debug

Efficiency of Recursion
Recursive methods often have slower execution times when compared to their iterative counterparts The overhead for loop repetition is smaller than the overhead for a method call and return If it is easier to conceptualize an algorithm using recursion, then you should code it as a recursive method The reduction in efficiency does not outweigh the advantage of readable code that is easy to debug

Recursive Array Search
Searching an array can be accomplished using recursion Simplest way to search is a linear search Examine one element at a time starting with the first element and ending with the last Base case for recursive search is an empty array Result is negative one Another base case would be when the array element being examined matches the target Recursive step is to search the rest of the array, excluding the element just examined

Recursive Data Structures
Computer scientists often encounter data structures that are defined recursively Trees are defined recursively Linked list can be described as a recursive data structure Recursive methods provide a very natural mechanism for processing recursive data structures The first language developed for artificial intelligence research was a recursive language called LISP

Recursive Definition of a Linked List
A non-empty linked list is a collection of nodes such that each node references another linked list consisting of the nodes that follow it in the list The last node references an empty list A linked list is empty, or it contains a node, called the list head, that stores data and a reference to a linked list

Backtracking Backtracking is an approach to implementing systematic trial and error in a search for a solution An example is finding a path through a maze If you are attempting to walk through a maze, you will probably walk down a path as far as you can go Eventually, you will reach your destination or you won’t be able to go any farther If you can’t go any farther, you will need to retrace your steps Backtracking is a systematic approach to trying alternative paths and eliminating them if they don’t work

Backtracking (continued)
Never try the exact same path more than once, and you will eventually find a solution path if one exists Problems that are solved by backtracking can be described as a set of choices made by some method Recursion allows us to implement backtracking in a relatively straightforward manner Each activation frame is used to remember the choice that was made at that particular decision point A program that plays chess may involve some kind of backtracking algorithm

Recursion types Linear recursion
Binary recursion (e.g tower of Hanoii) Multiple recursion

Sample questions Why would you use other logic when you can write recursive a function? Ans. Recursion will be bad for code readability - not every programmer can understand it. (if non-recursive is complex) Recursion is a repeated method call stack - the more you use recursion the more memory stack created. It is hard to debug the code.