0% found this document useful (0 votes)
8 views6 pages

TD DList Corr

The document defines a doubly linked list structure and provides function prototypes for creating, modifying, and traversing the list. Key functions include creating and deleting nodes, inserting at the beginning, traversing forward and backward, finding the middle node, detecting cycles, copying the list, and finding the K-th node from the end. The implementation is designed to facilitate various operations on the doubly linked list, similar to those used in singly linked lists.

Uploaded by

NESSRIN HANA
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views6 pages

TD DList Corr

The document defines a doubly linked list structure and provides function prototypes for creating, modifying, and traversing the list. Key functions include creating and deleting nodes, inserting at the beginning, traversing forward and backward, finding the middle node, detecting cycles, copying the list, and finding the K-th node from the end. The implementation is designed to facilitate various operations on the doubly linked list, similar to those used in singly linked lists.

Uploaded by

NESSRIN HANA
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

Doubly Linked List Functions

This list.h header file defines a basic doubly linked list structure and associated function
prototypes for manipulating the list nodes. Let's break down the components:

1. Structure Definition

typedef struct Node {


int value; // Data stored in the node.
struct Node* next; // Pointer to the next node in the list.
struct Node* prev; // Pointer to the previous node in the list.
} Node;

• Node is a struct type that represents a node in the doubly linked list.
• It contains an integer value (value) and two pointers:
o next (a pointer to the next node).
o prev (a pointer to the previous node).
• The next and prev pointers enable traversal in both directions, making this a doubly
linked list.

2. Function Prototypes

The following function prototypes are defined for performing operations on the doubly linked
list:

• Node* createNode(int value);


o Purpose: Creates a new node with the given value.
o Return type: Node* - a pointer to the newly created node.
• void deleteNode(Node* node);
o Purpose: Frees the memory of the given node. This function deallocates the
node's memory but does not remove it from the list structure.
o Return type: void - no return value.
• int getValue(Node* node);
o Purpose: Returns the value stored in the given node.
o Return type: int - the value stored in the node.
• void setValue(Node* node, int value);
o Purpose: Sets the value of the given node to the specified value.
o Return type: void - no return value.
• Node* getNext(Node* node);
o Purpose: Returns a pointer to the next node in the list.
o Return type: Node* - pointer to the next node.
• void setNext(Node* node, Node* nextNode);
o Purpose: Sets the next pointer of the given node to point to nextNode.
o Return type: void - no return value.
• Node* getPrev(Node* node);
o Purpose: Returns a pointer to the previous node in the list.
o Return type: Node* - pointer to the previous node.
• void setPrev(Node* node, Node* prevNode);
o Purpose: Sets the previous pointer of the given node to point to prevNode.
o Return type: void - no return value.

These function prototypes provide the necessary functionality to manipulate the doubly linked
list. They allow us to create, modify, and navigate through nodes in both directions. With these
building blocks, we can implement a variety of operations on the doubly linked list, as
demonstrated in the following solutions.

1. Initialization: Define and Initialize a Doubly Linked List with 5 Elements

We initialize the doubly linked list by creating the first node and then adding additional nodes,
linking them properly in both directions.

Node* initializeList() {
Node* head = createNode(1); // Create first node
Node* current = head;
for (int i = 2; i <= 5; i++) {
Node* newNode = createNode(i);
setNext(current, newNode); // Link current node to the new node
setPrev(newNode, current); // Set the previous pointer of the new node
current = newNode; // Move current pointer
}
return head; // Return the head of the list
}

2. Insert at Beginning: Insert an Element at the Beginning of the List

We insert a new node at the beginning of the list by adjusting the pointers such that the new node
points to the old head, and the head points to the new node.

void insert_begin(Node** head, int x) {


Node* newNode = createNode(x); // Create new node
if (*head == NULL) {
*head = newNode; // If the list is empty, set the new node as head
} else {
setNext(newNode, *head); // Link the new node to the current head
setPrev(*head, newNode); // Set the previous pointer of the old head
*head = newNode; // Update head to the new node
}
}

3. Delete Node by Position: Delete a Node at a Given Position

