Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
STD_Alg_KTURE_p1_large_font.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
272.96 Кб
Скачать

Iterative implementation (by loop)

int fac(int n)

{ int f = 1;

for(int i = 1; i <= n; i++)

f = f*i;

return f;

}//factorial_iterative

Recursive implementation:

int fac(int n)

{ if(n == 0) //if() statement is used to stop recursion

return 1;

else

return n*fac(n-1);

}//factorial_recursive

Both functions are called in the same way:

void main()

{ int n = 3, x;

x = fac(n);

}

Tracing execution of the call of the recursive function: int k = fac(3);

main()

How does a computer process numerous calls and returns?

Data (parameters and other local variables) for each running function are created and pushed on the top of a Program Stack (PS) by the OS, in the activation frame for a current running function.

When a new call is made then the contents of the CPU registers (including the address of the next machine instruction) are also saved in the top activation frame.

When a running function is over, the return to the calling function is made. The top activation frame is popped from the PS. The new top activation frame provides all necessary data to continue execution of the function that made the call.

call1 return4

fac(3) = 3*fac(2) = 6

fac(2) = 2*fac(1) = 2

call2 return3

call3 return2

fac(1) = 1*fac(0) = 1

fac(0) = 1

call4 return1

Sequence of PS contents for the above tracing:

PS

f(0)

call1

call2

call3

f(1)

call4

f(1)

ret1

f(1)

ret2

ret3

f(2)

f(2)

f(2)

f(2)

f(2)

push

f(3)

push

f(3)

push

f(3)

push

f(3)

pop

f(3)

pop

f(3)

pop

main

main

main

main

main

main

main

main is f(3) is f(2) is f(1) is f(0) is f(1) is f(2) is

running running running running running running running

PS

ret4

f(3)

pop

main

main

f(3) is main is

running running

Example: Tracing of the call int k = F(3); of the following recursive function:

main() { int k = F(3);}

int F(int n)

{ if(n < 2)

return n;

Else

return 2*F(n-1) + 3*F(n-2) + 4;

}//F()

void main() { int k = F(3); }

F(2) = 2*F(1) + 3*F(0) + 4 = 6;

F(1) = 1;

F(1) = 1;

F(0) = 0;

F(3) = 2*F(2) + 3*F(1) + 4 = 19;

Call1 return5

c2 r3 c5 r4

c3 r1 c4 r2

Java recursive functions for linked lists.

printList() for Linear Singly Linked List and Linear Singly Linked List classes

iterative solution:

public void printList()

{ Node p = first;

while(p!=null)

{ System.out.print(“, “ + p.data);

p = p.next;

}//while

System.out.println();

}//printList() iterative

Recursive implementation of printList() (for linked lists) by two functions:

//public function just calls the private function. The private function does the whole job.

public void printList()

{ print_recursive(first);

System.out.println();

} //printList()

private void print_recursive(Node p)

{ if(p!=null) { System.out.print(“, “ + p.data);

print_recursive(p.next);

}//if

}//print_recursive

T

#5000

7

#6000

10

null

racing of the call A.printList(); for the given obgect A of the class LinkedList.

A :

first #5000 #6000

main()

A.printList()

Call1 return4

