CS361 Outline

Spring 2024, Ashok Kumar Veerasamy

1 Preamble

Welcome to CS361

KEYS TO SUCCESS IN THIS COURSE:

1 Part I 01/07/2024 - 02/17/2024

1.1 Overview and ADTs Review 01/07/2024 - 01/13/2024

Overview

Coming into this course, you should already be familiar with Abstract Data Types and with the way that C++ classes are used to implement them.

To be certain that everyone is on the same page, however, this module examines some critical information about data and functions in C++.

Most of this material should be review for you, though it may be presented from a different perspective than you are used to. If you find yourself completely lost in these readings and/or unable to complete the first assignment, you may need to plan on doing some very rapid but intense review of the prerequisite material (the Resources page has useful links) or even reconsider whether you are prepared to take this course.


  1. Orientation 01/11/2024, 5:00PM EST
  2. [Q&A Discussion Forum]
  3. Weiss, Ch 1

  4. Choosing Your Programming Environment
  5. Lab 1: Setting Up Your Programming Environment 01/13/2024
  6. How data is Stored in C++
  7. Functions in C++
  8. Comparing Data
  9. Copying Data and the "Rule of the Big 3"
  1. See website for assignment

1.2 Templates and Iterators 01/14/2024 - 01/20/2024

Overview

Templates and iterators are often used together to provide patterns for code that can be applied to a wide range of underlying data structures.


  1. Algorithms as Patterns for Code
  2. Function Templates
  3. Class Templates
  4. The Standard Library: Overview
  5. Iterators: an ADT for Positions
  6. Working with Iterators

  7. Lab 2: Working with Iterators & Templates Due: 01/20/2024

1.3 Algorithm Analysis 01/21/2024 - 01/27/2024

Overview

An important theme throughout this semester will be viewing the process of developing software as an engineering process. Now, engineers in traditional engineering disciplines, civil engineers, electrical engineers, and the like, face trade offs in developing a new product, trade offs in cost, performance, and quality.

Software developers face the same kinds of choices. Early on, you may have several alternative designs and need to make a decision about which of those designs to actually pursue. It’s no good waiting until the program has already been implemented, written down in code. By then you’ve already committed to one design and invested significant resources into it.

In this module, we’ll look at mathematical techniques for analyzing algorithms to determine what their speed will be, or, more precisely, how badly their speed will degrade as we apply them to larger and larger amounts of data. The key to doing this will be to analyze the code for its worst case complexity.


  1. Analysis of Algorithms: Motivation
  2. Weiss, Ch 2
  3. Analysis of Algorithms: Worst Case Complexity
  4. The Algebra of Big-O

  5. Big-O Algebra (To find the self assessments, click on the “Quizzes” link in the left navigation bar on Canvas and scroll down to “Practice Quizzes”.)
  6. Worst-Case Complexity Analysis

  7. Complexity: step-by-step, short program fragments (in Canvas)
  8. Case Studies: Analyzing Standalone Functions

  9. Complexity: functions (in Canvas)
  10. Worst-Case Analysis (example)

  11. Quiz: Worst Case Complexity (in Canvas) Due: 01/27/2024

1.4 Sequences 01/28/2024 - 02/03/2024

Overview

A substantial amount of the data that we work with is arranged into a simple linear ordering, one thing after another. Of course, you are already quite familiar with one way of doing this, by putting the data into arrays.

In this module we explore the two most common variations on ADTs for maintaining data in a sequence: vectors and lists.

Vectors provide a mechanism for array-like sequences that can expand to accommodate the amount of data to be stored.

Lists allow for efficient insertion and removal of data from any location in the sequence, at the cost of limiting access to moving sequentially from one end of the list to the other.


  1. Weiss, Ch 3
  2. Vectors
  3. Lab 3: Working with Vectors Due: 02/01/2024
  4. Implementing the Vector Class
  5. Linked Lists

  6. Linked List Applications
  7. Standard Lists
  8. Linear Sequences
  9. See website for assignment

1.5 Generic Programming 02/04/2024 - 02/10/2024

The combination of templates and iterators, combined with a wider range of container types, brings us to generic programming, an important and pervasive style of coding in C++.


  1. Review the exam procedures and set up your proctoring for the Part I exam. 02/04/2024
  2. Generic Programming
  3. Lab 4: Generic Programming Due: 02/10/2024

1.6 Stacks and Queues 02/11/2024 - 02/17/2024

Overview

Sometimes one can achieve more readable, expressive algorithms by using ADTS that limit one’s choices.

Stacks and queues do not do anything that a vector or list cannot, but they limit us to access and modify their contents only at the ends of the sequence, never in the interior. There are a number of useful algorithms that work perfectly within these limitations.


  1. Recursion
  2. Lab 5: Recursion Due: 02/14/2024
  3. Stacks
  4. Queues
  5. Working with Queues

  6. See website for assignment

  7. Deques

1.7 End of Part I

  1. Exam Procedures
  2. Exam 1 (on Canvas) 02/18/2024 - 02/19/2024

2 Part II 02/18/2024 - 03/31/2024

2.1 Average Case Complexity 02/18/2024 - 02/24/2024

Overview

In Part I, we analyzed the speed of algorithms exclusively from the point of view of the worst case. One might argue that this is unnecessarily pessimistic on our part. There are some algorithms for the worst case input is rare enough that we might not be worried about it, particularly if we believe that typical inputs can be handled much more quickly.

We therefore next turn to the idea of average case complexity a measure of how the average behavior of a program degrades as the input sets get larger and larger.


  1. Average Case Analysis

  2. Analysis example: loading and searching sequences

  3. Case Study: Schemes to Improve the Average Case of Sequential Search

  4. Analysis example: loading and searching sequences (part 2)

  5. Lab 6: Average Case Analysis (in Canvas) Due: 02/24/2024

  6. See website for assignment

