Topic 5
Topic 5
Three different
representations of
the same 2d array
23 34 54 77 89
Linked lists are normally drawn with boxes and arrows but really they are more like
this...
3F4C
data: 54
next: 3348
HEAD: AF34
210E
data: 34 AF34
next: 3F4C data: 23
next: 210E 3348
124B
data: 77
data: 89
next: 124B
next: 0000
23 34 54 77 89
23 34 54 77 89
You could make this linked list using the Here is the code to add a node on the end
following code: of the list:
Node head = new Node(); Node newNode = new Node();
[Link] = 23; [Link] = 100;
[Link] = new Node(); if (head == null) {
[Link] = 34; head = newNode;
[Link] = new Node(); }
[Link] = 54; else {
[Link] = new Node(); Node tmp = head;
[Link] = 77; while ([Link] != null) {
[Link] = new Node(); tmp = [Link];
[Link] = 89; }
[Link] = newNode;
But as you can see, this approach is not }
workable as the list grows in size. Instead You no longer need to know how to code
we use loops to add nodes. linked list algorithms, but you may well
need to describe linked lists, how they are
constructed and how data is inserted.
FRONT BACK
N
To insert a new node,
you need a pointer to the
node before the location
HEAD
where the new node will 4 12 32 44 79
go. Make sure you
understand why. Can you
TMP
explain why?
N
The next thing to do is
get the new node's next
pointer to point to the
HEAD
Step 3: 24
N
Some of the animations assume you already have a tail pointer , or a pointer to the
last-but-one node.
If you don't already have those for your own linked list operations, it is easy to find the
end of the list using this code:
And if you want to find the last-but-one node , you can do this:
Node tmp = head;
Node lastButOne;
while ([Link] != null) {
lastButOne = tmp;
tmp = [Link];
}
▪ Arrays support direct access , so retrieving a ▪ Linked lists only support sequential access ;
value from the middle of the array is O(1) -- they don't support direct access since you
ie it's very quick. 👍 only have a pointer to the head node. This
▪ Arrays are static . That means you have to say means to retrieve a value from the middle of
how many elements you want when you the list you have to start at the beginning and
declare the array, ie before you use it. This loop through the list. This is O(N). 👎
could be bad if you don't know how many ▪ Linked lists are dynamic , which means you
elements you're likely to want. don't need to say how big they're going to
▪ If you declare too many and don't use them, get. 👍
then you waste memory . 👎 ▪ Linked lists never waste memory because
▪ If you don't declare enough and you need they only contain nodes which have data in
more, then you have to create a whole new them. You also never run out of space to add
array and copy each element across. This nodes (unless I guess if you run out of
takes time . 👎 memory entirely). 👍
▪ Adding and deleting elements from the ▪ It is easy to insert into and delete from the
middle of an array is problematic as well, middle of a linked list.👍
because existing elements need to be shifted
along to make room , or shifted back in
order to fill up any holes created.👎
Click here to see an animation showing insertion into the middle of an array and a linked list.
Shuffle all the cards, including the head pointer. Then (you will need two more students): Next:
1. Only the head/tmp pointer can ask questions. Using these rules, practice some of the algorithms on
2. Other students can only answer: the next slide.
a. Whose address is… [address]? (Student
answers by raising a hand.) Each time the group decides on an action, e.g.
b. The next two questions can only be asking/answering a question, changing a field value,
answered if the tmp pointer is pointing at the etc, get them to write it down on the board in
student: pseudocode. Build up the full pseudocode for each
i. What is the value of your data? algorithm.
ii. Where are you pointing?
© Justin Robertson 2019. All rights reserved.
returns true if the list is empty, otherwise false
Linked List Methods
isEmpty()
getLastElement() returns the value of the tail node On the left are some of the
insertAtHead(num) inserts num as the new head node methods you can include in
your linked list to make it
inserts num as the new tail node
more useful.
insertAtTail(num)
to think hard about all the possible preconditions void insertAtFront(int n) { // insert code }
such as the list is empty, the new node should be void insertAtTail(int n) { // insert code }
placed at the start, middle, end of the list.
void insertInOrder(int n) { // insert code }
class Node {
int data;
Node next;
}
1 2 3
You have to move all of the discs from 1 to 3 subject to two rules.
1 2 3
You can only move one disc at a time.
1 2 3
1 2 3
And you can't put a larger disc on top of a smaller one.
1 2 3
Now, you could start moving stuff about randomly, but you will
quickly find that this is actually quite a tough problem, especially if
you have more than a few discs. A moment's thought draws your
attention to this guy.
1 2 3
Think:
What will the state of the game be when you come to move this
disc? Take one full minute to think about it. Don't shout out. We
will discuss it in a moment.
1 2 3
Because this one is the biggest, when you move it, you will have to
move it to a rod that is empty, and if you want to move it from 1 to
3, then all the others need to be on 2. You quickly realise that at
some point, you will have to get to this next position...
1 2 3
Once you have reached this position, then you can move the big
one over...
1 2 3
And then work on getting the others from 2 to 3.
1 2 3
But how can you get the first four from 1 to 2? Let's consider this as
a separate problem.
1 2 3
A moment's thought draws your attention to this guy. Like before,
if you want to move it from 1 to 2, then all the others need to be on
3 and you quickly realise that at some point, you will have to get to
this position...
1 2 3
Then you can slide the big one over, etc.
1 2 3
The problem of the Towers of Hanoi is to move N
discs from the source peg to the destination peg via
the intermediate peg.
Function Output
call
Actually it is.
Recursion worksheet
© Justin Robertson 2019. All rights reserved.
Discuss in your table
groups.
● In what ways is this
pattern recursive in
nature?
Hints:
if (arg1 == base_case) {
return [value]
else {
Data
All the nodes together form a
binary tree. The nodes within
Recursive! the red triangle also form a
binary tree. The nodes within
the blue triangle also form a
binary tree. How may binary
trees are there in total?
Binary search tree
50
25 76
12 37 65 89
6 17 32 41 59 72 83 95
Binary search tree: A binary tree that has the following properties:
• The left subtree of a node contains only nodes with data less than the node's data.
• The right subtree of a node contains only nodes with data greater than the node's data.
• Both the left and right subtrees are also binary search trees.
Terminology
Parent of the root node
node that
contains 12
Right subtree of
50
the tree of which
Left child of the the 76 node is
node that 25 76 the root
contains 25
12 37 65 89
6 17 32 41 59 72 83 95
Leaf nodes
Binary trees don’t have to be symmetrical
Insertion operation
We want to insert a new node into the tree. Where should we put it?
63
50
25 76
12 37 65 89
6 17 32 41 59 72 83 95
Insertion operation
It is bigger than 50, so go
down the right subtree…
50 63
25 76
12 37 65 89
6 17 32 41 59 72 83 95
Insertion operation
It is smaller than 76, so go
down the left subtree…
50
25 76
63
12 37 65 89
6 17 32 41 59 72 83 95
Insertion operation
It is smaller than 65, so go
down the left subtree…
50
25 76
12 37 65 89
63
6 17 32 41 59 72 83 95
Insertion operation
It is bigger than 59, and
59 has no right children,
so that’s where it goes.
50
25 76
12 37 65 89
6 17 32 41 59 72 83 95
63
Task
Think about how you would code the insert operation…
50
25 76
12 37 65 89
6 17 32 41 59 72 83 95
63
The iterative way
Don’t think about this too long because there is a beautifully elegant alternative…
private Node root;
12 37 65 89
6 17 32 41 59 72 83 95
Binary Tree Traversals
Let's say that you want to print out your binary tree. Here are the three different
traversals.
Which of these would you want to use to print your binary search tree in ascending order?
Task
Write down the order of the numbers as printed by each of the traversals.
void preOrder(Node n){
if(n == null) return;
print(n);
preOrder([Link]); 50
preOrder([Link]);
}
25 76
void inOrder(Node n){
if(n == null) return;
inOrder([Link]);
print(n);
89
inOrder([Link]);
} 12 37 65
4 × (3 + 8)
This is written in what is called infix notation, in which the operators (+, - , x, /) are
written between their operands. It is the usual notation that you are familiar with
from mathematics.
However, there are two other ways of writing expressions like these, and both of
them are used in computer science.
In prefix notation, also known as Polish notation, the operators come before their
operands.
In postfix notation, also known as Reverse Polish notation, the operators come
after their operands.
Examples
Infix: 4 × (3 + 8)
Prefix: × 4 + 3 8
Postfix: 4 3 8 + ×
1. 4+5
2. 4/3+7
3. (5 + 2) × (3 + 1)
4. 4 / (3 + 6) + 5 × 9
This is not on the syllabus any more but it's a good example of how binary trees are used.
Reasons:
Task
• Create annotated notes in Word, using drawing
objects.
• Show how 5 x (4 + 3) is converted to postfix
notation.
• Show how the postfix expression is evaluated
using a stack.
This is not on the syllabus any more but it's a good example of how binary trees are used.
Task answer
Parse expression 5 × (4 + 3)
1
3
Convert to postfix: 543+×
Push 5 4
Push 4
5
Push 3 (diagram 1)
Pop 3 2
7
Pop 4
5
Push 3 + 4 = 7 (diagram 2)
Pop 7
3
Pop 5 35
Push 7 × 5 = 35 (diagram 3)
Past exam questions
Past exam questions (cont.)
Recursion Advantages:
● Some problems are much easier to
A recursive function is a function that calls itself, either
program using recursion.
directly or indirectly. Recursion is a powerful programming
technique in which a problem is divided into a set of similar
subproblems, each solved with a trivial solution. Generally, a Disadvantages:
recursive function calls itself to solve its subproblems. ● Can be confusing.
Douglas Crockford, JavaScript the Good Parts, 2008 ● Can take up a lot of memory with
repeated calls.
● Can be slower than iterative
int fib(int n) { alternatives.
if (n <= 1)
return n;
else
return (fib(n-1) + fib(n-2));
}
boolean binSearch(int[] x, int start, int end, int n)
{
int gcd(int m, int n) { if (end < start) return false;
if ((m % n) == 0) int mid = (start+end) / 2;
return n; if (x[mid] == n) {
return true;
else } else {
return gcd(n, m % n); if (x[mid] < n) {
} return binSearch(x, mid+1, end, n);
} else {
return binSearch(x, start, mid-1, n);
int factorial(int n) { }
if (n == 0) }
return 1; }
else
return (n * factorial(n-1));
} © Justin Robertson 2019. All rights reserved.
Junk
32 8 21 10
[0] [0] [1] [2] [3]
[1]
4 64 24 19
[2] [0] [1] [2] [3]
44 13 73 50
[0] [1] [2] [3]
[0]
32 8 21 10
[1]
4 64 24 19
[2]
44 13 73 50
12 65
3 17 43 77
13 24 69