IMPROVING PSEUDOCODE CS16: Introduction to Data Structures & Algorithms Thursday, February 26, 2015...
-
Upload
augustine-reeves -
Category
Documents
-
view
234 -
download
0
Transcript of IMPROVING PSEUDOCODE CS16: Introduction to Data Structures & Algorithms Thursday, February 26, 2015...
1
IMPROVING PSEUDOCODE
CS16: Introduction to Data Structures & Algorithms
Thursday, February 26, 2015
2
Clean Your Code
• Errors per line ~ constant• Fewer lines fewer errors overall
• Fewer lines are easier to grade• More likely to receive credit
• Cleaner code reflects cleaner thinking and a better understanding of the material
• Let’s work through an example…
Thursday, February 26, 2015
3
Lowest Common Ancestor (LCA)
Problem: Given two nodes u and v, determine the deepest node that’s an ancestor of both.
Thursday, February 26, 2015
A
B DC
G HE F
I J K
u v LCA(u, v)
C D A
J E B
G J A
G C C
4Thursday, February 26, 2015
function LCA(u, v):
lca = nulludepth = T.depth(u)vdepth = T.depth(v)if (T.isroot(u) == true) or (T.isroot(v) == true) then
lca = T.rootwhile (lca == null) do
if (u == v) thenlca = uelseif udepth > vdepth then
u = T.parent(u)udepth = udepth – 1
else if vdepth > udepthv = T.parent(v)vdepth = vdepth – 1
elseu = T.parent(u); udepth = udepth - 1v = T.parent(v); vdepth = vdepth – 1
return lca
5Thursday, February 26, 2015
function LCA(u, v):
lca = nulludepth = T.depth(u)vdepth = T.depth(v)if (T.isroot(u) == true) or (T.isroot(v) == true) then
lca = T.rootwhile (lca == null) do
if (u == v) thenlca = uelseif udepth > vdepth then
u = T.parent(u)udepth = udepth – 1
else if vdepth > udepthv = T.parent(v)vdepth = vdepth – 1
elseu = T.parent(u); udepth = udepth - 1v = T.parent(v); vdepth = vdepth – 1
return lca
What are the inputs? The output?
6Thursday, February 26, 2015
function LCA(u, v):// Input: two nodes u, v// Output: the lowest common ancestor of u and vlca = nulludepth = T.depth(u)vdepth = T.depth(v)if (T.isroot(u) == true) or (T.isroot(v) == true) then
lca = T.rootwhile (lca == null) do
if (u == v) thenlca = uelseif udepth > vdepth then
u = T.parent(u)udepth = udepth – 1
else if vdepth > udepthv = T.parent(v)vdepth = vdepth – 1
elseu = T.parent(u); udepth = udepth - 1v = T.parent(v); vdepth = vdepth – 1
return lca
7Thursday, February 26, 2015
function LCA(u, v):// Input: two nodes u, v// Output: the lowest common ancestor of u and vlca = nulludepth = T.depth(u)vdepth = T.depth(v)if (T.isroot(u) == true) or (T.isroot(v) == true) then
lca = T.rootwhile (lca == null) do
if (u == v) thenlca = uelseif udepth > vdepth then
u = T.parent(u)udepth = udepth – 1
else if vdepth > udepthv = T.parent(v)vdepth = vdepth – 1
elseu = T.parent(u); udepth = udepth - 1v = T.parent(v); vdepth = vdepth – 1
return lca
Where does T come from?
8Thursday, February 26, 2015
function LCA(u, v, T):// Input: two nodes u, v in a tree T// Output: the lowest common ancestor of u and vlca = nulludepth = T.depth(u)vdepth = T.depth(v)if (T.isroot(u) == true) or (T.isroot(v) == true) then
lca = T.rootwhile (lca == null) do
if (u == v) thenlca = uelseif udepth > vdepth then
u = T.parent(u)udepth = udepth – 1
else if vdepth > udepthv = T.parent(v)vdepth = vdepth – 1
elseu = T.parent(u); udepth = udepth - 1v = T.parent(v); vdepth = vdepth – 1
return lca
9
Ways to improve psuedocode
• Clarify your input and output with comments
• This is a good habit to get into and makes methods easily understandable for somebody who has never seen them before
• Make sure all necessary arguments are included as parameters
Thursday, February 26, 2015
10Thursday, February 26, 2015
function LCA(u, v, T):// Input: two nodes u, v in a tree T// Output: the lowest common ancestor of u and vlca = nulludepth = T.depth(u)vdepth = T.depth(v)if (T.isroot(u) == true) or (T.isroot(v) == true) then
lca = T.rootwhile (lca == null) do
if (u == v) thenlca = uelseif udepth > vdepth then
u = T.parent(u)udepth = udepth – 1
else if vdepth > udepthv = T.parent(v)vdepth = vdepth – 1
elseu = T.parent(u); udepth = udepth - 1v = T.parent(v); vdepth = vdepth – 1
return lca
Needlessly complex
11Thursday, February 26, 2015
function LCA(u, v, T):// Input: two nodes u, v in a tree T// Output: the lowest common ancestor of u and vlca = nulludepth = T.depth(u)vdepth = T.depth(v)if (T.isroot(u) == true) or (T.isroot(v) == true) then
lca = T.rootwhile (lca == null) do
if (u == v) thenlca = uelseif T.depth(u) > T.depth(v) then
u = T.parent(u)
else if T.depth(v) > T.depth(u)v = T.parent(v)
elseu = T.parent(u)v = T.parent(v)
return lca
Now irrelevant
12
Ways to improve psuedocode
• Get rid of unnecessary variables• Using variables for information which can be accurately found elsewhere leaves room for careless errors• In this example there is no need for udepth and vdepth when the tree keeps track of the node’s depth
Thursday, February 26, 2015
13Thursday, February 26, 2015
function LCA(u, v, T):// Input: two nodes u, v in a tree T// Output: the lowest common ancestor of u and vlca = null
if (T.isroot(u) == true) or (T.isroot(v) == true) then lca = T.root
while (lca == null) doif (u == v) thenlca = uelseif T.depth(u) > T.depth(v) then
u = T.parent(u)
else if T.depth(v) > T.depth(u)v = T.parent(v)
elseu = T.parent(u)v = T.parent(v)
return lca
14Thursday, February 26, 2015
function LCA(u, v, T):// Input: two nodes u, v in a tree T// Output: the lowest common ancestor of u and vlca = null
if (T.isroot(u) == true) or (T.isroot(v) == true) then lca = T.root
while (lca == null) doif (u == v) thenlca = uelseif T.depth(u) > T.depth(v) then
u = T.parent(u)
else if T.depth(v) > T.depth(u)v = T.parent(v)
elseu = T.parent(u)v = T.parent(v)
return lca
Redundant equality checks
15Thursday, February 26, 2015
function LCA(u, v, T):// Input: two nodes u, v in a tree T// Output: the lowest common ancestor of u and vlca = null
if T.isroot(u) or T.isroot(v) then lca = T.root
while (lca == null) doif (u == v) thenlca = uelseif T.depth(u) > T.depth(v) then
u = T.parent(u)
else if T.depth(v) > T.depth(u)v = T.parent(v)
elseu = T.parent(u)v = T.parent(v)
return lca
16Thursday, February 26, 2015
function LCA(u, v, T):// Input: two nodes u, v in a tree T// Output: the lowest common ancestor of u and vlca = null
if T.isroot(u) or T.isroot(v) then lca = T.root
while (lca == null) doif (u == v) thenlca = uelseif T.depth(u) > T.depth(v) then
u = T.parent(u)
else if T.depth(v) > T.depth(u)v = T.parent(v)
elseu = T.parent(u)v = T.parent(v)
return lca
17Thursday, February 26, 2015
function LCA(u, v, T):// Input: two nodes u, v in a tree T// Output: the lowest common ancestor of u and vlca = nullif T.isroot(u) or T.isroot(v) then
lca = T.rootwhile (lca == null) do
if (u == v) thenlca = uelseif T.depth(u) > T.depth(v) then
u = T.parent(u)else if T.depth(v) > T.depth(u)
v = T.parent(v)else
u = T.parent(u)v = T.parent(v)
return lca
Just removing some whitespace to fit on slides
18
Ways to improve psuedocode
• If a method returns a boolean, there is no need to check if return value == true
• Logical operators can be used on boolean return values • !T.isroot(u)equals T.isroot(u)==false
Thursday, February 26, 2015
19Thursday, February 26, 2015
function LCA(u, v, T):// Input: two nodes u, v in a tree T// Output: the lowest common ancestor of u and vlca = nullif T.isroot(u) or T.isroot(v) then
lca = T.rootwhile (lca == null) do
if (u == v) thenlca = uelseif T.depth(u) > T.depth(v) then
u = T.parent(u)else if T.depth(v) > T.depth(u)
v = T.parent(v)else
u = T.parent(u)v = T.parent(v)
return lca
It’s the answer, return it!
20Thursday, February 26, 2015
function LCA(u, v, T):// Input: two nodes u, v in a tree T// Output: the lowest common ancestor of u and vlca = nullif T.isroot(u) or T.isroot(v) then
lca = T.rootreturn lca
while (lca == null) doif (u == v) thenlca = uelseif T.depth(u) > T.depth(v) then
u = T.parent(u)else if T.depth(v) > T.depth(u)
v = T.parent(v)else
u = T.parent(u)v = T.parent(v)
return lca
It’s the answer, return it!
21Thursday, February 26, 2015
function LCA(u, v, T):// Input: two nodes u, v in a tree T// Output: the lowest common ancestor of u and vlca = nullif T.isroot(u) or T.isroot(v) then
lca = T.rootreturn lca
while (lca == null) doif (u == v) thenlca = ureturn lcaelseif T.depth(u) > T.depth(v) then
u = T.parent(u)else if T.depth(v) > T.depth(u)
v = T.parent(v)else
u = T.parent(u)v = T.parent(v)
return lca
22
Ways to improve psuedocode
• As soon as you know you’ve found the answer, return it!• This avoids going through unnecessary code
Thursday, February 26, 2015
23Thursday, February 26, 2015
function LCA(u, v, T):// Input: two nodes u, v in a tree T// Output: the lowest common ancestor of u and vlca = nullif T.isroot(u) or T.isroot(v) then
lca = T.rootreturn lca
while (lca == null) doif (u == v) thenlca = ureturn lcaelseif T.depth(u) > T.depth(v) then
u = T.parent(u)else if T.depth(v) > T.depth(u)
v = T.parent(v)else
u = T.parent(u)v = T.parent(v)
return lca
Condition is irrelevant
24Thursday, February 26, 2015
function LCA(u, v, T):// Input: two nodes u, v in a tree T// Output: the lowest common ancestor of u and vlca = nullif T.isroot(u) or T.isroot(v) then
lca = T.rootreturn lca
repeatif (u == v) thenlca = ureturn lcaelseif T.depth(u) > T.depth(v) then
u = T.parent(u)else if T.depth(v) > T.depth(u)
v = T.parent(v)else
u = T.parent(u)v = T.parent(v)
lca is no longer used
25Thursday, February 26, 2015
function LCA(u, v, T):// Input: two nodes u, v in a tree T// Output: the lowest common ancestor of u and v
if T.isroot(u) or T.isroot(v) then
return T.rootrepeat
if (u == v) then
return uelseif T.depth(u) > T.depth(v) then
u = T.parent(u)else if T.depth(v) > T.depth(u)
v = T.parent(v)else
u = T.parent(u)v = T.parent(v)
26Thursday, February 26, 2015
function LCA(u, v, T):// Input: two nodes u, v in a tree T// Output: the lowest common ancestor of u and vif T.isroot(u) or T.isroot(v) then
return T.rootrepeat
if (u == v) thenreturn uelseif T.depth(u) > T.depth(v) then
u = T.parent(u)else if T.depth(v) > T.depth(u)
v = T.parent(v)else
u = T.parent(u)v = T.parent(v)
27
Ways to improve psuedocode
• If a variable is only used for the purpose of returning something, simply return the value
• This avoids having to keep track of an unnecessary variable and makes your code shorter and clearer
Thursday, February 26, 2015
28Thursday, February 26, 2015
function LCA(u, v, T):// Input: two nodes u, v in a tree T// Output: the lowest common ancestor of u and vif T.isroot(u) or T.isroot(v) then
return T.rootrepeat
if (u == v) thenreturn uelseif T.depth(u) > T.depth(v) then
u = T.parent(u)else if T.depth(v) > T.depth(u)
v = T.parent(v)else
u = T.parent(u)v = T.parent(v)
29Thursday, February 26, 2015
function LCA(u, v, T):// Input: two nodes u, v in a tree T// Output: the lowest common ancestor of u and vwhile T.depth(u) > T.depth(v)
u = T.parent(u)while T.depth(v) > T.depth(u)
v = T.parent(v)if T.isroot(u) or T.isroot(v) then
return T.rootrepeat
if (u == v) thenreturn uelseu = T.parent(u)v = T.parent(v)
30
Ways to improve psuedocode
• If you know you will not enter a conditional after one iteration through a while loop, attempt to use two separate while loops to simplify• In this example, if u is at a lower depth than v, the algorithm will not allow u to get to a higher depth than v. Therefore, it is unnecessary to continue checking both of these within one while loop
Thursday, February 26, 2015
31Thursday, February 26, 2015
function LCA(u, v, T):// Input: two nodes u, v in a tree T// Output: the lowest common ancestor of u and vwhile T.depth(u) > T.depth(v)
u = T.parent(u)while T.depth(v) > T.depth(u)
v = T.parent(v)if T.isroot(u) or T.isroot(v) then
return T.rootrepeat
if (u == v) thenreturn uelseu = T.parent(u)v = T.parent(v)
32Thursday, February 26, 2015
function LCA(u, v, T):// Input: two nodes u, v in a tree T// Output: the lowest common ancestor of u and vwhile T.depth(u) > T.depth(v)
u = T.parent(u)while T.depth(v) > T.depth(u)
v = T.parent(v)if T.isroot(u) or T.isroot(v) or u == v then
return urepeat
if (u == v) thenreturn uelseu = T.parent(u)v = T.parent(v)
33Thursday, February 26, 2015
function LCA(u, v, T):// Input: two nodes u, v in a tree T// Output: the lowest common ancestor of u and vwhile T.depth(u) > T.depth(v)
u = T.parent(u)while T.depth(v) > T.depth(u)
v = T.parent(v)if T.isroot(u) or T.isroot(v) or u == v then
return urepeat
if (u == v) thenreturn uelseu = T.parent(u)v = T.parent(v)
Can be simplified!
34
Ways to improve psuedocode
• Avoid unnecessary conditional checks• In this example, after the two while loops, u and v have the same depth. If either is a root, they both are the same root
• Try to be as concise as possible!
Thursday, February 26, 2015
35Thursday, February 26, 2015
function LCA(u, v, T):// Input: two nodes u, v in a tree T// Output: the lowest common ancestor of u and vwhile T.depth(u) > T.depth(v)
u = T.parent(u)while T.depth(v) > T.depth(u)
v = T.parent(v)if u == v then
return urepeat
if (u == v) thenreturn uelseu = T.parent(u)v = T.parent(v)
Condense into a single loop!
36Thursday, February 26, 2015
function LCA(u, v, T):// Input: two nodes u, v in a tree T// Output: the lowest common ancestor of u and vwhile T.depth(u) > T.depth(v)
u = T.parent(u)while T.depth(v) > T.depth(u)
v = T.parent(v)while u != v then
u = T.parent(u)v = T.parent(v)
return u
From a clunky 19 lines to an elegant 8 line beauty!