2.2 Sorting 02/25/2024 - 03/02/2024

Overview

Sorting algorithms arrange data stored in a sequence into a new desired order.

Because the data structures involved are elementary (arrays, vectors, and, occasionally, linked lists) and because the need for sorted data arises in so many practical applications, you probably learned learned one or more sorting algorithms in your earliest programming classes.

But sorting is actually a fairly subtle problem, and the sorting algorithms taught to beginning programmers are chosen for simplicity, not performance. They are often slow and rather clumsy.

In this section we’ll look at more sophisticated sorting algorithms. We’ll also consider the fundamental limits on just how fast a sorting algorithm can get, and we’ll see that some practical algorithms actually approach that upper speed limit.


  1. Weiss, Ch 7
  2. Sorting --- Insertion Sort
  3. Sorting Speed Limits
  4. Sorting --- Merge Sort
  5. Sorting --- Quick Sort
  6. Lab 7: Sorting (in Canvas) Due: 03/02/2024

2.3 Trees 03/10/2024 - 03/16/2024

Overview

Most of the data structures we have looked at so far have been devoted to keeping a collection of elements in some linear order.

Trees are the most common non-linear data structure in computer science. Trees are useful in representing things that naturally occur in hierarchies (e.g., many company organization charts are trees) and for things that are related in a “is-composed-of” or "contains manner (e.g., this country is composed of states, each state is composed of counties, each county contains cities, each city contains streets, etc.)

Trees also turn out to be exceedingly useful in searching. Properly implemented, a tree can be both searched and inserted into in O(log N) time. Compare this to the data structures we’ve seen so far, which may allow us to search in O(log N) time but insert in O(N), or insert in O(1) but search in O(N).


General Trees

  1. Weiss, Ch 4
  2. Trees
  3. See website for assignment

Search Trees

  1. Binary Search Trees
  2. Traversing Trees with Iterators
  3. Weiss, Ch 12.2
  4. Balanced Search Trees

2.4 Sets and Maps 03/17/2024 - 03/23/2024

Overview

We have seen that trees are an efficient data structure for both searching and updating collections of data.

These can serve as the underlying data structure to implement associative containers like sets (collections of items with no duplicates) and maps (lookup “tables” that can search for data associated with keys).


  1. Review the exam procedures and set up your proctoring for the Part 2 exam. 03/17/2024

  2. Sets and MultiSets

  3. Maps and MultiMaps
  4. Working with Sets & Maps

  5. Lab 8: Sets and Maps Due: 03/23/2024

2.5 Hashing 03/24/2024 - 03/30/2024

Overview

Hashing is an alternative to trees for providing fast associative containers (sets and maps).

Hashing stored data in arrays (primarily), but does not store them in any predictable order, or even contiguously. Instead, hashing uses a special “hash function” to compute a desired location for any key we want to insert. If you don’t actually know the internal details of the hash function, its choices of locations would seem arbitrary, almost random.

Nonetheless, it works, and in many cases works well. Hash tables can often store and search for data in O(1) average time.


  1. Hashing
  2. Weiss, Ch 5
  3. Resolving Collisions
  4. Rehashing (Variable Hashing)
  5. Hash-Based Sets and Maps
  6. Lab 9: Unordered Sets Due: 03/27/2024
  7. See website for assignment

2.6 End of Part II

  1. Exam 2 03/31/2024 - 04/01/2024

3 Part III 03/31/2024 - 04/22/2024

3.1 Algorithm Design Techniques 03/31/2024 - 04/06/2024

Overview

By this point in the semester, you’ve learned a lot of algorithms. Many practical problems can be solved by direct application of these. But what do you do when faced with an unfamiliar problem, one for which none of the “canned” algorithms in your personal toolbox are suitable?

When you have to design your own algorithms, you should consider some of the common patterns or styles that are available to you. This lesson looks at these styles, many of which we have seen before, and a few new ones as well.


  1. Weiss, Ch 10
  2. Converting Recursion to Iteration
  3. A Gallery of Algorithmic Styles
  4. Backtracking

  5. Dynamic Programming (the knapsack problem)

  6. See website for assignment

  7. Exponential and NP Algorithms

3.2 Heaps and Priority Queues 04/07/2024 - 04/13/2024

Overview

A priority queue is an ADT that allows us to repeatedly find and remove the largest (or smallest) item from a colleciton of data. They take their name from the idea that they implement a “queue” of items awaiting processing, but one in which some items have higher priority than others and so get to jump to the head of the line if nothing ahead has even higher priority.

Priority queues are generally implemented using heaps, a tree with very special ordering properties.


  1. Weiss, Ch 6
  2. Priority Queues
  3. Heaps
  4. Heapsort
  5. Review the exam procedures and set up your proctoring for the Final exam. 04/12/2024

3.3 Graphs 04/14/2024 - 04/22/2024

Overview

A graph is a collection of vertices (nodes) connected by edges in arbitrary fashion. Graphs are used to represent data relationships that are far more complicated than could be represented using trees or lists.


  1. Weiss, Ch 9
  2. Graphs --- the Basics
  3. Graphs --- ADT and Traversing

  4. Graphs --- Sample Algorithms
  5. Graph algorithms: traverse and min path

  6. Lab 10: Graphs Basics (in Canvas) Due: 04/18/2024

  7. Sharing Pointers and Garbage Collection
  8. Graph algorithms: max-flow and min-cut

  9. See website for assignment

3.4 End of Part III

  1. Final exam (cumulative) 04/29/2024 - 04/30/2024

4 Frequently Asked Questions