Skip to content

Commit a038ca0

Browse files
committed
feat: Finish LinkedList methods
1 parent 021eb5e commit a038ca0

File tree

3 files changed

+197
-99
lines changed

3 files changed

+197
-99
lines changed

.gitignote

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
.byebug_history
1+
byebug_history

data-structures/LinkedList/linked_list.rb

Lines changed: 75 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3,68 +3,94 @@
33
class LinkedList
44
attr_accessor :head, :tail
55

6-
def add(value)
7-
node = Node.new(value)
8-
node.value = value
9-
if !head
10-
@head = node
11-
@tail = node
6+
def append(value)
7+
raise ArgumentError.new("Error: Invalid value") if value.nil?
8+
new_node = Node.new(value)
9+
new_node.previous_node = @tail
10+
@tail.next_node = new_node if @tail
11+
@tail = new_node
12+
@head ||= new_node
13+
"Success: Value '#{value}' was appended"
14+
rescue => exception
15+
warn exception.message
16+
end
17+
18+
def prepend(value)
19+
raise ArgumentError.new("Error: Invalid value") if value.nil?
20+
new_node = Node.new(value)
21+
new_node.next_node = @head
22+
@head.previous_node = new_node if @head
23+
@head = new_node
24+
@tail ||= new_node
25+
"Success: Value '#{value}' was prepended"
26+
rescue => exception
27+
warn exception.message
28+
end
29+
30+
def insert_at(index, value)
31+
raise ArgumentError.new("Error: Invalid value") if value.nil?
32+
raise IndexError.new("Error: Index out of bounds") if index < 0 || index > size
33+
raise StandardError.new("Error: The list is empty") if size == 0
34+
35+
case index
36+
when 0
37+
prepend(value)
38+
when size
39+
append(value)
1240
else
13-
node.previous_node = @tail
14-
@tail.next_node = node
15-
@tail = node
41+
new_node = Node.new(value)
42+
prev_node = select_node(index - 1)
43+
next_node = select_node(index)
44+
45+
prev_node.next_node = new_node
46+
new_node.previous_node = prev_node
47+
new_node.next_node = next_node
48+
next_node.previous_node = new_node
1649
end
17-
"success"
50+
"Success: Value '#{value}' was inserted at index #{index}"
51+
rescue => exception
52+
warn exception.message
1853
end
1954

2055
def get(index)
21-
begin
22-
return @head.value if index === 0
23-
node = select_node(index)
24-
raise "INDEX #{index} OUT OF BOUNDS" if !node
25-
node.value
26-
rescue => exception
27-
p "#{exception.message}"
28-
end
56+
raise StandardError.new("Error: The list is empty") if size === 0
57+
return @head.value if index === 0
58+
node = select_node(index)
59+
raise IndexError.new("Index #{index} out of bounds") if !node
60+
node.value
61+
rescue => exception
62+
warn exception.message
2963
end
3064

3165
def replace(index, new_value)
32-
begin
33-
node_to_replace = select_node(index)
34-
raise "INDEX #{index} OUT OF BOUNDS" if !node_to_replace
35-
# Replace the value directly
36-
node_to_replace.value = new_value
37-
new_value # This should be the replaced node's value
38-
rescue => exception
39-
p "#{exception.message}"
40-
end
66+
raise StandardError.new("Error: The list is empty") if size === 0
67+
node_to_replace = select_node(index)
68+
raise IndexError.new("Index #{index} out of bounds") unless node_to_replace
69+
node_to_replace.value = new_value
70+
rescue => exception
71+
warn exception.message
4172
end
4273

4374
def remove(index)
44-
begin
45-
# if the node is the head
46-
if index === 0
47-
@head.next_node.previous_node = nil
48-
@head = @head.next_node
49-
return
50-
end
51-
52-
node = select_node(index)
53-
raise "INDEX #{index} OUT OF BOUNDS" if !node
54-
# if the node is the tail
55-
if !node.next_node
56-
node.previous_node.next_node = nil
57-
@tail = node.previous_node
58-
return
59-
end
75+
raise StandardError.new("Error: The list is empty") if size === 0
76+
if index === 0
77+
@head.next_node.previous_node = nil
78+
@head = @head.next_node
79+
return
80+
end
6081