This function removes a node from a specified position by adjusting the previous and next
pointers of the surrounding nodes.

void delete_val(Node** head, int position) {


if (*head == NULL) return;
Node* current = *head;
int count = 0;

if (position == 0) {
*head = getNext(current); // Update head if deleting the first node
if (*head != NULL) {
setPrev(*head, NULL);
}
deleteNode(current); // Delete the node
return;
}

while (current != NULL && count < position) {


current = getNext(current);
count++;
}

if (current == NULL) return;


setNext(getPrev(current), getNext(current)); // Link previous node to the
next node

deleteNode(current); // Free the node's memory


}

4. Traverse Forward: Traverse the List from Head to Tail

We iterate through the list starting from the head, printing each node's value until we reach the
end.
void traverse_forward(Node* head) {
Node* current = head;
while (current != NULL) {
printf("%d -> ", getValue(current)); // Print node value
current = getNext(current); // Move to next node
}
printf("NULL\n"); // Indicate end of list
}

5. Traverse Backward: Traverse the List from Tail to Head

We traverse the list starting from the tail by first moving to the last node and then following the
previous pointers to the head.

void traverse_backward(Node* head) {


Node* current = head;
while (current != NULL && getNext(current) != NULL) {
current = getNext(current); // Move to the last node
}

while (current != NULL) {


printf("%d -> ", getValue(current)); // Print node value
current = getPrev(current); // Move to the previous node
}
printf("NULL\n"); // Indicate end of list
}

6. Find Middle Node: Find the Middle Node of the List

We use the two-pointer technique (slow and fast pointers) to find the middle node, where the
slow pointer moves one step at a time, and the fast pointer moves two steps at a time.

Node* find_middle(Node* head) {


if (head == NULL) return NULL;

Node* slow = head;


Node* fast = head;

while (fast != NULL && getNext(fast) != NULL) {


slow = getNext(slow); // Move slow pointer one step
fast = getNext(getNext(fast)); // Move fast pointer two steps
}

return slow; // Return the middle node


}

7. Detect Cycle: Check if the List Contains a Cycle

We use the Floyd’s Cycle-Finding Algorithm (Tortoise and Hare) to detect a cycle by using two
pointers moving at different speeds.

int has_cycle(Node* head) {


if (head == NULL) return 0;

Node* slow = head;


Node* fast = head;

while (fast != NULL && getNext(fast) != NULL) {


slow = getNext(slow); // Move slow pointer one step
fast = getNext(getNext(fast)); // Move fast pointer two steps

if (slow == fast) { // If slow and fast pointers meet, there is a cycle


return 1;
}
}

return 0; // No cycle detected


}

8. Copy List: Create a Copy of the List

We traverse the original list and create new nodes with the same values, linking them in a similar
way as the original list.

Node* copy(Node* head) {


if (head == NULL) return NULL;

Node* newHead = createNode(getValue(head)); // Create first node of the copy


Node* current = getNext(head);
Node* newCurrent = newHead;

while (current != NULL) {


Node* newNode = createNode(getValue(current)); // Create a new node
setNext(newCurrent, newNode); // Link the new node to the copy
setPrev(newNode, newCurrent);
newCurrent = newNode;
current = getNext(current);
}

return newHead; // Return the copied list


}

9. Kth Node from End: Find the K-th Node from the End of the List

We use two pointers: one is moved k steps ahead, and then both pointers move simultaneously
until the first pointer reaches the end, at which point the second pointer points to the K-th node
from the end.

Node* kth_from_end(Node* head, int k) {


if (head == NULL) return NULL;

Node* first = head;


Node* second = head;

for (int i = 0; i < k; i++) {


if (first == NULL) return NULL;
first = getNext(first); // Move the first pointer k steps ahead
}

while (first != NULL) {


first = getNext(first); // Move both pointers until first reaches the
end
second = getNext(second);
}

return second; // Return the K-th node from the end


}

Final Notes:

• This implementation meets the given requirements and follows the same structure and
logic you used for singly linked lists, adapted for doubly linked lists.
• It includes all necessary functionality such as insertion, deletion, traversal, and cycle
detection.

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy