Skip to content

Commit 004fdc9

Browse files
committed
[Issue - 608] - Add tests for Python Doubly Linked List
1 parent 23b43da commit 004fdc9

File tree

2 files changed

+188
-0
lines changed

2 files changed

+188
-0
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
class Node:
2+
def __init__(self, data=None, prev=None, next=None):
3+
self.data = data
4+
self.prev = prev
5+
self.next = next
6+
7+
8+
class DoublyLinkedList:
9+
def __init__(self):
10+
self.head = None
11+
12+
def insert_at_beginning(self, data):
13+
if self.head is None:
14+
node = Node(data)
15+
self.head = node
16+
else:
17+
new_head = Node(data, next=self.head)
18+
self.head.prev = new_head
19+
self.head = new_head
20+
21+
def length(self):
22+
itr = self.head
23+
count = 0
24+
while itr:
25+
count += 1
26+
itr = itr.next
27+
return count
28+
29+
def insert_at_end(self, data):
30+
if self.head is None:
31+
self.insert_at_beginning(data)
32+
else:
33+
itr = self.head
34+
while itr.next:
35+
itr = itr.next
36+
itr.next = Node(data, prev=itr)
37+
38+
def insert_at(self, data, at):
39+
if at == 0:
40+
self.insert_at_beginning(data)
41+
elif at == self.length() - 1 and self.length() > 2:
42+
self.insert_at_end(data)
43+
else:
44+
itr = self.head
45+
count = 0
46+
while itr:
47+
if count != at - 1:
48+
count += 1
49+
itr = itr.next
50+
else:
51+
break
52+
itr.next = Node(data, itr, itr.next)
53+
54+
def remove_val(self, val):
55+
while self.head and self.head.data is val:
56+
self.head = self.head.next
57+
if self.head is None:
58+
return
59+
60+
current = self.head
61+
while current:
62+
if current.data == val:
63+
if current == self.head:
64+
self.head = current.next
65+
self.head.prev = None
66+
if current.next is None:
67+
current.prev.next = None
68+
return
69+
else:
70+
current.next.prev = current.prev
71+
current.prev.next = current.next
72+
current = current.next
73+
74+
def __str__(self):
75+
current = self.head
76+
as_string = ''
77+
while current:
78+
as_string += str(current.data)
79+
if current.next:
80+
as_string += ' --> '
81+
current = current.next
82+
return as_string
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import unittest
2+
from Python.DataStructures.DoublyLinkedList.doubly_linked_list import DoublyLinkedList
3+
4+
class TestDoublyLinkedList(unittest.TestCase):
5+
6+
def test_list_is_empty_on_initialization(self):
7+
a_doubly_linked_list = DoublyLinkedList()
8+
self.assertEqual(a_doubly_linked_list.length(), 0)
9+
10+
def test_adding_to_front_should_append_node_to_front(self):
11+
a_doubly_linked_list = DoublyLinkedList()
12+
a_doubly_linked_list.insert_at_beginning(5)
13+
self.assertEqual(a_doubly_linked_list.length(), 1)
14+
a_doubly_linked_list.insert_at_beginning(4)
15+
self.assertEqual(a_doubly_linked_list.__str__(), "4 --> 5")
16+
17+
def test_adding_to_end_should_append_node_to_end(self):
18+
a_doubly_linked_list = DoublyLinkedList()
19+
a_doubly_linked_list.insert_at_beginning(5)
20+
self.assertEqual(a_doubly_linked_list.length(), 1)
21+
a_doubly_linked_list.insert_at_end(4)
22+
self.assertEqual(a_doubly_linked_list.__str__(), "5 --> 4")
23+
self.assertEqual(a_doubly_linked_list.length(), 2)
24+
25+
def test_insert_at_should_append_node_to_correct_position_for_a_short_list(self):
26+
a_doubly_linked_list = DoublyLinkedList()
27+
a_doubly_linked_list.insert_at_beginning(5)
28+
a_doubly_linked_list.insert_at_beginning(3)
29+
30+
a_doubly_linked_list.insert_at(4, 1)
31+
self.assertEqual(a_doubly_linked_list.__str__(), "3 --> 4 --> 5")
32+
self.assertEqual(a_doubly_linked_list.length(), 3)
33+
34+
def test_insert_at_should_append_node_to_correct_position(self):
35+
a_doubly_linked_list = DoublyLinkedList()
36+
a_doubly_linked_list.insert_at_beginning(5)
37+
a_doubly_linked_list.insert_at_beginning(4)
38+
a_doubly_linked_list.insert_at_beginning(2)
39+
a_doubly_linked_list.insert_at_beginning(1)
40+
41+
a_doubly_linked_list.insert_at(3, 2)
42+
self.assertEqual(a_doubly_linked_list.__str__(), "1 --> 2 --> 3 --> 4 --> 5")
43+
self.assertEqual(a_doubly_linked_list.length(), 5)
44+
45+
def test_insert_at_should_insert_at_start(self):
46+
a_doubly_linked_list = DoublyLinkedList()
47+
a_doubly_linked_list.insert_at_beginning(5)
48+
a_doubly_linked_list.insert_at_beginning(4)
49+
50+
a_doubly_linked_list.insert_at(3, 0)
51+
self.assertEqual(a_doubly_linked_list.__str__(), "3 --> 4 --> 5")
52+
self.assertEqual(a_doubly_linked_list.length(), 3)
53+
54+
def test_insert_at_should_insert_at_end_for_short_list(self):
55+
a_doubly_linked_list = DoublyLinkedList()
56+
a_doubly_linked_list.insert_at_beginning(5)
57+
a_doubly_linked_list.insert_at_beginning(4)
58+
59+
a_doubly_linked_list.insert_at(6, 2)
60+
self.assertEqual(a_doubly_linked_list.__str__(), "4 --> 5 --> 6")
61+
self.assertEqual(a_doubly_linked_list.length(), 3)
62+
63+
def test_insert_at_should_insert_at_end(self):
64+
a_doubly_linked_list = DoublyLinkedList()
65+
a_doubly_linked_list.insert_at_beginning(5)
66+
a_doubly_linked_list.insert_at_beginning(4)
67+
a_doubly_linked_list.insert_at_beginning(4)
68+
a_doubly_linked_list.insert_at_beginning(4)
69+
70+
a_doubly_linked_list.insert_at(6, 4)
71+
self.assertEqual(a_doubly_linked_list.__str__(), "4 --> 4 --> 4 --> 5 --> 6")
72+
self.assertEqual(a_doubly_linked_list.length(), 5)
73+
74+
def test_remove_val_should_remove_values_from_list(self):
75+
a_doubly_linked_list = DoublyLinkedList()
76+
a_doubly_linked_list.insert_at_beginning(4)
77+
a_doubly_linked_list.insert_at_beginning(3)
78+
a_doubly_linked_list.insert_at_beginning(2)
79+
a_doubly_linked_list.insert_at_beginning(1)
80+
81+
a_doubly_linked_list.remove_val(1)
82+
self.assertEqual(a_doubly_linked_list.length(), 3)
83+
self.assertEqual(a_doubly_linked_list.__str__(), "2 --> 3 --> 4")
84+
85+
def test_remove_val_should_remove_values_from_list_when_values_are_all_the_same(self):
86+
a_doubly_linked_list = DoublyLinkedList()
87+
a_doubly_linked_list.insert_at_beginning(4)
88+
a_doubly_linked_list.insert_at_beginning(4)
89+
a_doubly_linked_list.insert_at_beginning(4)
90+
a_doubly_linked_list.insert_at_beginning(4)
91+
92+
a_doubly_linked_list.remove_val(4)
93+
self.assertEqual(a_doubly_linked_list.length(), 0)
94+
self.assertEqual(a_doubly_linked_list.__str__(), "")
95+
96+
def test_remove_val_should_remove_values_from_list_when_values_are_all_the_same_except_one(self):
97+
a_doubly_linked_list = DoublyLinkedList()
98+
a_doubly_linked_list.insert_at_beginning(4)
99+
a_doubly_linked_list.insert_at_beginning(5)
100+
a_doubly_linked_list.insert_at_beginning(4)
101+
a_doubly_linked_list.insert_at_beginning(4)
102+
103+
a_doubly_linked_list.remove_val(4)
104+
self.assertEqual(a_doubly_linked_list.__str__(), "5")
105+
self.assertEqual(a_doubly_linked_list.length(), 1)
106+
self.assertEqual(a_doubly_linked_list.__str__(), "5")

0 commit comments

Comments
 (0)