CSE 40872 Lecture 005

Topic:Data Structures (Linked lists)
Author: Peter Bui <pbui@cse.nd.edu>
Date: September 07, 2009

Linked Lists Definition

Linked List

A collection of elements where each element is composed of the data and a set of links to subsequent elements.

typedef struct IntNode {
    struct IntNode  *next;
    int              data;
} IntNode;

Types of Linked Lists

  1. Singly-linked: Node only has links to next node:

    [1]->[2]->[3]->[4]
    
  2. Doubly-linked: Node has links to next and previous nodes:

    [1]<=>[2]<=>[3]<=>[4]
    
  3. Circularly-linked: List is a cycle with no head or tail:

    [1]->[2]->[3]->[4]   [1]<=>[2]<=>[3]<=>[4]
     ^--------------|     ^=================^
    

Linked Lists Properties

STL Collections

Use list for doubly-linked list and slist for singly-linked list.

list<int> mList;

mList.push_back(0);
mList.push_front(0);

Find Mth to the Last Element

Given a singly-linked list, return the Mth to the last element.

Input:

0 1 2 3 4 5 6 7 8 9
3
5

Output:

6
4

Possible Approaches

  1. Traverse list, check if we are Mth to the last element. O(MN).
  2. Traverse list, keep track of last Mth elements. O(N) + O(M).
  3. Traverse list to get list length (L) and then traverse L - M elements. O(N).
  4. Traverse list and keep track of Mth element away from current. O(N).

Complete find_mth_to_the_last example.

NULL or Cycle

Given a linked list, determine if you have a cycle.

Acyclic:

[1]->[2]->[3]->[4]->[5]->0  # Ends with link to NULL

Cyclic:

[1]->[2]->[3]->[4]->[5]     # Tail points to node in list
           ^---------|

Possible Approaches

  1. Traverse list, keeping track of all nodes already seen.
  2. Traverse list, marking nodes as we go.
  3. Traverse list with two pointers going at different speeds.

Solution

bool is_cyclic(Node *head) { // From Programming Interviews Exposed
    Node *fast, *slow;
    fast = slow = head;
    while (true) {
        if (!fast || !fast->next) {
            return false;
        } else if (fast == slow || fast->next == slow) {
            return true;
        } else {
            slow = slow->next;
            fast = fast->next->next;
        }
    }
}