Week 10 Lecture Code

// Pantea Aria

// Linked Lists - Create, travers, insert, length, search

// Build a linked list by inserting values 0 to 9
// at the end (tail) of an initially empty list

// Use a loop to repeatedly add each new node to the tail

// free functions for later

// For now, this program will leak memory

#include <stdio.h>
#include <stdlib.h>

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

struct node *create_node(int data, struct node *next);
void print_list(struct node *head);
struct node * insert_at_tail(struct node *head, int data);  
int list_search(struct node *head, int value);

int main(void) {

    printf("==== Creating List ====\n");

    struct node *head = NULL;

    // Insert some values at the tail
    head = insert_at_tail(head, 5);
    head = insert_at_tail(head, 15);
    head = insert_at_tail(head, 25);
    head = insert_at_tail(head, 35);

    print_list(head);


    printf("\n==== Search Tests ====\n");

    // Search for first element
    printf("Search 5: %d\n", list_search(head, 5));

    // Search for middle element
    printf("Search 25: %d\n", list_search(head, 25));

    // Search for last element
    printf("Search 35: %d\n", list_search(head, 35));

    // Search for value not in list
    printf("Search 100: %d\n", list_search(head, 100));


    printf("\n==== Search in Empty List ====\n");

    struct node *empty = NULL;
    printf("Search 10 in empty list: %d\n",
           list_search(empty, 10));

    return 0;
}

    
struct node *create_node(int data, struct node *next) {
    struct node *new_node = malloc(sizeof(struct node));
    if (new_node == NULL) {
        return NULL;
    }
    new_node->data = data;
    new_node->next = next;
    return new_node;
}

void print_list(struct node *head) {
    printf("List: ");
    struct node *curr = head;
    while (curr != NULL) {
        printf("%d ", curr->data);
        curr = curr->next;
    }
    printf("\n");
}

//                
struct node *insert_at_tail(struct node *head, int data) {
    struct node *new_node = create_node(data, NULL);
    
    // The list is empty
    if (head == NULL) {
        head = new_node;
    } else {
        struct node *current = head; //NULL
        
        while (current->next != NULL) {
            current = current->next;
        }
        current->next = new_node;
    }
    return head;
}

// return 1 if the value is found in the given list
// return 0 otherwise
int list_search(struct node *head, int value) {
    if (head == NULL) {
         return 0;
    }
    struct node *curr = head;
    while(curr != NULL) {
        if (curr->data == value) {
            return 1;
        }
        curr = curr->next;
    }        
    // it means value not found
    return 0;

}
// Pantea Aria

// linked list
// - create_node
// - print_list
// - insert_at_tail
// - delete_first
// - delete_all
// - search_and_delete

#include <stdio.h>
#include <stdlib.h>

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

struct node *create_node(int data, struct node *next);
void print_list(struct node *head);
struct node *insert_at_tail(struct node *head, int data);

struct node *delete_first(struct node *head);
struct node * delete_all(struct node *head);
struct node *search_and_delete(struct node *head, int value);

int main(void) {
    struct node *head = NULL;

    // TODO: Print the empty list
    print_list(head);

    printf("Search and delete from empty list\n");
    // TODO: Try deleting 99 from an empty list
    head = search_and_delete(head, 1000);
    print_list(head);

    // TODO: Build a list that stores 0..9 by inserting at the tail
    for (int i = 0; i < 10; i++) {
        head = insert_at_tail(head, i);
    }
    print_list(head);
    
    printf("delete first '0'\n");
    // TODO: Delete 4 (middle case)
    head = delete_first(head);
    print_list(head);
    
    //delete_all(head);
   // print_list(head);
    

    printf("Search and delete 4\n");
    // TODO: Delete 4 (middle case)
    head = search_and_delete(head, 4);
    print_list(head);

    printf("Search and delete 1000\n");
    // TODO: Delete 99 (not found case)
    head = search_and_delete(head, 1000);
    print_list(head);

    printf("Search and delete 9\n");
    // TODO: Delete 9 (tail case)
    head = search_and_delete(head, 9);
    print_list(head);

    printf("Search and delete 0\n");
    // TODO: Delete 0 (head case)
    head = search_and_delete(head, 0);
    print_list(head);

    // TODO: Free all remaining nodes to prevent memory leaks
    head = delete_all(head);

    print_list(head);

    return 0;
}

