Skip to content

Commit 8013622

Browse files
authored
Merge pull request kelvins#265 from ribmarciojr/doubly_linked_list
Add Doubly linked list DSA in C++
2 parents 3071f28 + 5bbcbe6 commit 8013622

File tree

2 files changed

+225
-2
lines changed

2 files changed

+225
-2
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2162,8 +2162,8 @@ In order to achieve greater coverage and encourage more people to contribute to
21622162
</a>
21632163
</td>
21642164
<td> <!-- C++ -->
2165-
<a href="./CONTRIBUTING.md">
2166-
<img align="center" height="25" src="./logos/github.svg" />
2165+
<a href="./src/cpp/DoublyLinkedList.cpp">
2166+
<img align="center" height="25" src="./logos/cplusplus.svg" />
21672167
</a>
21682168
</td>
21692169
<td> <!-- Java -->

src/cpp/DoublyLinkedList.cpp

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
#include <iostream>
2+
3+
class Node
4+
{
5+
private:
6+
int value;
7+
8+
public:
9+
Node *next{nullptr};
10+
Node *previous{nullptr};
11+
12+
// Node constructor
13+
Node(int value)
14+
{
15+
this->value = value;
16+
}
17+
18+
int getValue() { return this->value; };
19+
};
20+
21+
class DoublyLinkedList
22+
{
23+
private:
24+
Node *first{nullptr};
25+
26+
// Receives the node reference and make the pointers around stop pointing to
27+
void remove_pointers_to(Node *&node)
28+
{
29+
if (node->next)
30+
{
31+
node->next->previous = node->previous;
32+
}
33+
if (node->previous)
34+
{
35+
node->previous->next = node->next;
36+
}
37+
else
38+
{
39+
this->first = node->next;
40+
}
41+
}
42+
43+
public:
44+
DoublyLinkedList() {}
45+
46+
void push_front(int value)
47+
{
48+
// Initialize a pointier to a new node with received value
49+
Node *node = new Node(value);
50+
// Node points to the first
51+
node->next = this->first;
52+
53+
// If there is a first node, make him point to new node
54+
if (this->first)
55+
{
56+
this->first->previous = node;
57+
}
58+
59+
// Node becomes the first
60+
this->first = node;
61+
}
62+
63+
// Checks if there is a first node
64+
bool isEmpty()
65+
{
66+
if (!this->first)
67+
{
68+
return true;
69+
}
70+
return false;
71+
}
72+
73+
void push_back(int value)
74+
{
75+
Node *node = new Node(value);
76+
Node *selectedNode = this->first;
77+
78+
if (this->isEmpty())
79+
{
80+
this->first = node;
81+
return;
82+
}
83+
84+
Node *aux{nullptr};
85+
while (selectedNode)
86+
{
87+
aux = selectedNode;
88+
selectedNode = selectedNode->next;
89+
}
90+
91+
node->previous = aux;
92+
aux->next = node;
93+
};
94+
95+
void remove(int value)
96+
{
97+
// Throw exception to empty List
98+
if (this->isEmpty())
99+
{
100+
throw std::logic_error("List is empty, nothing to be removed!");
101+
}
102+
103+
// Initialize a pointier to first element
104+
Node *node = this->first;
105+
106+
// Go through the list until find the value or the end
107+
while ((node) && (node->getValue() != value))
108+
{
109+
node = node->next;
110+
}
111+
// Throw exception if didn't find the value
112+
if (!node)
113+
{
114+
throw std::logic_error("Value must be in the list!");
115+
}
116+
117+
// Remove all pointier to the value if exists
118+
this->remove_pointers_to(node);
119+
120+
// Delete node
121+
delete (node);
122+
}
123+
124+
// Removes the k-th element, where k it's an ordinal number
125+
void remove_ordinary(int position)
126+
{
127+
if (this->isEmpty())
128+
{
129+
throw std::logic_error("List is empty, nothing to be removed!");
130+
}
131+
132+
if (position < 1)
133+
{
134+
throw std::logic_error("Invalid position!");
135+
}
136+
137+
Node *selectedNode = this->first;
138+
int aux = 1;
139+
140+
while ((selectedNode) && (aux != position))
141+
{
142+
selectedNode = selectedNode->next;
143+
aux++;
144+
}
145+
146+
if (!selectedNode)
147+
{
148+
throw std::logic_error("Index out of bound!");
149+
}
150+
151+
this->remove_pointers_to(selectedNode);
152+
153+
delete (selectedNode);
154+
}
155+
156+
std::pair<bool, Node *> find(int value)
157+
{
158+
// Throw exception to empty List
159+
if (this->isEmpty())
160+
{
161+
throw std::logic_error("List is empty, nothing to be removed!");
162+
}
163+
164+
// Initialize a pointier to first element
165+
Node *node = this->first;
166+
167+
// Go through the list until find the value or the end
168+
while ((node) && (node->getValue() != value))
169+
{
170+
node = node->next;
171+
}
172+
173+
if (!node)
174+
{
175+
return {false, nullptr};
176+
}
177+
return {true, node};
178+
}
179+
180+
void print()
181+
{
182+
Node *selectedNode = this->first;
183+
std::cout << "[ ";
184+
while (selectedNode)
185+
{
186+
std::cout << selectedNode->getValue() << " ";
187+
selectedNode = selectedNode->next;
188+
}
189+
std::cout << "]" << std::endl;
190+
}
191+
};
192+
193+
int main()
194+
{
195+
DoublyLinkedList *doubly_linked_list = new DoublyLinkedList();
196+
197+
std::cout << "Push_front(20, 30, 40):" << std::endl;
198+
doubly_linked_list->push_front(20);
199+
doubly_linked_list->push_front(30);
200+
doubly_linked_list->push_front(40);
201+
202+
doubly_linked_list->print();
203+
204+
std::cout << "Remove second!" << std::endl;
205+
206+
doubly_linked_list->remove_ordinary(2);
207+
208+
doubly_linked_list->print();
209+
210+
std::cout << "Remove(20, 40)!" << std::endl;
211+
doubly_linked_list->remove(20);
212+
doubly_linked_list->remove(40);
213+
214+
std::cout << "List is empty: ";
215+
doubly_linked_list->print();
216+
217+
std::cout << "Push_back(512, 123, 412)!" << std::endl;
218+
doubly_linked_list->push_back(512);
219+
doubly_linked_list->push_back(123);
220+
doubly_linked_list->push_back(412);
221+
222+
doubly_linked_list->print();
223+
}

0 commit comments

Comments
 (0)