|
1 | | -# Doubly Linked List |
| 1 | +# Doubly Linked List Implementation |
2 | 2 |
|
3 | | -## Table of Contents |
| 3 | +This Python implementation provides a basic Doubly Linked List structure with various functionalities. |
4 | 4 |
|
5 | | -- [Description](#description) |
6 | | -- [Functions](#functions) |
7 | | -- [Time and Space Complexity](#time-and-space-complexity) |
8 | | -- [Contributing](#contributing) |
| 5 | +## Doubly Linked List |
9 | 6 |
|
10 | | -## Description |
| 7 | +A Doubly Linked List is a linear data structure in which each node contains a data element and two pointers, the first pointing to the previous node, and the second pointing to the next node in the sequence. |
11 | 8 |
|
12 | | -A Doubly Linked List is a data structure that stores a collection of elements, each of which points to the previous and next elements in the sequence. This README provides an overview of the functions, time and space complexity analysis, and instructions for contributing to the project. |
| 9 | +## Class Structure |
13 | 10 |
|
14 | | -## Functions |
| 11 | +### Node |
| 12 | +- **Attributes:** |
| 13 | + - `data`: The value of the node. |
| 14 | + - `next`: Reference to the next node. |
| 15 | + - `prev`: Reference to the previous node. |
15 | 16 |
|
16 | | -### Append(value) |
| 17 | +### doublyLinkedList |
| 18 | +- **Attributes:** |
| 19 | + - `head`: Reference to the head (first node) of the doubly linked list. |
| 20 | + - `tail`: Reference to the tail (last node) of the doubly linked list. |
17 | 21 |
|
18 | | -Add a value to the end of the linked list. |
| 22 | +### Functions and Time Complexity (Worst and Best Cases) and Space Complexity |
19 | 23 |
|
20 | | -### Insert at Beginning(value) |
| 24 | +| Function | Description | Worst Case Time Complexity | Best Case Time Complexity | Space Complexity (Auxiliary) | |
| 25 | +|---------------------------------------|-----------------------------------------------|----------------------------|---------------------------|-------------------------------| |
| 26 | +| `add_node(o)` | Adds a node with the given value to the end of the doubly linked list. | O(1) | O(1) | O(1) | |
| 27 | +| `delete_at_beginning()` | Deletes the first node in the doubly linked list. | O(1) | O(1) | O(1) | |
| 28 | +| `delete_at_end()` | Deletes the last node in the doubly linked list. | O(1) | O(1) | O(1) | |
| 29 | +| `remove(index)` | Removes the node at the specified index. | O(n) | O(1) | O(1) | |
| 30 | +| `Display()` | Displays the values of the doubly linked list. | O(n) | O(n) | O(1) | |
| 31 | +| `insert(val, new_val)` | Inserts a new node with the given value after the node with the specified value. | O(n) | O(1) | O(1) | |
| 32 | +| `insertatbegin(k)` | Inserts a new node with the given value at the beginning of the doubly linked list. | O(1) | O(1) | O(1) | |
| 33 | +| `insertatend(k)` | Inserts a new node with the given value at the end of the doubly linked list. | O(1) | O(1) | O(1) | |
| 34 | +| `insertatind(k, pos)` | Inserts a new node with the given value at the specified position in the doubly linked list. | O(n) | O(1) | O(1) | |
| 35 | +| `insert_after(value, new_value)` | Inserts a new node with the given value after the node with the specified value. | O(n) | O(1) | O(1) | |
| 36 | +| `insert_before(value, new_value)` | Inserts a new node with the given value before the node with the specified value. | O(n) | O(1) | O(1) | |
21 | 37 |
|
22 | | -Insert a value at the beginning of the linked list. |
| 38 | +**Note:** |
| 39 | +- Time complexity is given in terms of the number of nodes (n). |
| 40 | +- Space complexity is specified for auxiliary space, not including the space required by the input and output. |
23 | 41 |
|
24 | | -### Insert at Index(value, index) |
25 | | - |
26 | | -Insert a value at a specific index in the linked list. |
27 | | - |
28 | | -### Insert at End(value) |
29 | | - |
30 | | -Insert a value at the end of the linked list. |
31 | | - |
32 | | -### Update Node(value, index) |
33 | | - |
34 | | -Update the value of a node at a specific index. |
35 | | - |
36 | | -### Remove First Node |
37 | | - |
38 | | -Remove the first node in the linked list. |
39 | | - |
40 | | -### Remove Last Node |
41 | | - |
42 | | -Remove the last node in the linked list. |
43 | | - |
44 | | -### Remove at Index(index) |
45 | | - |
46 | | -Remove a node at a specific index. |
47 | | - |
48 | | -### Remove Node(value) |
49 | | - |
50 | | -Remove a node with a specific value. |
51 | | - |
52 | | -### Size of Linked List |
53 | | - |
54 | | -Get the size (number of nodes) of the linked list. |
55 | | - |
56 | | -### Display |
57 | | - |
58 | | -Display the elements of the linked list. |
59 | | - |
60 | | -### Iterator Functions |
61 | | - |
62 | | -- Initialize an iterator at the head of the list. |
63 | | -- Initialize a reverse iterator at the tail of the list. |
64 | | -- Get the value of the current node in the iteration. |
65 | | -- Move the iterator to the next node in the forward iteration. |
66 | | -- Remove the current node being iterated. |
67 | | - |
68 | | -# Time and Space Complexity |
69 | | - |
70 | | -## Class Initialization (__init__(self)) |
71 | | -- **Time Complexity**: O(1) |
72 | | -- **Space Complexity**: O(1) |
73 | | - |
74 | | -The initialization method creates two sentinel nodes (head and tail) and sets them as the first and last elements in the list. This is a constant-time operation. Only two sentinel nodes are created regardless of the size of the list, so the space complexity is constant. |
75 | | - |
76 | | -## Add Node (add_node(self, o)) |
77 | | -- **Time Complexity**: O(1) |
78 | | -- **Space Complexity**: O(1) |
79 | | - |
80 | | -Adding a node to the end of the list involves updating the prev and next pointers of the tail node and the new node. This is a constant-time operation. The space complexity is constant because only one additional node is created. |
81 | | - |
82 | | -## Delete Node at Beginning (delete_at_beginning(self)) |
83 | | -- **Time Complexity**: O(1) |
84 | | -- **Space Complexity**: O(1) |
85 | | - |
86 | | -Removing the first node in the list involves updating the next pointer of the head node to point to the new first node. This is a constant-time operation. No additional data structures are created, so the space complexity is constant. |
87 | | - |
88 | | -## Delete Node at End (delete_at_end(self)) |
89 | | -- **Time Complexity**: O(1) |
90 | | -- **Space Complexity**: O(1) |
91 | | - |
92 | | -Removing the last node in the list involves updating the next pointer of the second-to-last node to point to the tail node. This is a constant-time operation. No additional data structures are created, so the space complexity is constant. |
93 | | - |
94 | | -## Remove Node by Index (remove(self, index)) |
95 | | -- **Time Complexity**: O(n) |
96 | | -- **Space Complexity**: O(1) |
97 | | - |
98 | | -The time complexity of removing a node by its index depends on the position of the node to be removed. In the worst case, it may need to traverse the entire list, making it a linear time operation. No additional data structures are created, so the space complexity is constant. |
99 | | - |
100 | | -## Insert Node by Value (insert(self, val, new_val)) |
101 | | -- **Time Complexity**: O(n) |
102 | | -- **Space Complexity**: O(1) |
103 | | - |
104 | | -Inserting a node after a specific value requires traversing the list to find the value to insert after. In the worst case, it may need to traverse the entire list, making it a linear time operation. No additional data structures are created, so the space complexity is constant. |
105 | | - |
106 | | -## Insert Node at Beginning (insertatbegin(self, k)) |
107 | | -- **Time Complexity**: O(1) |
108 | | -- **Space Complexity**: O(1) |
109 | | - |
110 | | -Inserting a node at the beginning involves updating the next and prev pointers of the new node, the current first node, and the head node. This is a constant-time operation. The space complexity is constant because only one additional node is created. |
111 | | - |
112 | | -## Insert Node at End (insertatend(self, k)) |
113 | | -- **Time Complexity**: O(1) |
114 | | -- **Space Complexity**: O(1) |
115 | | - |
116 | | -Inserting a node at the end involves updating the next and prev pointers of the new node, the current last node, and the tail node. This is a constant-time operation. The space complexity is constant because only one additional node is created. |
117 | | - |
118 | | -## Insert Node at a Specific Position (insertatind(self, k, pos)) |
119 | | -- **Time Complexity**: O(n) |
120 | | -- **Space Complexity**: O(1) |
121 | | - |
122 | | -Inserting a node at a specific position requires traversing the list to find the insertion point. In the worst case, it may need to traverse the entire list, making it a linear time operation. No additional data structures are created, so the space complexity is constant. |
123 | | - |
124 | | -## Insert Node after a Value (insert_after(self, value, new_value)) |
125 | | -- **Time Complexity**: O(n) |
126 | | -- **Space Complexity**: O(1) |
127 | | - |
128 | | -Inserting a node after a specific value requires traversing the list to find the value to insert after. In the worst case, it may need to traverse the entire list, making it a linear time operation. No additional data structures are created, so the space complexity is constant. |
129 | | - |
130 | | -## Insert Node before a Value (insert_before(self, value, new_value)) |
131 | | -- **Time Complexity**: O(n) |
132 | | -- **Space Complexity**: O(1) |
133 | | - |
134 | | -Inserting a node before a specific value requires traversing the list to find the value to insert before. In the worst case, it may need to traverse the entire list, making it a linear time operation. No additional data structures are created, so the space complexity is constant. |
135 | | - |
136 | | -## Display List (Display(self)) |
137 | | -- **Time Complexity**: O(n) |
138 | | -- **Space Complexity**: O(1) |
139 | | - |
140 | | -Displaying the entire list requires traversing and printing all elements in the list, making it a linear time operation. No additional data structures are created for displaying the list, so the space complexity is constant. |
141 | | - |
142 | | -## Traverse List (traverse(self)) |
143 | | -- **Time Complexity**: O(n) |
144 | | -- **Space Complexity**: O(1) |
145 | | - |
146 | | -Traversing the list to print its elements is a linear time operation, as it involves visiting all nodes. No additional data structures are created for traversal, so the space complexity is constant. |
147 | | - |
148 | | -## Iterator Methods (begining(self), end(self), rbegining(self), rend(self)) |
149 | | -- **Time Complexity**: O(1) |
150 | | -- **Space Complexity**: O(1) |
151 | | - |
152 | | -These methods return iterators pointing to the head, tail, or sentinel nodes. They are constant-time operations. These methods return existing iterator objects, so the space complexity is constant. |
153 | | - |
154 | | -## Iterator Methods (__iter__(self), __reversed__(self), getObject(self), __next__(self), remove(self)) |
155 | | -- **Time Complexity**: O(1) |
156 | | -- **Space Complexity**: O(1) |
157 | | - |
158 | | -These methods are used to create and manage iterators, so they are constant-time operations. These methods involve working with existing iterator objects, so the space complexity is constant. |
159 | | - |
160 | | - |
161 | | -## Contributing |
162 | | - |
163 | | -Contributions are welcome! If you find any issues or have improvements to suggest, please open an issue or a pull request. |
| 42 | +Feel free to use this Doubly Linked List implementation for your projects and modify it as needed! |
0 commit comments