Improving Pseudo-Code CS16: Introduction to Data Structures & - - PowerPoint PPT Presentation

improving pseudo code
SMART_READER_LITE
LIVE PREVIEW

Improving Pseudo-Code CS16: Introduction to Data Structures & - - PowerPoint PPT Presentation

Improving Pseudo-Code CS16: Introduction to Data Structures & Algorithms Spring 2020 CleanYour Code! Errors per line is approximately constant fewer lines fewer errors overall Fewer lines are easier to grade more likely to


slide-1
SLIDE 1

Improving Pseudo-Code

CS16: Introduction to Data Structures & Algorithms Spring 2020

slide-2
SLIDE 2

CleanYour Code!

  • Errors per line is approximately constant
  • fewer lines → fewer errors overall
  • Fewer lines are easier to grade
  • more likely to receive credit
  • Clean code reflects clean thinking
  • and a better understanding of material
  • Let’s see some examples
2
slide-3
SLIDE 3

Lowest Common Ancestor

  • Given two nodes u and v
  • determine deepest node that is ancestor of both
3 A B D C G H E F I J K u v LCA(u, v) C D A J E B G J A G C C 3
slide-4
SLIDE 4

Lowest Common Ancestor

4

3 min

Activity #1

slide-5
SLIDE 5

Lowest Common Ancestor

5

3 min

Activity #1

slide-6
SLIDE 6

Lowest Common Ancestor

6

2 min

Activity #1

slide-7
SLIDE 7

Lowest Common Ancestor

7

1 min

Activity #1

slide-8
SLIDE 8

Lowest Common Ancestor

8

0 min

Activity #1

slide-9
SLIDE 9

Ways to Improve Pseudo-Code

  • Clarify inputs and outputs with comments
  • good habit and makes methods easier to understand
  • Make sure all necessary arguments are included

as parameters

9
slide-10
SLIDE 10

Lowest Common Ancestor

10 function LCA(u, v): lca = null udepth = T.depth(u) vdepth = T.depth(v) if (T.isroot(u) == true) or (T.isroot(v) == true) then lca = T.root while (lca == null) do if (u == v) then lca = u else if udepth > vdepth then u = T.parent(u) udepth = udepth – 1 else if vdepth > udepth v = T.parent(v) vdepth = vdepth – 1 else u = T.parent(u); udepth = udepth - 1 v = T.parent(v); vdepth = vdepth – 1 return lca

Inputs &

  • utputs ?
slide-11
SLIDE 11

Lowest Common Ancestor

11 function LCA(u, v): // Input: two nodes u, v // Output: the lowest common ancestor of u and v lca = null udepth = T.depth(u) vdepth = T.depth(v) if (T.isroot(u) == true) or (T.isroot(v) == true) then lca = T.root while (lca == null) do if (u == v) then lca = u else if udepth > vdepth then u = T.parent(u) udepth = udepth – 1 else if vdepth > udepth v = T.parent(v) vdepth = vdepth – 1 else u = T.parent(u); udepth = udepth - 1 v = T.parent(v); vdepth = vdepth – 1 return lca
slide-12
SLIDE 12

Lowest Common Ancestor

12 function LCA(u, v): // Input: two nodes u, v // Output: the lowest common ancestor of u and v lca = null udepth = T.depth(u) vdepth = T.depth(v) if (T.isroot(u) == true) or (T.isroot(v) == true) then lca = T.root while (lca == null) do if (u == v) then lca = u else if udepth > vdepth then u = T.parent(u) udepth = udepth – 1 else if vdepth > udepth v = T.parent(v) vdepth = vdepth – 1 else u = T.parent(u); udepth = udepth - 1 v = T.parent(v); vdepth = vdepth – 1 return lca

Where does T come from?

slide-13
SLIDE 13

Lowest Common Ancestor

13 function LCA(u, v, T): // Input: two nodes u, v in a tree T // Output: the lowest common ancestor of u and v lca = null udepth = T.depth(u) vdepth = T.depth(v) if (T.isroot(u) == true) or (T.isroot(v) == true) then lca = T.root while (lca == null) do if (u == v) then lca = u else if udepth > vdepth then u = T.parent(u) udepth = udepth – 1 else if vdepth > udepth v = T.parent(v) vdepth = vdepth – 1 else u = T.parent(u); udepth = udepth - 1 v = T.parent(v); vdepth = vdepth – 1 return lca
slide-14
SLIDE 14

