Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Recursion
Algorithms and Data Structures
COMP3506 / 7505
Arrays
• Data structure consisting of a group of elements
having a single name that are accessed by
indexing.
– computer science definition of an array
• Occupies a contiguous area of storage.
– most programming languages
• Each element has the same data type.
– statically typed programming languages
Java Example 1
1 public class Example1
2 {
3 public static void main(String[] args)
4 {
5 int[] array = new int[4];
6 array[0] = 255;
7 }
8 }
Java Example 1
1 public class Example1
2 {
3 public static void main(String[] args)
4 {
5 int[] array = new int[4];
6 array[0] = 255;
7 }
8 }
Java Example 1
1 public class Example1
2 {
3 public static void main(String[] args)
4 {
5 int[] array = new int[4];
6 array[0] = 255;
7 }
8 }
Java Example 1
1 public class Example1
2 {
3 public static void main(String[] args)
4 {
5 int[] array = new int[4];
6 array[0] = 255;
7 }
8 }
Java Example 1
1 public class Example1
2 {
3 public static void main(String[] args)
4 {
5 int[] array = new int[4];
6 array[0] = 255;
7 }
8 }
Java Example 2
1 public class Example2
2 {
3 public static void main(String[] args)
4 {
5 String[] array = new String[4];
6 array[0] = new String("Hello world");
7 System.out.println(array[0]);
8 }
9 }
Java Example 2
1 public class Example2
2 {
3 public static void main(String[] args)
4 {
5 String[] array = new String[4];
6 array[0] = new String("Hello world");
7 System.out.println(array[0]);
8 }
9 }
Java Example 2
1 public class Example2
2 {
3 public static void main(String[] args)
4 {
5 String[] array = new String[4];
6 array[0] = new String("Hello world");
7 System.out.println(array[0]);
8 }
9 }
Java Example 2
1 public class Example2
2 {
3 public static void main(String[] args)
4 {
5 String[] array = new String[4];
6 array[0] = new String("Hello world");
7 System.out.println(array[0]);
8 }
9 }
Java Example 2
1 public class Example2
2 {
3 public static void main(String[] args)
4 {
5 String[] array = new String[4];
6 array[0] = new String("Hello world");
7 System.out.println(array[0]);
8 }
9 }
Java Example 2
1 public class Example2
2 {
3 public static void main(String[] args)
4 {
5 String[] array = new String[4];
6 array[0] = new String("Hello world");
7 System.out.println(array[0]);
8 }
9 }
Java Example 3
1 public class Array
2 {
3 private Object[] data;
4
5 public Array()
6 {
7 this.data = new Object[4];
8 }
9
10 public static void main(String[] args)
11 {
12 Array arrayObject = new Array();
13 }
14 }
Java Example 3
1 public class Array
2 {
3 private Object[] data;
4
5 public Array()
6 {
7 this.data = new Object[4];
8 }
9
10 public static void main(String[] args)
11 {
12 Array arrayObject = new Array();
13 }
14 }
Java Example 3
1 public class Array
2 {
3 private Object[] data;
4
5 public Array()
6 {
7 this.data = new Object[4];
8 } arrayObject: null
9
10 public static void main(String[] args)
11 {
12 Array arrayObject = new Array();
13 }
14 }
Java Example 3
1 public class Array
2 {
3 private Object[] data;
4
5 public Array()
6 {
7 this.data = new Object[4];
8 } arrayObject: null
9
10 public static void main(String[] args)
11 {
12 Array arrayObject = new Array();
13 }
14 }
Java Example 3
1 public class Array
2 {
3 private Object[] data;
4
5 public Array()
6 {
7 this.data = new Object[4];
8 } arrayObject: null
9
10 public static void main(String[] args)
11 {
12 Array arrayObject = new Array();
13 }
14 }
Java Example 3
1 public class Array
2 {
3 private Object[] data;
4
5 public Array()
6 {
7 this.data = new Object[4];
8 } arrayObject: null
9
10 public static void main(String[] args)
11 {
12 Array arrayObject = new Array();
13 }
14 }
Java Example 3
1 public class Array
2 {
3 private Object[] data;
4
5 public Array()
6 {
7 this.data = new Object[4];
8 } arrayObject: 0xFFFC
9
10 public static void main(String[] args)
11 {
12 Array arrayObject = new Array();
13 }
14 }
Contiguous Uniform Storage
• What does it get us?
• Dynamic
– Heap provides a dynamic supply of memory for
new objects.
• Incremental
– Chained data structure is used to allow incremental
growth.
LinkedList and ListNode
class ListNode<T> {
T element;
ListNode<T> next;
}
…
}
LinkedList (addFirst)
public class LinkedList<T> {
private ListNode<T> head;
private ListNode<T> tail;
private int size;
if (this.tail == null) {
this.tail = aNode;
}
this.size++;
}
}
Java Example 4
1 public class Example4
2 {
3 public static void main(String[] args)
4 {
5 LinkedList<Integer> list = new LinkedList();
6 ListNode<Integer> node = new ListNode();
7
8 node.element = 11;
9
10 list.addFirst(node);
11 }
12 }
Java Example 4
1 public class Example4 0x0000
Program Code
2 { …
3 public static void main(String[] args) … Java Stack
4 {
…
5 LinkedList<Integer> list = new LinkedList();
…
6 ListNode<Integer> node = new ListNode();
7 …
8 node.element = 11; …
9 …
10 list.addFirst(node); …
11 } Free Memory
…
12 } …
…
…
…
…
0xFFFC Memory Heap
Java Example 4
1 public class Example4 0x0000
Program Code
2 { …
3 public static void main(String[] args) … main():
4 {
… PC: 5
5 LinkedList<Integer> list = new LinkedList();
… list: null
6 ListNode<Integer> node = new ListNode();
7 … node: null
8 node.element = 11; …
9 …
10 list.addFirst(node); …
11 } …
12 } … Free Memory
…
…
…
…
0xFFFC Memory Heap
Java Example 4
1 public class Example4 0x0000
Program Code
2 { …
3 public static void main(String[] args) … main():
4 {
… PC: 6
5 LinkedList<Integer> list = new LinkedList();
… list: 0xFFF4
6 ListNode<Integer> node = new ListNode();
7 … node: null
8 node.element = 11; …
9 …
10 list.addFirst(node); …
11 } … Free Memory
12 } …
list: …
LinkedList …
head 0xFFF4 head: null
tail 0xFFF8 tail: null
size: 0 0xFFFC size: 0
Java Example 4
1 public class Example4 0x0000
2 { Program Code
…
3 public static void main(String[] args) … main():
4 {
… PC: 8
5 LinkedList<Integer> list = new LinkedList();
… list: 0xFFF4
6 ListNode<Integer> node = new ListNode();
7 … node: 0xFFEC
8 node.element = 11; …
9 …
10 list.addFirst(node); … Free Memory
11 } …
12 }
…
list: 0xFFEC element: null
LinkedList node:
ListNode 0xFFF0 next: null
head 0xFFF4 head: null
element
tail 0xFFF8 tail: null
next
size: 0 0xFFFC size: 0
Java Example 4
1 public class Example4 0x0000
2 { Program Code
…
3 public static void main(String[] args) … main():
4 {
… PC: 10
5 LinkedList<Integer> list = new LinkedList();
… list: 0xFFF4
6 ListNode<Integer> node = new ListNode();
7 … node: 0xFFEC
8 node.element = 11; …
9 …
Free Memory
10 list.addFirst(node); …
11 } …
12 }
0xFFE8 11
list: 0xFFEC element: 0xFFE8
LinkedList node:
ListNode element: 0xFFF0 next: null
head Integer 0xFFF4 head: null
element
tail value: 11 0xFFF8 tail: null
next
size: 0 0xFFFC size: 0
Java Example 4 0x0000
Program Code
1 public class LinkedList<T> { …
2 private ListNode<T> head; … main():
3 private ListNode<T> tail;
… PC: 10
4 private int size;
… list: 0xFFF4
5
6 public void addFirst(ListNode<T> aNode) { … node: 0xFFEC
7 aNode.next = this.head; … addFirst():
8 this.head = aNode; … PC: 7
9
… this: 0xFFF4
10 if (this.tail == null) {
… aNode: 0xFFEC
11 this.tail = aNode;
12 } Free Memory
13 this.size++; 0xFFE8 11
14 list:} 0xFFEC element: 0xFFE8
15LinkedList
} node: 0xFFF0
element: next: null
ListNode
head Integer 0xFFF4 head: null
element
tail value: 11 0xFFF8 tail: null
next
size: 0 0xFFFC size: 0
Java Example 4 0x0000
Program Code
1 public class LinkedList<T> { …
2 private ListNode<T> head; … main():
3 private ListNode<T> tail;
… PC: 10
4 private int size;
5 … list: 0xFFF4
6 public void addFirst(ListNode<T> aNode) { … node: 0xFFEC
7 aNode.next = this.head; … addFirst():
8 this.head = aNode; … PC: 8
9
… this: 0xFFF4
10 if (this.tail == null) {
… aNode: 0xFFEC
11 this.tail = aNode;
12 } Free Memory
13 this.size++; 0xFFE8 11
14 list:} 0xFFEC element: 0xFFE8
15LinkedList
} node:
element: 0xFFF0 next: null
ListNode
head Integer 0xFFF4 head: null
element
tail value: 11 0xFFF8 tail: null
next
size: 0 0xFFFC size: 0
Java Example 4 0x0000
Program Code
1 public class LinkedList<T> { …
2 private ListNode<T> head; … main():
3 private ListNode<T> tail;
… PC: 10
4 private int size;
5 … list: 0xFFF4
6 public void addFirst(ListNode<T> aNode) { … node: 0xFFEC
7 aNode.next = this.head; … addFirst():
8 this.head = aNode; … PC: 10
9
… this: 0xFFF4
10 if (this.tail == null) {
… aNode: 0xFFEC
11 this.tail = aNode;
12 } Free Memory
13 this.size++; 0xFFE8 11
14 list:} 0xFFEC element: 0xFFE8
15LinkedList
} node:
element: 0xFFF0 next: null
ListNode
head Integer 0xFFF4 head: 0xFFEC
element
tail value: 11 0xFFF8 tail: null
next
size: 0 0xFFFC size: 0
Java Example 4 0x0000
Program Code
1 public class LinkedList<T> { …
2 private ListNode<T> head; … main():
3 private ListNode<T> tail;
… PC: 10
4 private int size;
5 … list: 0xFFF4
6 public void addFirst(ListNode<T> aNode) { … node: 0xFFEC
7 aNode.next = this.head; … addFirst():
8 this.head = aNode; … PC: 11
9
… this: 0xFFF4
10 if (this.tail == null) {
… aNode: 0xFFEC
11 this.tail = aNode;
12 } Free Memory
13 this.size++; 0xFFE8 11
14 list:} 0xFFEC element: 0xFFE8
15LinkedList
} node:
element: 0xFFF0 next: null
ListNode
head Integer 0xFFF4 head: 0xFFEC
element
tail value: 11 0xFFF8 tail: null
next
size: 0 0xFFFC size: 0
Java Example 4 0x0000
Program Code
1 public class LinkedList<T> { …
2 private ListNode<T> head; … main():
3 private ListNode<T> tail;
… PC: 10
4 private int size;
5 … list: 0xFFF4
6 public void addFirst(ListNode<T> aNode) { … node: 0xFFEC
7 aNode.next = this.head; … addFirst():
8 this.head = aNode; … PC: 13
9
… this: 0xFFF4
10 if (this.tail == null) {
… aNode: 0xFFEC
11 this.tail = aNode;
12 } Free Memory
13 this.size++; 0xFFE8 11
14 list:} 0xFFEC element: 0xFFE8
15LinkedList
} node:
element: 0xFFF0 next: null
ListNode
head Integer 0xFFF4 head: 0xFFEC
element
tail value: 11 0xFFF8 tail: 0xFFEC
next
size: 0 0xFFFC size: 0
Java Example 4 0x0000
Program Code
1 public class LinkedList<T> { …
2 private ListNode<T> head; … main():
3 private ListNode<T> tail;
… PC: 10
4 private int size;
5 … list: 0xFFF4
6 public void addFirst(ListNode<T> aNode) { … node: 0xFFEC
7 aNode.next = this.head; … addFirst():
8 this.head = aNode; … PC: 14
9
… this: 0xFFF4
10 if (this.tail == null) {
… aNode: 0xFFEC
11 this.tail = aNode;
12 } Free Memory
13 this.size++; 0xFFE8 11
14 list:} 0xFFEC element: 0xFFE8
15LinkedList
} node:
element: 0xFFF0 next: null
ListNode
head Integer 0xFFF4 head: 0xFFEC
element
tail value: 11 0xFFF8 tail: 0xFFEC
next
size: 1 0xFFFC size: 1
Java Example 4
1 public class Example4 0x0000
2 { Program Code
…
3 public static void main(String[] args) … main():
4 {
… PC: 10
5 LinkedList<Integer> list = new LinkedList();
… list: 0xFFF4
6 ListNode<Integer> node = new ListNode();
7 … node: 0xFFEC
8 node.element = 11; …
9 …
Free Memory
10 list.addFirst(node); …
11 } …
12 }
0xFFE8 11
list: 0xFFEC element: 0xFFE8
LinkedList node:
ListNode element: 0xFFF0 next: null
head Integer 0xFFF4 head: 0xFFEC
element
tail value: 11 0xFFF8 tail: 0xFFEC
next
0
size: 1 0xFFFC size: 1
Linked Lists Summary
• Do not allow access via index
– Must traverse entire list
• Singly linked lists
– Can easily add to head and tail of list
– Can easily remove from head of list
• Doubly linked lists
– Can add to/remove from head and tail
– Can insert anywhere you have a pointer to
Recursion
• Linear Recursion
• Binary Recursion
• Multiple Recursion
Recursion Pattern
• Recursive definition: 1 if n = 0
f (n) =
n f ( n − 1) else
8 1
• Linear Recursion
– Tail Recursion can easily be mapped to iterative
algorithms
• Binary Recursion
– Recursive method contains two recursive calls
(divide and conquer)
• Multiple Recursion
Lecture Summary
• Arrays
– Fast access, slow to increase size (requires copy)
• Linked lists
– Fast access to head and tail, slow random access
• Recursion
Feel Like Programming?
• Write a recursive algorithm that will output all the
subsets of a set of n elements (without repeating
subsets)
• Describe a recursive algorithm that will check if an
array A of integers contains an integer A[i] that is the
sum of two integers that appear earlier in A, that is,
such that A[i] = A[j] + A[k] for j, k < i such that j != k