Lecture 26 Linked Lists

Joseph Haugh

University of New Mexico

Free Recall

Review Question 1

What is output of the following code?

void main() {
    int *ptr = (int *)malloc(sizeof(int));
    *ptr = 10;
    printf("%d\n", *ptr);
    free(ptr);
    printf("%d\n", *ptr);
}
10
3943? 1120? Segfault?

Review Question 2

What is output of the following code?

void main() {
    int *ptr1 = (int *)malloc(sizeof(int));
    int *ptr2 = (int *)calloc(1, sizeof(int));
    *ptr1 = 5;
    printf("%d %d\n", *ptr1, *ptr2);
    free(ptr1);
    free(ptr2);
}
5 0

Review Question 3

What is output of the following code?

void main() {
    int *ptr = (int *)malloc(5 * sizeof(int));
    for (int i = 0; i < 5; i++) {
        *(ptr + i) = i;
    }
    for (int i = 0; i < 5; i++) {
        printf("%d ", *(ptr + i));
    }
}
0 1 2 3 4

Review Question 4

What is output of the following code?

void main() {
    int *ptr = (int *)malloc(5 * sizeof(int));
    for (int i = 0; i < 5; i++) {
        *(ptr + i) = i;
    }
    free(ptr)
    for (int i = 0; i < 5; i++) {
        printf("%d ", *(ptr + i));
    }
}
7242 0 1909629632 1133610355 4?
6193 0 1416086567 -353966814 4?
Undefined

Review Question 5

What is output of the following code?

void main() {
    int *x = (int *)malloc(sizeof(int));
    int *y = (int *)malloc(sizeof(int));
    *x = 5;
    *y = 10;   
    int *z = x;
    free(x);
    free(y);   
    *z = 20;
    printf("After free: z = %d\n", *z);
}
After free: z = 20? Undefined

Linked List

  • A linked list is a data structure that consists of a sequence of data records such that in each record there is a field that contains a reference (a link) to the next record in the sequence.

  • In the C programming language, the “link” is usually implemented as a pointer. The link could, however, be implemented in other ways (i.e. as an array index).

Why Linked Lists?

Why not just stick with arrays?

  • The order of the linked items may be different from the order that the data items are stored in memory or on disk.

  • Size is not predetermined, so can make better use of memory.

  • We can insert and remove elements without having to reorganize the entire structure.

Linked Lists in File Systems

  • Most file systems store data as linked lists of data blocks.

  • “Defragmenting” a hard disk moves the blocks to maximize the number of blocks that are physically adjacent.

Linked List Access and Insertion

  • Access to the ith element requires walking the list from the beginning and counting links to i. Such a process is said to have a time complexity of O(n).

  • Insertion or Deletion at a known access point has a constant time complexity time O(1).

Basic Structure

Nodes are self-referential structures.

struct ListNode {
  int data;
  struct ListNode *next;
};

Initializing

struct ListNode *createNode(int data) {
  struct ListNode *node =
               malloc(sizeof(struct ListNode));
  node->data = data;
  node->next = NULL;
  return node;
}

Looking through a list

void printlist(struct ListNode* head) {
    struct ListNode *current = head;
    while (current != NULL) {
        printf("%d ", current->data);
        current = current->next;
    }
    printf("\n");
}

Looking through a list

void printlist(struct ListNode* head) {
    struct ListNode *current = head;
    while (current != NULL) {
        printf("%d ", current->data);
        current = current->next;
    }
    printf("\n");
}

Looking through a list

void printlist(struct ListNode* head) {
    struct ListNode *current = head;
    while (current != NULL) {
        printf("%d ", current->data);
        current = current->next;
    }
    printf("\n");
}

Looking through a list

void printlist(struct ListNode* head) {
    struct ListNode *current = head;
    while (current != NULL) {
        printf("%d ", current->data);
        current = current->next;
    }
    printf("\n");
}

List Length

int listlength(struct ListNode* head) {
   struct ListNode* current = head;
   int count = 0;
   while (current != NULL) {
       count++;
       current = current->next;
   }
   return count;
}

Inserting an element

  • Beginning of the list
  • Middle of the list
  • End of the list

Inserting at the beginning

struct ListNode *newNode = createNode(data);
newNode->next = head;
head = newNode;

Inserting at the beginning

struct ListNode *newNode = createNode(data);
newNode->next = head;
head = newNode;

Inserting at the beginning

struct ListNode *newNode = createNode(data);
newNode->next = head;
head = newNode;

Inserting at the beginning

struct ListNode *newNode = createNode(data);
newNode->next = head;
head = newNode;

Inserting at the beginning

struct ListNode *newNode = createNode(data);
newNode->next = head;
head = newNode;

Insert in the middle

struct ListNode* newNode = createNode(data);
newNode->next = currentNode->next;
currentNode->next = newNode;

Insert in the middle

struct ListNode* newNode = createNode(data);
newNode->next = currentNode->next;
currentNode->next = newNode;

Insert in the middle

struct ListNode* newNode = createNode(data);
newNode->next = currentNode->next;
currentNode->next = newNode;

Insert in the middle

struct ListNode* newNode = createNode(data);
newNode->next = currentNode->next;
currentNode->next = newNode;

Insert in the middle

struct ListNode* newNode = createNode(data);
newNode->next = currentNode->next;
currentNode->next = newNode;

Remove from beginning

struct ListNode* node = head;
head = node->next;
free(node);

Remove from beginning

struct ListNode* node = head;
head = node->next;
free(node);

Remove from beginning

struct ListNode* node = head;
head = node->next;
free(node);

Remove from beginning

struct ListNode* node = head;
head = node->next;
free(node);