Ways to Improve Pseudo-Code

  • Get rid of unnecessary variables
  • Using vars for information that is elsewhere…
  • …leads to careless errors
  • In example, no need for udepth and vdepth
  • since Tree keeps track of node’s depth
14
slide-15
SLIDE 15

Lowest Common Ancestor

15 function LCA(u, v, T): // Input: two nodes u, v in a tree T // Output: the lowest common ancestor of u and v lca = null udepth = T.depth(u) vdepth = T.depth(v) if (T.isroot(u) == true) or (T.isroot(v) == true) then lca = T.root while (lca == null) do if (u == v) then lca = u else if udepth > vdepth then u = T.parent(u) udepth = udepth – 1 else if vdepth > udepth v = T.parent(v) vdepth = vdepth – 1 else u = T.parent(u); udepth = udepth - 1 v = T.parent(v); vdepth = vdepth – 1 return lca

Needlessly complex

slide-16
SLIDE 16

Lowest Common Ancestor

16 function LCA(u, v, T): // Input: two nodes u, v in a tree T // Output: the lowest common ancestor of u and v lca = null udepth = T.depth(u) vdepth = T.depth(v) if (T.isroot(u) == true) or (T.isroot(v) == true) then lca = T.root while (lca == null) do if (u == v) then lca = u else if 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); udepth = udepth - 1 v = T.parent(v); vdepth = vdepth – 1 return lca

Now irrelevant

slide-17
SLIDE 17

Lowest Common Ancestor

17 function LCA(u, v, T): // Input: two nodes u, v in a tree T // Output: the lowest common ancestor of u and v lca = null if (T.isroot(u) == true) or (T.isroot(v) == true) then lca = T.root while (lca == null) do if (u == v) then lca = u else if 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
slide-18
SLIDE 18

Ways to Improve Pseudo-Code

  • If method returns boolean
  • no need to check if returned value ==true
  • Logical operators can be used on boolean

returned valued

  • !T.isroot(u) is same as

T.isroot(u)==false

18
slide-19
SLIDE 19

Lowest Common Ancestor

19 function LCA(u, v, T): // Input: two nodes u, v in a tree T // Output: the lowest common ancestor of u and v lca = null if (T.isroot(u) == true) or (T.isroot(v) == true) then lca = T.root while (lca == null) do if (u == v) then lca = u else if 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

Redundant equality checks

slide-20
SLIDE 20

Lowest Common Ancestor

20 function LCA(u, v, T): // Input: two nodes u, v in a tree T // Output: the lowest common ancestor of u and v lca = null if T.isroot(u) or T.isroot(v) then lca = T.root while (lca == null) do if (u == v) then lca = u else if 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
slide-21
SLIDE 21

Lowest Common Ancestor

21 function LCA(u, v, T): // Input: two nodes u, v in a tree T // Output: the lowest common ancestor of u and v lca = null if T.isroot(u) or T.isroot(v) then lca = T.root while (lca == null) do if (u == v) then lca = u else if 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 removed whitespace

slide-22
SLIDE 22

Ways to Improve Pseudo-Code

  • As soon as you found answer, return it
  • This avoids going through unnecessary code
22
slide-23
SLIDE 23

Lowest Common Ancestor

23 function LCA(u, v, T): // Input: two nodes u, v in a tree T // Output: the lowest common ancestor of u and v lca = null if T.isroot(u) or T.isroot(v) then lca = T.root while (lca == null) do if (u == v) then lca = u else if 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!

slide-24
SLIDE 24

Lowest Common Ancestor

24 function LCA(u, v, T): // Input: two nodes u, v in a tree T // Output: the lowest common ancestor of u and v lca = null if T.isroot(u) or T.isroot(v) then lca = T.root return lca while (lca == null) do if (u == v) then lca = u else if 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!

slide-25
SLIDE 25

Lowest Common Ancestor

25 function LCA(u, v, T): // Input: two nodes u, v in a tree T // Output: the lowest common ancestor of u and v lca = null if T.isroot(u) or T.isroot(v) then lca = T.root return lca while (lca == null) do if (u == v) then lca = u return lca else if 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
slide-26
SLIDE 26