61-
# if the node is in the middle
62-
node.previous_node.next_node = node.next_node
63-
node.next_node.previous_node = node.next_node
82+
node = select_node(index)
83+
raise IndexError.new("Index #{index} out of bounds") if !node
84+
if !node.next_node
85+
node.previous_node.next_node = nil
86+
@tail = node.previous_node
6487
return
65-
rescue => exception
66-
p "#{exception.message}"
6788
end
89+
90+
node.previous_node.next_node = node.next_node
91+
node.next_node.previous_node = node.next_node
92+
rescue => exception
93+
warn exception.message
6894
end
6995

7096
def inspect
@@ -78,7 +104,7 @@ def inspect
78104
end
79105

80106
def size
81-
return 0 if @head === nil
107+
return 0 if @head.nil?
82108
size = 1
83109
node = @head
84110
while node.next_node

spec/linked_list_spec.rb

Lines changed: 121 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,153 @@
1+
# frozen_string_literal: true
2+
13
require_relative "../data-structures/LinkedList/linked_list"
2-
require "byebug"
4+
35
RSpec.describe LinkedList do
4-
let(:linked_list) { LinkedList.new }
6+
context "with an empty list" do
7+
describe "#append" do
8+
it "adds a value to the enf of the list" do
9+
expect(subject.append("First Value")).to eq "Success: Value 'First Value' was appended"
10+
expect(subject.head.value).to eq "First Value"
11+
expect(subject.tail.value).to eq "First Value"
12+
expect(subject.size).to eq 1
13+
end
14+
end
515

6-
describe "#add" do
7-
it "adds a value to the linked list" do
8-
expect(linked_list.add("First Value")).to eq "success"
9-
expect(linked_list.head.value).to eq "First Value"
10-
expect(linked_list.tail.value).to eq "First Value"
16+
describe "#prepend" do
17+
it "adds a value at the start of the list" do
18+
expect(subject.prepend("New first value")).to eq "Success: Value 'New first value' was prepended"
19+
expect(subject.head.value).to eq "New first value"
20+
expect(subject.tail.value).to eq "New first value"
21+
end
1122
end
12-
end
1323

14-
describe "#get" do
15-
it "gets the value at a given index" do
16-
linked_list.add("First Value")
17-
linked_list.add("Second Value")
18-
expect(linked_list.get(1)).to eq "Second Value"
24+
describe "#isert_at" do
25+
it "show an error" do
26+
expect { subject.insert_at(0, "First value") }.to output("Error: The list is empty\n").to_stderr
27+
end
1928
end
2029

21-
it "returns error message if index out of bounds" do
22-
expect(linked_list.get(10)).to eq "INDEX 10 OUT OF BOUNDS"
30+
describe "#get" do
31+
it "returns error message if list is empty" do
32+
expect { subject.get(0) }.to output("Error: The list is empty\n").to_stderr
33+
end
2334
end
24-
end
2535

26-
describe "#replace" do
27-
before do
28-
linked_list.add("First Value")
29-
linked_list.add("Second Value")
36+
describe "#replace" do
37+
it "returns error message if list is empty" do
38+
expect { subject.replace(0, "New Value") }.to output("Error: The list is empty\n").to_stderr
39+
end
40+
end
41+
42+
describe "#remove" do
43+
it "returns error message if the list is empty" do
44+
expect { subject.remove(0) }.to output("Error: The list is empty\n").to_stderr
45+
end
3046
end
3147

32-
it "replaces the value at a given index" do
33-
linked_list.replace(1, "New First Value")
34-
expect(linked_list.get(1)).to eq "New First Value"
48+
describe "#inspect" do
49+
it "prints the linked list" do
50+
expect(subject.inspect).to eq []
51+
end
3552
end
3653

37-
it "returns error message if index out of bounds" do
38-
expect(linked_list.replace(10, "New Value")).to eq "INDEX 10 OUT OF BOUNDS"
54+
describe "#size" do
55+
it "returns 0 if the linked list is empty" do
56+
expect(subject.size).to eq 0
57+
end
3958
end
4059
end
4160

42-
describe "#remove" do
61+
context "whit nodes already in the list" do
4362
before do
44-
linked_list.add("First Value")
45-
linked_list.add("Second Value")
63+
subject.append("First Value")
64+
subject.append("Second Value")
4665
end
4766

