Skip to main content

CSC 207.02 2019S, Class 33: Traveral and Iterators

Overview

  • Preliminaries
    • Notes and news
    • Upcoming work
    • Extra credit
    • Questions
  • Mentor evals
  • About traversal and iterators

Preliminaries

News / Etc.

  • I think today sets a new record for the length of the preliminaries.
  • This day has switched from hash tables to traversal/iteration.
    • I had hoped to discuss both, but the morning session suggested that we need the full class for traversal/iteration.
  • I plan to return makeup exams on Friday.
  • The College has decided to institute electronic end-of-course evaluations. You should be getting information about them next week. We will do evaluations in class on the last day of class, so you should not be able to access this class’s EOCEs before then.
  • Next week’s Science Teaching and Learning Group will discuss student wellness. I’m hoping to share some of the extra credit reports you’ve submitted (anonymously). Let me know if you object to me sharing yours.
  • Since there were some questions about Monday’s quiz, we’ll spend some time discussing the various issues and approaches.
  • Given how quizzes have gone this semester, I’m not counting them in your final grade. (Or I’m counting them based on the percentage you took.) (Or maybe I’ll do “whichever is higher: your grade counting quizzes or your grade not coutning quizzes”.)
  • You should think about taking HIS 295, which approaches some computational topics from a very different perspective.

    HIS 295 Digital History: Investigating the Past. This course will introduce students to methods used in the digital humanities, with a special emphasis on applications to historical studies. Students will create projects and study existing digital projects, with a special focus on U.S. History in a global context. Readings will include primary sources as well as recent contributions to theory in digital humanities. We will learn general principles of working with humanistic data as well as techniques such as building on-line exhibitions, digital mapping, and computational analysis of text. No technical skills or experience in digital humanities work are required, but willingness to gain both are fundamental to the class. Prerequisite: HIS-100 or second-year standing.

Upcoming work

  • No additional reading! (But you may want to review.)
  • Assignment 8 due Thursday the 25th
  • Exam 2 to be distributed Friday.
  • Today’s lab writeup: TBD

Extra credit