Ways to Improve Pseudo-Code

  • If variable is only used to return something
  • simply return it
  • Avoids keeping track of unnecessary variables
  • and makes code shorter and cleaner
26
slide-27
SLIDE 27

Lowest Common Ancestor

27 function LCA(u, v, T): // Input: two nodes u, v in a tree T // Output: the lowest common ancestor of u and v lca = null if T.isroot(u) or T.isroot(v) then lca = T.root return lca while (lca == null) do if (u == v) then lca = u return lca else if 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

slide-28
SLIDE 28

Lowest Common Ancestor

28 function LCA(u, v, T): // Input: two nodes u, v in a tree T // Output: the lowest common ancestor of u and v lca = null if T.isroot(u) or T.isroot(v) then lca = T.root return lca repeat if (u == v) then lca = u return lca else if 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

slide-29
SLIDE 29

Lowest Common Ancestor

29 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.root repeat if (u == v) then return u else if 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)
slide-30
SLIDE 30

Lowest Common Ancestor

30 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.root repeat if (u == v) then return u else if 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)
slide-31
SLIDE 31

Ways to Improve Pseudo-Code

  • If you never enter a conditional in a while loop,
  • try to use two while loops to simplify
  • If u is at lower depth than v, algorithm will not

allow u to get to a higher depth than v

  • so unnecessary to check both within one

while loop

31
slide-32
SLIDE 32

Lowest Common Ancestor

32 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.root repeat if (u == v) then return u else if 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); udepth = udepth - 1 v = T.parent(v); vdepth = vdepth – 1

Only one of these conditionals will ever be true

slide-33
SLIDE 33

Lowest Common Ancestor

33 function LCA(u, v, T): // Input: two nodes u, v in a tree T // Output: the lowest common ancestor of u and v while 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.root repeat if (u == v) then return u else u = T.parent(u) v = T.parent(v)
slide-34
SLIDE 34

Ways to Improve Pseudo-Code

  • Avoid unnecessary conditional checks
  • In example, after the two while loops,
  • u and v have same depth
  • if either is root, they both are the same root
  • Try to be as concise as possible!
34
slide-35
SLIDE 35

Lowest Common Ancestor

35 function LCA(u, v, T): // Input: two nodes u, v in a tree T // Output: the lowest common ancestor of u and v while 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.root repeat if (u == v) then return u else u = T.parent(u) v = T.parent(v)
slide-36
SLIDE 36

Lowest Common Ancestor

36 function LCA(u, v, T): // Input: two nodes u, v in a tree T // Output: the lowest common ancestor of u and v while 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 u repeat if (u == v) then return u else u = T.parent(u) v = T.parent(v)
slide-37
SLIDE 37

Ways to Improve Pseudo-Code

  • After the two while loops,
  • u and v have same depth
  • if either is root, then they both are root
  • Try to be as concise as possible!
37
slide-38
SLIDE 38

Lowest Common Ancestor

38 function LCA(u, v, T): // Input: two nodes u, v in a tree T // Output: the lowest common ancestor of u and v while 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 u repeat if (u == v) then return u else u = T.parent(u) v = T.parent(v)

Can be simplified

slide-39
SLIDE 39

Lowest Common Ancestor

39 function LCA(u, v, T): // Input: two nodes u, v in a tree T // Output: the lowest common ancestor of u and v while 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 u repeat if (u == v) then return u else u = T.parent(u) v = T.parent(v)
slide-40
SLIDE 40

Lowest Common Ancestor

40 function LCA(u, v, T): // Input: two nodes u, v in a tree T // Output: the lowest common ancestor of u and v while 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 u repeat if (u == v) then return u else u = T.parent(u) v = T.parent(v)

Condense into a single loop

slide-41
SLIDE 41

Lowest Common Ancestor

41 function LCA(u, v, T): // Input: two nodes u, v in a tree T // Output: the lowest common ancestor of u and v while 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 clunky 19 lines to elegant 8 lines!

slide-42
SLIDE 42

Improve Pseudo-Code

  • Now that you have seen how easily pseudocode

can be simplified…

  • …you are expected to make similar improvements to

your pseudo-code

  • Good pseudo-code is both accurate & concise
42