ScholarQuill logoScholarQuillUniversity Notes
My Semester
Explore Notes
Past Papers12 New
Video CoursesNew
Search
Settings
Study Tools
GPA/CGPA Calculator
Schedule & To-Do
Student Portal
Contact
Contact
ScholarQuill logo
My Semester
Explore Notes
Past Papers12 New
Video CoursesNew
Search
Settings
GPA/CGPA Calculator
Schedule & To-Do
Student Portal
Contact
ScholarQuill logoScholarQuillUniversity Notes
Study PortalCC-112Self Referential Struc…
Ctrl + K
Login
Explore
Search
Semester
Papers
CGPA
    CC-112

    Programming Fundamentals

    Progress0 / 39 done
    Topics39
    1Introduction to Problem Solving, Algorithms, Programming, and C Language2Problem Solving, a brief review of Von-Neumann Architecture3The C Programming Language, Pseudo-code, Concept of Variable4Data types in Pseudo-code, The C Standard Library and Open Source5Input/Output, Arithmetic expressions, Assignment statement, Operator precedence6Concept of Integer division, Flowchart and its notations7Typical C Program Development Environment, Role of Compiler and Linker8Test Driving C Application
    9A Simple C Program: Printing Text, Adding Two Integer10Memory Concepts, Arithmetic in C, Operators
    11Equality and Relational Operators
    12The if, if...else, while Nested Control Statements
    13for, switch, do...while, break, continue, Logical Operators
    14Modularizing Program in C, Math Library Functions15Function Definitions and Prototypes, Function-Call Stack and Stack Frames16Stack rolling and unrolling, Headers, Passing Arguments by Value and by Reference17Random Number Generation, Scope Rules, Recursion, Recursion vs Iteration
    18Defining Arrays, Character Arrays, Static and Automatic Local Arrays19Passing Arrays to Function, Sorting and Searching Arrays20Multidimensional and Variable Length Arrays
    21Pointer Definitions and Initialization, Pointer Operators22Passing Arguments to Function by Reference, Using the const and sizeof Operator23Pointer Expressions and Arithmetic, Pointers and Arrays, Array of Pointers24Function Pointers
    25Strings and Characters, Character Handling Library26String Functions, Library Functions
    27Streams, Formatted Output with printf, Formatted Input with scanf
    28Defining Structures, Accessing Structure Member, Structures and Functions29typedef, Unions
    30Bitwise Operators, Bit Fields, Enumeration Constants
    31Files and Streams, Creating, Reading and Writing data to a Sequential and a Random-Access File
    32#include, #define, Conditional Compilation, #error and #pragma33# and ## Operators, Predefined Symbolic Constants, Assertions
    34Variable Length Argument List, Using Command Line Arguments35Compiling Multiple-Source-File Programs, Program Termination with exit and atexit36Suffixes for Integer and Floating-Point Literals, Signal Handling
    37calloc and realloc, goto
    38Self-Referential Structures, Linked Lists39Efficiency of Algorithms, Selection and Insertion Sort
    7 min read
    Topic 38 of 39
    Topic Study Note Illustration
    38

    Advance Topics: Self-Referential Structures, Linked Lists

    In advanced C programming, two important concepts often discussed are self-referential structures and linked lists . These are fundamental topics in data structure design, offering powerful ways...

    Advanced Topics: Self-Referential Structures, Linked Lists

    In advanced C programming, two important concepts often discussed are self-referential structures and linked lists. These are fundamental topics in data structure design, offering powerful ways to organize and manage data in a dynamic and flexible manner.


    1. Self-Referential Structures

    A self-referential structure in C is a structure that contains a pointer to an instance of the same structure type. This allows for the creation of recursive data structures, like linked lists, trees, and graphs. The key feature of a self-referential structure is that it "refers to itself" through pointers.

    Definition of a Self-Referential Structure

    In C, a structure is defined using the struct keyword, and a self-referential structure typically has a pointer to itself (or another instance of the same structure).

    Example: Definition of a Self-Referential Structure
    #include <stdio.h>
    #include <stdlib.h>
    
    // Definition of a self-referential structure
    struct Node {
        int data;
        struct Node* next;  // Pointer to the next Node, making it self-referential
    };
    
    int main() {
        // Create a self-referential structure (linked list node)
        struct Node* head = (struct Node*)malloc(sizeof(struct Node));
        head->data = 10;
        head->next = NULL;
    
        printf("Data: %d\n", head->data);  // Output: Data: 10
    
        free(head);  // Free the allocated memory
        return 0;
    }
    

    Explanation:

    • The Node structure has an int field (data) and a pointer (next) to another Node. This makes it self-referential because the next pointer points to another instance of the same structure.
    • This design enables us to create dynamic data structures where each element (node) can point to the next, such as in linked lists.

    2. Linked Lists

    A linked list is a linear data structure where each element (called a node) contains two parts:

    1. Data: The actual data stored in the node.
    2. Next: A pointer to the next node in the sequence (or NULL if it’s the last node).

    Linked lists are dynamic in nature, meaning that their size can grow or shrink at runtime, unlike arrays that have a fixed size.

    Types of Linked Lists:

    • Singly Linked List: Each node points only to the next node.
    • Doubly Linked List: Each node contains two pointers: one pointing to the next node and one pointing to the previous node.
    • Circular Linked List: The last node’s next pointer points back to the first node, forming a loop.

    Singly Linked List

    A singly linked list is a simple form of linked list where each node contains data and a pointer to the next node in the list.

    Structure of a Singly Linked List Node:
    struct Node {
        int data;        // Data of the node
        struct Node* next;  // Pointer to the next node
    };
    
    Example: Implementing a Simple Singly Linked List
    #include <stdio.h>
    #include <stdlib.h>
    
    // Definition of the Node structure (self-referential structure)
    struct Node {
        int data;
        struct Node* next;
    };
    
    // Function to print the linked list
    void printList(struct Node* head) {
        struct Node* temp = head;
        while (temp != NULL) {
            printf("%d -> ", temp->data);
            temp = temp->next;
        }
        printf("NULL\n");
    }
    
    int main() {
        // Allocate memory for 3 nodes
        struct Node* head = (struct Node*)malloc(sizeof(struct Node));
        struct Node* second = (struct Node*)malloc(sizeof(struct Node));
        struct Node* third = (struct Node*)malloc(sizeof(struct Node));
    
        // Initialize data
        head->data = 10;
        head->next = second;
    
        second->data = 20;
        second->next = third;
    
        third->data = 30;
        third->next = NULL;  // Last node's next is NULL
    
        // Print the linked list
        printList(head);
    
        // Free the memory
        free(head);
        free(second);
        free(third);
    
        return 0;
    }
    

    Explanation:

    • Three nodes are created dynamically using malloc(), with each node containing an integer (data) and a pointer (next).
    • The first node (head) points to the second node, and the second node points to the third. The last node points to NULL, indicating the end of the list.
    • The printList() function traverses the list, printing each node’s data until it reaches NULL.
    Output:
    10 -> 20 -> 30 -> NULL
    

    Operations on Singly Linked Lists:

    • Insertion: Adding a new node at the beginning, middle, or end of the list.
    • Deletion: Removing a node from the beginning, middle, or end.
    • Traversal: Going through each node of the list to access data or perform operations.
    • Searching: Finding a specific value within the list.
    • Reversal: Reversing the order of the nodes in the list.
    Example: Inserting a New Node at the Beginning
    void insertAtBeginning(struct Node** head, int new_data) {
        struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
        new_node->data = new_data;
        new_node->next = *head;  // Make next of new node point to the old head
        *head = new_node;        // Move the head pointer to the new node
    }
    
    int main() {
        struct Node* head = NULL;
        insertAtBeginning(&head, 10);
        insertAtBeginning(&head, 20);
        insertAtBeginning(&head, 30);
    
        printList(head);  // Output: 30 -> 20 -> 10 -> NULL
    
        // Free the memory
        free(head);
    
        return 0;
    }
    

    3. Doubly Linked List

    In a doubly linked list, each node has two pointers:

    • next: A pointer to the next node.
    • prev: A pointer to the previous node.

    This structure allows for traversal in both directions: forward and backward.

    Structure of a Doubly Linked List Node:
    struct Node {
        int data;
        struct Node* next;
        struct Node* prev;
    };
    
    Advantages of Doubly Linked Lists:
    • Bidirectional Traversal: Can be traversed both forward and backward.
    • Efficient Insertion/Deletion: Insertion or deletion of a node can be done efficiently from both ends of the list or from the middle, as you can directly access the previous node.

    4. Circular Linked List

    In a circular linked list, the last node points back to the first node, forming a loop. It can be either singly or doubly circular.

    • Singly Circular Linked List: The next pointer of the last node points to the first node.
    • Doubly Circular Linked List: Both next and prev pointers form a circle.
    Advantages of Circular Linked Lists:
    • Continuous Traversal: You can keep traversing the list infinitely without needing to check for a NULL at the end.
    • Efficient Circular Queue Implementation: Useful for circular buffers or queues.

    Summary of Key Points

    Concept Description Advantages/Use Cases
    Self-Referential Structure A structure that contains a pointer to itself, enabling recursive data structures (like linked lists). Used to create dynamic data structures like linked lists, trees, etc.
    Singly Linked List A linked list where each node points to the next node. Dynamic memory allocation, simple to implement.
    Doubly Linked List A linked list where each node points to both the next and previous nodes. Bidirectional traversal, efficient insertions and deletions from both ends.
    Circular Linked List A linked list where the last node points back to the first node. Continuous traversal, used for circular buffers or queues.

    Conclusion

    Self-referential structures, like linked lists, are essential in dynamic memory management and allow you to create complex data structures in C. Linked lists, whether singly, doubly, or circular, provide flexibility in how data can be organized, accessed, and manipulated. These structures are foundational in understanding more advanced algorithms and data structures, such as trees, graphs, and dynamic memory management techniques.

    ← Previous topic 37
    Dynamic Memory Allocation: calloc and realloc, goto
    Next topic 39 →
    Efficiency of Algorithms, Selection and Insertion Sort

    Past Papers

    Open this section to view and download past papers

    Click on Show Past Papers to load available exam papers.

    Reading Progress
    0%
    7mremaining
    1.3kwords
    Intermediatelevel
    On This Page

    No headings found

    Study Toolkit

    Subject Portal

    Programming Fundamentals