Introduction


Supplemental material


Getting started with Java

Let's get warmed up with a few simple Java exercises:

In-Class Exercise 1: Write a HelloWorld program that prints a string out (perhaps your name instead of HelloWorld) to the screen. Compile and run at the command-line.

In-Class Exercise 2: Download Wall.java and and ImageTool.java.

In-Class Exercise 3: Download and modify this Java program print out patterns that look like this (when N=5):

  1
  2 1
  3 2 1
  4 3 2 1
  5 4 3 2 1
  

If you need to review Java:

Note: we will be using a recent version of Java but will not use the more advanced or exotic features


What the course is about

In brief:


Some examples of a simple list

What exactly is a list?
    ⇒ A data structure to hold, well, a list of items.

Example:

// Need to import the LinkedList class from java.util:
import java.util.*;

public class ListExample {

    public static void main (String[] argv)
    {
        // Create an empty  list:
        LinkedList<Integer> intList = new LinkedList<Integer> ();

        // Produce data and add each to list.
        for (int i=0; i < 10; i++) {
            // Compute i-th square number.
            int square = i*i;
            intList.add (square);
        }

        // Print.
        for (int i=0; i < 10; i++) {
            int element = intList.get (i);
            System.out.println ("Element #" + i + " = " + element);
        }
    }

}
Note:
  • The data structure above is LinkedList<Integer>, from the Java library.

  • We haven't looked "under the hood" to see how it works; we merely use it above.

  • The example shows how to create a list, how to add stuff and how to extract stuff in order.

Lists can contain any kind of object, for example:

import java.util.*;
import java.awt.*;
import java.awt.image.*;

public class ListExample2 
{
    public static void main (String[] argv) 
    {
        // Create an empty list that can hold objects of type Image:
        LinkedList<Image> imageList = new LinkedList<Image> ();

        // Retrieve images from files using ImageTool, and add one
        // by one into the list.
        ImageTool imTool = new ImageTool ();
        Image image1 = imTool.readImageFile ("alum1.jpg");
        imageList.add (image1);
        Image image2 = imTool.readImageFile ("alum2.jpg");
        imageList.add (image2);
        Image image3 = imTool.readImageFile ("alum3.jpg");
        imageList.add (image3);

        viewImages (imageList);

    }


    // The list as method parameter:

    static void viewImages (java.util.List<Image> imageList)
    {
        ImageTool imTool = new ImageTool ();
        for (Image image : imageList) {        // Note the for-loop
            imTool.showImage (image);
        }
    }

}

In-Class Exercise 4: Download the above program, along with ImageTool.java and the three image files (alum1.jpg, alum2.jpg, alum3.jpg), compile and execute. Can you identify the person in the third picture?

Can an array be used for a list?
      ⇒ Yes, for example

public class ListExample3 {

    public static void main (String[] argv)
    {
        // Plain old array: must specify size
        int[] intList = new int [10];

        for (int i=0; i < 10; i++) {
            intList[i] = i*i;
        }

        // Print.
        for (int i=0; i < 10; i++) {
            System.out.println ("Element #" + i + " = " + intList[i]);
        }
    }
    
}
Note:
  • When using an array, we must specify the size in advance.

  • For some applications, we may not know the desired size ahead of time.

  • Later we will see that arrays can be very efficient.


A queue

What is a queue?

  • In a list:
    • We usually add items at the end, but sometimes also in sorted order.
    • Deletion is usually an afterthought, to "fix" the list.
    • Access is usually front to back, or for a particular element in the list.

  • In a queue:
    • Items are always added at the end.
    • Items are always deleted from the beginning.
    • The whole purpose is to create "order-of-arrival".

Let's look at an example

import java.util.*;

public class QueueExample {