48-
it "removes the value at a given index" do
49-
linked_list.remove(0)
50-
expect(linked_list.get(0)).to eq "Second Value"
67+
describe "#append" do
68+
it "adds a value to the enf of the list" do
69+
expect(subject.append("Third Value")).to eq "Success: Value 'Third Value' was appended"
70+
expect(subject.head.value).to eq "First Value"
71+
expect(subject.tail.value).to eq "Third Value"
72+
expect(subject.size).to eq 3
73+
end
5174
end
5275

53-
it "returns error message if index out of bounds" do
54-
expect(linked_list.remove(10)).to eq "INDEX 10 OUT OF BOUNDS"
76+
describe "#prepend" do
77+
it "adds a value at the start of the list" do
78+
expect(subject.prepend("New first value")).to eq "Success: Value 'New first value' was prepended"
79+
expect(subject.head.value).to eq "New first value"
80+
expect(subject.tail.value).to eq "Second Value"
81+
end
5582
end
56-
end
5783

58-
describe "#inspect" do
59-
before do
60-
linked_list.add("First Value")
61-
linked_list.add("Second Value")
84+
describe "#isert_at" do
85+
it "inserts the node on index 0" do
86+
expect(subject.size).to eq 2
87+
expect(subject.insert_at(0, "New node")).to eq "Success: Value 'New node' was inserted at index 0"
88+
expect(subject.head.value).to eq "New node"
89+
expect(subject.size).to eq 3
90+
end
91+
92+
it "inserts the node on the last index" do
93+
expect(subject.size).to eq 2
94+
expect(subject.insert_at(2, "New node")).to eq "Success: Value 'New node' was inserted at index 2"
95+
expect(subject.tail.value).to eq "New node"
96+
expect(subject.size).to eq 3
97+
end
98+
99+
it "inserts the new node in the middle" do
100+
expect(subject.size).to eq 2
101+
expect(subject.insert_at(1, "New node")).to eq "Success: Value 'New node' was inserted at index 1"
102+
expect(subject.head.value).to eq "First Value"
103+
expect(subject.tail.value).to eq "Second Value"
104+
expect(subject.size).to eq 3
105+
end
62106
end
63107

64-
it "prints the linked list" do
65-
expect(linked_list.inspect).to eq ["First Value", "Second Value"]
108+
describe "#get" do
109+
it "gets the value at a given index" do
110+
expect(subject.get(1)).to eq "Second Value"
111+
end
112+
113+
it "returns error message if index out of bounds" do
114+
expect { subject.get(10) }.to output("Index 10 out of bounds\n").to_stderr
115+
end
116+
end
117+
118+
describe "#replace" do
119+
it "replaces the value at a given index" do
120+
subject.replace(1, "New First Value")
121+
expect(subject.get(1)).to eq "New First Value"
122+
end
123+
124+
it "returns error message if index out of bounds" do
125+
expect { subject.replace(10, "New Value") }.to output("Index 10 out of bounds\n").to_stderr
126+
end
127+
end
128+
129+
describe "#remove" do
130+
it "removes the value at a given index" do
131+
subject.remove(0)
132+
expect(subject.get(0)).to eq "Second Value"
133+
end
134+
135+
it "returns error message if index out of bounds" do
136+
expect { subject.remove(10) }.to output("Index 10 out of bounds\n").to_stderr
137+
end
66138
end
67-
end
68139

69-
describe "#size" do
70-
it "returns the size of the linked list" do
71-
linked_list.add("First Value")
72-
linked_list.add("Second Value")
73-
linked_list.add("Third Value")
74-
expect(linked_list.size).to eq 3
140+
describe "#inspect" do
141+
it "prints the linked list" do
142+
expect(subject.inspect).to eq ["First Value", "Second Value"]
143+
end
75144
end
76145

77-
it "returns 0 if the linked list is empty" do
78-
expect(linked_list.size).to eq 0
146+
describe "#size" do
147+
it "returns the size of the linked list" do
148+
subject.append("Third Value")
149+
expect(subject.size).to eq 3
150+
end
79151
end
80152
end
81153
end

0 commit comments

Comments
 (0)