// TODO: Allocate memory for a new node using malloc.
// TODO: If malloc fails, return NULL.
// TODO: Set new_node->data and new_node->next, then return new_node.
struct node *create_node(int data, struct node *next) {
    // TODO
    struct node *new = malloc(sizeof(struct node));
    if (new != NULL) {
        new->data = data;
        new->next = next;
        return new;
    } else {  
        return NULL;
    } 
}

// TODO: Traverse from head to NULL and print each node’s data.
// TODO: Print something like: "list:" then the values on one line.
void print_list(struct node *head) {
    // TODO
    struct node *curr = head;
    while (curr != NULL) {
        printf("%d ", curr->data);
        curr = curr->next;
    }
    printf("\n");    
}

// TODO: Insert a new node (with given data) at the end of the list.
// Cases to handle:
// - Empty list: new node becomes the head.
// - Non-empty list: traverse to last node, then link it to new node.
// Return the (possibly updated) head.
struct node *insert_at_tail(struct node *head, int data) {
    // TODO
    struct node *new = create_node(data, NULL);
    if (head == NULL) {
        return new;   //head = new; return head;
    } else {
        // find the last node
        struct node *last = head;
        while (last->next != NULL) {
            last = last->next;
        }
        last->next = new;
    }    
                   
    return head;
}

// TODO: Delete the first node (if it exists) and free it.
// Return the new head pointer.
struct node *delete_first(struct node *head) {
    // TODO
    if (head == NULL) {
        return NULL;   //return head;
    }  
    // head->10->2->X
    // head->2->X
    struct node *tmp = head;
    head = head->next;
    free(tmp);

    return head;
}

// TODO: Free every node in the list.
// Hint: you must save the next pointer before calling free on current.
// issues here
struct node *delete_all(struct node *head) {
    // TODO
    struct node *current = head;

     while (current != NULL) {
        struct node *tmp = current->next;
        free(current);
        current = tmp;
     } 
     return NULL;  
          
}

// TODO: Find the first node whose data == value, remove it from the list,
// and free it.
// Cases to handle:
// - Empty list
// - Value not found
// - Deleting head node
// - Deleting middle/tail node
// Return the updated head.
struct node *search_and_delete(struct node *head, int value) {
    if (head == NULL) {
        return NULL;
    }
    struct node *prev = NULL;
    struct node *curr = head;
    while (curr != NULL && curr->data != value) {
        prev = curr;
        curr = curr->next;
    }
    // 1. if prev = NULL, the first node should be removed
    if (prev == NULL) {
        head = curr->next;
    } else if (curr == NULL) {
        return head;
    } else {    
        prev->next = curr->next;
    }
    free (curr);        

    return head;
}
// Pantea Aria

// Linked Lists - Create, travers, insert, length, search

// Build a linked list by inserting values 0 to 9
// at the end (tail) of an initially empty list

// Use a loop to repeatedly add each new node to the tail

// free functions for later

// For now, this program will leak memory

#include <stdio.h>
#include <stdlib.h>

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

struct node *create_node(int data, struct node *next);
void print_list(struct node *head);
struct node * insert_at_tail(struct node *head, int data);  
int list_search(struct node *head, int value);