print_recursive(#5000) print: #5000.data (=7) (1st )

call2 return3

print_recursive(#5000.next) #6000 print: #6000.data (=10) (2nd )

call3 return2

print_recursive(#6000.next) null

call4 return1

Printing a linked list (LinkedList class) in reverse order:

public void print_reverse()

{ print_reverse_recursive(first);

System.out.println();

}//print_reverse

private void print_reverse_recusive(Node p)

{ if(p!=null)

{ print_reverse_recusive(p.next);

System.out.print(", " + p.data);

}//if

}//print_reverse_recusive

Tracing the call A.print_reverse() for the above given LSLL object A:

main()

A.print_reverse()

Call1 return4

print_reverse_recursive(#5000) print: #5000.data (=7) (2nd)

call2 return3

print_reverse_recursive(#5000.next) #6000 print: #6000.data (=10) (1st)

call3 return2

print_recursive_recursive(#6000.next) null

call4 return1

Recursive function search() for linked lists (LSLL or LDLL classes)

public boolean search(int item)

{ return search_recursive (item, first); }//search

private boolean search_recursive(int item, Node p)

{ if(p==null) return false;

else if(p.data == item) return true;

else return search_recusive(item, p.next);

}//search_recursive

Topic 10. Introduction to trees.

Informally, a graph is a set of points (vertices, nodes) and a set of lines (edges) connecting points. It is not important if lines are straight or curved, long or short.

A tree is a connected graph that contains no cycles. Examples of trees:

T1 T2 T3

E xamples graphs that are not trees:

G1 (has a cycle) G2 (has a cycle) G3 (is disconnected)

A tree may have a root node (the1st node to appear in tree). In such a case, edges become directed:

father node son node

T he nodes belong to their levels. Level

(root node) A 0 A is father for B, C, and D.

B C D 1 C is father F and G.

E F G 2 F and G are son nodes (sons) of C, and so on.

A leaf is a node without son nodes. In our example, E, F, G, and D are leaf nodes (leaves).

A binary tree is a rooted tree in which any node has not more than 2 sons (0, 1, or 2). Examples:

A  Root nodes are here  X

B C Y

D E F Z U

B_T1 B_T2

In a binary tree each son is either left son or right son. For example, in B_T1 , B is left son and C is right son of root node A. The direction of edges may be not shown (like in B_T2 ). But it is clear from a tree shape.

Most functions for binary trees are recursive because a binary tree has a recursive nature.

A recursive definition of a binary tree: A binary tree is a set of nodes which is:

  • empty;

  • if not empty it is partitioned (divided) into 3 subsets:

  1. One node which is called the root of a binary tree;

  2. A set of nodes which is a binary tree itself and is called the left subtree;

  3. A set of nodes which is a binary tree itself and is called the right subtree.

For example, B_T1 = {A, B, C, D, E, F} = {root = {A}, left subtree1 = {B, D, E}, right subtree1 = {C, F}}.

Left subtree1 = {root1 = {B}, left subtree2 = {D}, right subtree2 = {E}}.

Right subtree1 = {root2 = {C}, left subtree3 = {}, right subtree3 = {F}}. And so on. Recursive decomposition of a subtree ends when it becomes an empty set (like in case of left subtree3).

Operations for binary trees.

There are different types of binary trees: binary search trees, balanced binary trees, etc.

Some operations can be used for any type of binary trees: isEmpty, isFull, makeEmpty, size, traversal of a binary tree. These operations are included into the base class BinaryTree.

Operations addItem, deleteItem, retrieve must be special for each type a binary tree. These operations are included into classes like BinarySearchTree. Such classes inherit the base class BinaryTree.

Representation of binary trees in computer memory.

A binary tree will be represented in memory by linked nodes as follows:

r

8

oot in memory root (reference)

5

4

9

7

8

5

null

4

null

9

null

null

7

null

null

public class TNode { left data right

protected int data;

TNode left, right;

public TNode( int d)

{ data = d; left = right = null; } //constructor

}//class TNode

Topic 11. Traversals of Binary Trees.

Traversal is visiting each node exactly one time and processing the data of each node.

Three types of traversals:

  • Preorder traversal: visit_process(root)  preorder(left subtree)  preorder(right subtree);

  • Inorder traversal: inorder(left subtree)  visit_prcess(root)  inorder(right subtree);

  • postorder traversal: postorder(left subtree)  postorder(right subtree)  visit_prcess(root);

r

7

Preorder sequence: 7, 5, 6, 8, 2, 9

Inorder sequence: 6, 5, 8, 7, 2, 9

Postorder sequence: 6, 8, 5, 9, 2, 7

Here each node was visited for printing (= processing) data.

oot

5

2

6

8

9

In a Java code each traversal algorithm (preorder, inorder and postorder) is presented by 2 functions: public and protected (recursive). Tracing of these functions is done inside the code text.

Java code of the class BinaryTree

Prepared by Dr. Alex Ossyka

//////////////////////////////////////////////////////////////////////////////////////////////////

package binarytree;

// author Dr. Alex Ossyka

public class TNode {

protected int data;

protected TNode left, right;

//*****************************************

public TNode(int item)

{ data = item;

left = right = null;

}//constructor

}//class TNode. It is the type of a node used in binary trees

////////////////////////////////////////////////////////////////////////////////////////////////////////

package binarytree;

public class BinaryTree {

protected TNode root;

//***********************

public BinaryTree()

{ root = null; }// constructor

//***********************

public boolean isEmpty()

{ return root == null; }

//***********************

public boolean isFull()

{ TNode p = new TNode(0);

return p == null;

}

//**********************

public void makeEmpty()

{ root = null; }

//**********************

//preorder, inorder and postorder traversals for printing data on nodes.

public void preorder()

{ System.out.println("preorder sequence of nodes:");

preorder_rec(root);

System.out.println(";");

}//preorder

protected void preorder_rec(TNode p)

{ if(p != null)

{ System.out.print(", " + p.data);

preorder_rec(p.left);

preorder_rec(p.right);

}//if

}//preoder_rec

/* tracing the call: A.preorder(). Given object BinaryTree A including objects n1, n2, n3 of TNode class.

&n1

A:  root Note: &n1 denotes the address of the node n1, etc.

5

&n2

&n3

n1:

null

9

null

null

7

null

n2: n3:

main()

After return8, it is printed: , 5, 9, 7

A.preorder()

call1 return8

call2 return7

A.preorder_rec(&n1)

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]