Extra credit (Academic/Artistic)

  • Tomorrow: PBK Convo, Thursday, 11am: “Antievolutionism in Historical Perspective”
  • Tomorrow: McKibben lecture, Thursday, 4:15 p.m., JRC 101
  • New/Tomorrow: Technology and the Arts:

    Guest Artist Carol Burch-Brown is the creator of “Salt Marsh Suite” a collaborative inter-media arts installation and dance performance based in fieldwork, data collection, and close observation of a North Carolina coastal estuary. Join us on Thursday April 25th at 11AM in the Flanagan Theatre to see the installation, and hear Carol talk about the digital art-making processes, specifically theerror. MAX coding environment, and other digital tools she used to make this unique work.

    Performances: Thurs April 25-Saturday April 27 at 7:00PM and 8:30PM; Sunday April 28 2PM and 3:30PM.

  • New: CS Table, next Tuesday, Big data and Facebook
  • New: Three talks by Prof. Dr. Yvonne Foerster (https://yvonnefoerster.com/)

    Wednesday: May 1, 4:30-6pm, HSSC S3325: Beyond the Anthropocene: Technology, Innovation, and the (Post-)Human Condition

    Emergent technologies today are advertised as means to create a better future, while the futures imagined in popular science and culture move rather towards the transcendence of human life. This talk examines the conception of innovation between the technological enthusiasm to overcome human limitations and the necessity to critically reflect on the (post-)human condition.

    Thursday, May 2, Noon-12:50pm, HSSC N3110 Degrees of Freedom: Embodiment, Neuroplasticity, and the Need for a Critical Neuroscience

    Lunch and beverages provided

    Neuroplasticity, the ability of the brain to adjust to new affordances and to overcome limitations through damage, has been part of a discourse that celebrated freedom rather than neuro-determinism. My aim is to discuss this concept with regard to the rise of neurocultures (e.g., enhancement strategies, neuromarketing) in a more critical light.

    Friday, May 3, Noon-12:50pm, Bucksbaum 152: Designing Future Bodies: Fashion and Technology

    Lunch and beverages provided

    Fashion and technology are inextricably linked in production, marketing, design, and functionality. In this talk I shed some light on the potential of fashion to critically examine the role of technology in shaping bodies, gender, and social relations. I will take a closer look at experimental practices and scientific cooperation in the field of fashion.

Extra credit (Peer)

  • Track at Grand View on Friday. (Attend class first!)
  • Kinetic Sculpture Competition, Saturday 1-3pm in Central Park.
  • YGB, 4pm Saturday in Sebring-Lewis.
  • Sunday at 1pm Food Recovery Network Award and Presentation with EPA Science Person (JRC 226)
  • Swing/Contra with Live Band Friday at 8:00-10:30 in Loose Lounge
  • Titular Head Saturday.

Extra credit (Wellness)

  • New: Guided Movement Meditations, 12:15 Friday and Saturday, Flanagan Theatre. Also between performances of the show.
  • New: Bread-Making Workshop, Friday, 6-8 p.m. Sign up through grahamj@grinnell.edu. (Limited to 12 people.) (May be filled already.)

Extra credit (Wellness, Regular)

  • 30 Minutes of Mindfulness at SHACS/SHAW every Monday 4:15-4:45
  • Any organized exercise. (See previous eboards for a list.)
  • 60 minutes of some solitary self-care activities that are unrelated to academics or work. Your email reflection must explain how the activity contributed to your wellness.
  • 60 minutes of some shared self-care activity with friends. Your email reflection must explain how the activity contributed to your wellness.

Extra credit (Misc)

Other good things

  • Today: Dartanyan Brown discussion, 4pm Wednesday April 24, HSSC S3325
  • Today: Dartanyan Brown concert, 7:30pm Wednesday April 24, Sebring-Lewis
  • Today: Irish Music in Bob’s at 7:30pm.

Questions

Do I really need to understand the analysis starting on p. 671?

You should read that analysis. However, I don’t expect you to understand it all. It would be good to understand the early recurrence relations and how they are derived.

How do I do part 3 of the assignment?

You will likely need to augment your various procedures to log the number of steps they take. (I’d count each time you follow an edge and each time you switch a level.)

Pick a variety of sizes (e.g., 1000, 2000, 4000, 8000) and, for each size, do a bunch of calls to add, get, and remove. That should give you a minimum, maximum, and average number of steps for each operation.
(I’d do each size a few different times.)

See if the growth appears logarithmic.

Why can’t I call nodes.add(i, node)?

Most frequently, because the size of nodes is less than i.

But I initialized nodes with new ArrayList<Node<K,V>>(16) and i is less than 16.

That creates an arraylist of capacity 16, but size 0.

Any hints?

I found it helpful to write a general find procedure that gave me an ArrayList of all the previous nodes. I used that for set, get, and remove.

I found it useful to create a dummy node for the front of the list. (The latter required me to customize the comparator to handle the dummy node.)

I got sick of typing things like node.next.get(i), so I wrote a method that just gets the ith element of the next field of a node. (Neither of these methods are necessary, but they were helpful.)

  /**
   * Get the next node at the specified level.
   */
  public SLNode<K, V> next(int level) {
    return this.next.get(level);
  } // next

  /**
   * Set the next node at the specified level.
   */
  public void setNext(int level, SLNode<K, V> next) {
    this.next.set(level, next);
  } // setNext(int, SLNode<K,V>)

How might we skip over a node for remove?

You will make an arraylist (or array) of previous nodes. Let’s say it’s called nodes. For each level, you’ll write something like.

    SLNode<K,V> prev = nodes.get(level);
    prev.setNext(level, prev.next(level).next(level));

What should we count for part 3?

You can either count every call to next and every change in level, or every time you actually follow a next link and every change in level.

They will be similar. (The former is approximately twice as big as the latter.)

If you use the next method above, you could just increment the counter there.

Should the height of the skip list change?

I tend to allow my skip lists to grow, but you can choose to cap the height at something reasonable.

_Can we follow the paper’s approach of capping heights at MAX_HEIGHT, starting the list’s height at 1, and increasing the height when there’s a new node?

Sure.

How should we treat the issues of someone trying to remove something that’s not there? (Particularly when there’s nothing there).

The documentation says that you should return null.

if (this.front.get(0) == null) { return null; }.

There’s a bug in your tests.

Probably. I’ll check it this afternoon.

Types of tree traversal

       __ A __
      /       \
     Q         X
    / \       /
   B   D     L
              \
               M

Ten different types of traversal, guided by three principles

  • In-order vs Preorder vs Postorder: Do we process a node (a) between children, (b) before children, or (c) after children.
  • Breadth-first vs. Depth-first: Do we go deep into one subtree before visiting the other subtree or do you go accross each level?
  • Left-to-right vs Right-to-left

That gives twelve. Why did Sam say ten?

  • In-order breadth-first doesn’t make sense. (Left-to-right or right-to-left)

Examples:

  • Breadth first, preorder (top-down), left-to-right: A Q X B D L M
  • Breadth first, postorder (bottom-up), right-to-left: M L D B X Q A
    • Exact reverse of the previous one!
  • Depth-first, preorder, left-to-right: A Q B D X L M

Of these ten, what do you think the most common ones are (and why)?

  • Breadth-first, preorder (top-down), left-to-right: “It makes sense; helps you better visualize the levels”. Matches how we read. Gives nodes closer to the root first.
  • Depth-first, preorder, left-to-right: Seems natural for code. Easy to implement with recursion. (process(node), visit(left), visit(right)). Used for dump.
  • Depth-first, inorder, left-to-right: If we’re working in a BST, gives us the keys in sorted order.

Implementing a complete traversal method

Idea: Use a queue

void forEach(BiConsumer<K,V> action) {
  if (root == null) { return; }
  SimpleQueue<Node<K,V>> q = new SimpleQueue<Node<K,V>>(root);
  while (!q.isEmpty()) {
    Node<K,V> node = q.get(); // dequeue
    action.accept(node.key(), node.value());
    // Do something with left and right
    if (node.left != null) { q.put(node.left); }
    if (node.right != null) { q.put(node.right); }
  } // while
} // forEach

Turning it into an iterator

Key idea: Go from a control structure to an object that keeps track of the state of looping. (That allows us to pause the loop and then restart it, among other things).

void Iterator<Node<K,V>> iterator() {
  return new Iterator<K,V>() {
    SimpleQueue<Node<K,V>> q = new SimpleQueue<Node<K,V>>(root);

    public boolean hasNext() {
      return !q.isEmpty();
    } // hasNext

    public Node<K,V> next() {
      Node<K,V> node = q.get(); // dequeue
      if (node.left != null) { q.put(node.left); }
      if (node.right != null) { q.put(node.right); }
      return node;
    } // next
  }; // new Iterator<K,V>
} // iterator()

If the iterator is public, we probably don’t want to reveal the nodes.

void Iterator<Pair<K,V>> iterator() {
  return new Iterator<K,V>() {
    SimpleQueue<Node<K,V>> q = new SimpleQueue<Node<K,V>>(root);

    public boolean hasNext() {
      return !q.isEmpty();
    } // hasNext

    public Pair<K,V> next() {
      Node<K,V> node = q.get(); // dequeue
      if (node.left != null) { q.put(node.left); }
      if (node.right != null) { q.put(node.right); }
      return new Pair<K,V>(node.key(), node.value());
    } // next
  }; // new Iterator<K,V>
} // iterator()

Choosing other traversal mechanisms

What would you change to make this depth-first rather than breadth-first?

void Iterator<Pair<K,V>> iterator() {
  return new Iterator<K,V>() {
    SimpleStack<Node<K,V>> s = new SimpleStack<Node<K,V>>(root);

    public boolean hasNext() {
      return !q.isEmpty();
    } // hasNext

    public Pair<K,V> next() {
      Node<K,V> node = s.get(); // dequeue
      if (node.right != null) { s.put(node.right); }
      if (node.left != null) { s.put(node.left); }
      return new Pair<K,V>(node.key(), node.value());
    } // next
  }; // new Iterator<K,V>
} // iterator()

What would you do for inorder?

What would you do for postorder?

What would you do for right-to-left