int main(void) {

    printf("==== Creating List ====\n");

    struct node *head = NULL;

    // Insert some values at the tail
    head = insert_at_tail(head, 5);
    head = insert_at_tail(head, 15);
    head = insert_at_tail(head, 25);
    head = insert_at_tail(head, 35);

    print_list(head);


    printf("\n==== Search Tests ====\n");

    // Search for first element
    printf("Search 5: %d\n", list_search(head, 5));

    // Search for middle element
    printf("Search 25: %d\n", list_search(head, 25));

    // Search for last element
    printf("Search 35: %d\n", list_search(head, 35));

    // Search for value not in list
    printf("Search 100: %d\n", list_search(head, 100));


    printf("\n==== Search in Empty List ====\n");

    struct node *empty = NULL;
    printf("Search 10 in empty list: %d\n",
           list_search(empty, 10));

    return 0;
}

    
struct node *create_node(int data, struct node *next) {
//TODO
}

void print_list(struct node *head) {
//TODO
}

//                
struct node *insert_at_tail(struct node *head, int data) {
//TODO
}

// return 1 if the value is found in the given list
// return 0 otherwise
int list_search(struct node *head, int value) {
//TODO

}
// Pantea Aria

// linked list
// - create_node
// - print_list
// - insert_at_tail
// - delete_first
// - delete_all
// - search_and_delete

#include <stdio.h>
#include <stdlib.h>

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

struct node *create_node(int data, struct node *next);
void print_list(struct node *head);
struct node *insert_at_tail(struct node *head, int data);

struct node *delete_first(struct node *head);
struct node * delete_all(struct node *head);
struct node *search_and_delete(struct node *head, int value);

int main(void) {
    struct node *head = NULL;

    // Print the empty list
    print_list(head);

    printf("Search and delete from empty list\n");
    // Try deleting 99 from an empty list
    head = search_and_delete(head, 1000);
    print_list(head);

    // Build a list that stores 0..9 by inserting at the tail
    for (int i = 0; i < 10; i++) {
        head = insert_at_tail(head, i);
    }
    print_list(head);
    
    printf("delete first '0'\n");
    // Delete first
    head = delete_first(head);
    print_list(head);
    
    //delete_all(head);
   // print_list(head);
    

    printf("Search and delete 4\n");
    // Delete 4 (middle case)
    head = search_and_delete(head, 4);
    print_list(head);

    printf("Search and delete 1000\n");
    // Delete 99 (not found case)
    head = search_and_delete(head, 1000);
    print_list(head);

    printf("Search and delete 9\n");
    // Delete 9 (tail case)
    head = search_and_delete(head, 9);
    print_list(head);

    printf("Search and delete 0\n");
    // Delete 0 (head case)
    head = search_and_delete(head, 0);
    print_list(head);

    // Free all remaining nodes to prevent memory leaks
    head = delete_all(head);

    print_list(head);

    return 0;
}

// TODO: Allocate memory for a new node using malloc.
// TODO: If malloc fails, return NULL.
// TODO: Set new_node->data and new_node->next, then return new_node.
struct node *create_node(int data, struct node *next) {
    // TODO

}

// TODO: Traverse from head to NULL and print each node’s data.
// TODO: Print something like: "list:" then the values on one line.
void print_list(struct node *head) {
    // TODO
  
}

// TODO: Insert a new node (with given data) at the end of the list.
// Cases to handle:
// - Empty list: new node becomes the head.
// - Non-empty list: traverse to last node, then link it to new node.
// Return the (possibly updated) head.
struct node *insert_at_tail(struct node *head, int data) {
    // TODO

}

// TODO: Delete the first node (if it exists) and free it.
// Return the new head pointer.
struct node *delete_first(struct node *head) {
    // TODO

}

// TODO: Free every node in the list.
// Hint: you must save the next pointer before calling free on current.
// issues here
struct node *delete_all(struct node *head) {
    // TODO

          
}

// TODO: Find the first node whose data == value, remove it from the list,
// and free it.
// Cases to handle:
// - Empty list
// - Value not found
// - Deleting head node
// - Deleting middle/tail node
// Return the updated head.
struct node *search_and_delete(struct node *head, int value) {

}