    public static void main (String[] argv)
    {
        // We'll use a list, but treat it like a queue.
        // Note: it's a list meant to hold strings.
        LinkedList<String> queue = new LinkedList<String> ();

        // Add some names:
        queue.add ("Alice");
        queue.add ("Bob");
        queue.add ("Chen");
        queue.add ("Dagmar");
        queue.add ("Eva");
        queue.add ("Faisal");
        
        System.out.println ("Queue contents: " + queue);

        // Extract one by one:
        while (! queue.isEmpty() ) {
            String name = queue.remove ();
            System.out.println ("Next comes " + name);
            System.out.println ("Queue contents: " + queue);
        }
    }
    
}
Note:
  • The output is:
    Queue contents: [Alice, Bob, Chen, Dagmar, Eva, Faisal]
    Next comes Alice
    Queue contents: [Bob, Chen, Dagmar, Eva, Faisal]
    Next comes Bob
    Queue contents: [Chen, Dagmar, Eva, Faisal]
    Next comes Chen
    Queue contents: [Dagmar, Eva, Faisal]
    Next comes Dagmar
    Queue contents: [Eva, Faisal]
    Next comes Eva
    Queue contents: [Faisal]
    Next comes Faisal
    Queue contents: []
        

  • We've used three types of operations: add(), isEmpty(), remove()

  • It's possible to print some data structures in their entirety with a single println:
            System.out.println ("Queue contents: " + queue);
        
    Of course, this may not be a good idea if the queue is large (e.g., 100,000 items).


A stack

What is a stack?

  • You always add items to the front (not the back).
  • You always remove items from the front
        ⇒ you remove the most recently inserted item.

Let's look at an example:

import java.util.*;

public class StackExample {

    public static void main (String[] argv)
    {
        // The Java library has a Stack data structure. Here, we'll
        // make a stack to hold strings.
        Stack<String> toDoList = new Stack<String> ();

        // Add some strings.
        toDoList.push ("Pay bills");
        toDoList.push ("Clean room");
        toDoList.push ("Do homework");
        toDoList.push ("See movie");
        toDoList.push ("Hang out");
        
        // Print.
        System.out.println ("Priorities: ");
        while (! toDoList.isEmpty() ) {
            String nextPriority = toDoList.pop ();
            System.out.println (" " + nextPriority);
        }
    }
    
}
Note:
  • The output is, as you might expect:
    Priorities: 
     Hang out
     See movie
     Do homework
     Clean room
     Pay bills
         

  • The operations we've used are: push(), pop(), isEmpty().

  • Although we have created a stack of strings, we could just as easily create and use a stack of integers or various kinds of objects.


A tree

What is a tree?

  • This a data structure, we'll learn later, that resembles the branch-like structure of a tree.

  • Trees are a fundamental data structure in computer science.

  • There are many variants of trees; we'll learn about Binary Trees in this course.

  • Why use trees at all?
        ⇒ They are simple and efficient.
Consider this example:

public class TreeExample {

    public static void main (String[] argv)
    {
        // Java's library has tree variant called TreeSet.
        // We'll make an instance to hold String's.
        TreeSet<String> unusualWords = new TreeSet<String> ();

        // Put some stuff in.
        unusualWords.add ("queueing");        // Six vowels in a row.
        unusualWords.add ("psychorhythms");   // Longest with one vowel.
        unusualWords.add ("verisimilitudes"); // Longest with alternating vowel/consonant.
        unusualWords.add ("frillless");       // Three letters in a row.
        unusualWords.add ("bookkeeper");      // Three double-letter's in a row.
        unusualWords.add ("cwm");             // Pronounced "koom" (type of crevasse).
        unusualWords.add ("feedback");        // Contains all letters 'a' to 'f'.

        // Print.
        System.out.println (unusualWords);
    }

}
Note:
  • The program prints out:
    [bookkeeper, cwm, feedback, frillless, psychorhythms, queueing, verisimilitudes]
        
    Thus, the output looks like a simple list. It's the internal structure that's tree-like.

  • Like other data structures, this one can hold numbers or any kind of object.

In-Class Exercise 5: In this exercise, you will compare the speed of searching in a tree vs. a straightforward list. Download TreeExample2.java and UniformRandom.java. You will see code that creates a tree and a linked-list and sets them up for a search comparison. The code for searching in the tree is already given. You need to add very similar code for searching in the list. Then, compile and execute.


What the course is really about

Now that we've seen some examples, you have a better sense of what's forthcoming:

  • We will learn how fundamental data structures work, how they are used, and how to build them ourselves.

  • We will learn why they work, for example, why one is faster/better than another.

  • We will learn how data structures are represented in memory.

  • We will strengthen our programming skills and learn more about Java to be able to implement data structures.

  • Along the way, we will also learn about problem-solving and recursion.

Ready?


© 2006, Rahul Simha (revised 2017)