Skip to content
336 changes: 225 additions & 111 deletions lib/linked_list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,150 +12,264 @@ def initialize(value, next_node = nil)

# Defines the singly linked list
class LinkedList
def initialize
@head = nil # keep the head private. Not accessible outside this class
end
def initialize
@head = nil # keep the head private. Not accessible outside self class
end

# method to add a new node with the specific data value in the linked list
# insert the new node at the beginning of the linked list
# Time Complexity: ?
# Space Complexity: ?
def add_first(value)
raise NotImplementedError
# method to add a new node with the specific data value in the linked list
# insert the new node at the beginning of the linked list
# Time Complexity: O(1)
# Space Complexity: O(1)
def add_first(value)
Comment on lines +19 to +23

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

if @head
second = @head
@head = Node.new(value, second)
else
@head = Node.new(value)
end
Comment on lines +24 to 29

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if @head
second = @head
@head = Node.new(value, second)
else
@head = Node.new(value)
end
@head = Node.new(value, @head)

end

# method to find if the linked list contains a node with specified value
# returns true if found, false otherwise
# Time Complexity: ?
# Space Complexity: ?
def search(value)
raise NotImplementedError
# method to find if the linked list contains a node with specified value
# returns true if found, false otherwise
# Time Complexity: O(n)
# Space Complexity: O(1)
def search(value)
Comment on lines +34 to +36

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Nice helper method

if @head == nil
return false
end
return search_help(value) != nil
end

# method to return the max value in the linked list
# returns the data value and not the node
def find_max
raise NotImplementedError
# method to return the max value in the linked list
# returns the data value and not the node
def find_max
Comment on lines +43 to +45

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

if @head == nil
return nil
end
max = @head.data
current = @head
while current != nil
if current.data > max
max = current.data
end
current = current.next
end
return max
end

# method to return the min value in the linked list
# returns the data value and not the node
# Time Complexity: ?
# Space Complexity: ?
def find_min
raise NotImplementedError
# method to return the min value in the linked list
# returns the data value and not the node
# Time Complexity: O(n)
# Space Complexity: O(1)
def find_min
Comment on lines +62 to +64

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

if @head == nil
return nil
end
min = @head.data
current = @head
while current != nil
if current.data < min
min = current.data
end
current = current.next
end
return min
end


# method that returns the length of the singly linked list
# Time Complexity: ?
# Space Complexity: ?
def length
raise NotImplementedError
# method that returns the length of the singly linked list
# Time Complexity: O(n)
# Space Complexity: O(1)
def length
Comment on lines +81 to +83

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

if @head == nil
return 0
end

# method that returns the value at a given index in the linked list
# index count starts at 0
# returns nil if there are fewer nodes in the linked list than the index value
# Time Complexity: ?
# Space Complexity: ?
def get_at_index(index)
raise NotImplementedError
current = @head
length = 0
while current != nil
length += 1
current = current.next
end
return length
end

# method to print all the values in the linked list
# Time Complexity: ?
# Space Complexity: ?
def visit
raise NotImplementedError
# method that returns the value at a given index in the linked list
# index count starts at 0
# returns nil if there are fewer nodes in the linked list than the index value
# Time Complexity: O(n)
# Space Complexity: O(1)
def get_at_index(index)
Comment on lines +99 to +101

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

node = get_node_at_index(index)
if node
return node.data
else
return nil
end
end

# method to delete the first node found with specified value
# Time Complexity: ?
# Space Complexity: ?
def delete(value)
raise NotImplementedError
# method to print all the values in the linked list
# Time Complexity: O(n)
# Space Complexity: O(1)
def visit
Comment on lines +111 to +113

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

current = @head
while current != nil
puts current.data
current = current.next
end
end

# method to delete the first node found with specified value
# Time Complexity: O(n)
# Space Complexity: O(1)
def delete(value)
Comment on lines +121 to +124

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

target = search_help(value)
after_target = target.next
target.next = nil
before_target_index = self.length - 2
before_target = get_node_at_index(before_target_index)
before_target.next = after_target
end

# method to reverse the singly linked list
# note: the nodes should be moved and not just the values in the nodes
# Time Complexity: ?
# Space Complexity: ?
def reverse
raise NotImplementedError
# method to reverse the singly linked list
# note: the nodes should be moved and not just the values in the nodes
# Time Complexity: O(n)
# Space Complexity: O(n)
def reverse
Comment on lines +133 to +137

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

new_list = LinkedList.new
current = @head
while current != nil
new_list.add_first(current)
current = current.next
end
@head.next = nil
@head = new_list.get_first
end


## Advanced Exercises
# returns the value at the middle element in the singly linked list
# Time Complexity: ?
# Space Complexity: ?
def find_middle_value
raise NotImplementedError
end
## Advanced Exercises
# returns the value at the middle element in the singly linked list
# Time Complexity: O(n)
# Space Complexity: O(1)
def find_middle_value
Comment on lines +149 to +153

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

length = self.length
middle_index = length/2
return get_at_index(middle_index)
end

# find the nth node from the end and return its value
# assume indexing starts at 0 while counting to n
# Time Complexity: ?
# Space Complexity: ?
def find_nth_from_end(n)
raise NotImplementedError
end
# find the nth node from the end and return its value
# assume indexing starts at 0 while counting to n
# Time Complexity: O(n)
# Space Complexity: O(1)
def find_nth_from_end(n)
Comment on lines +161 to +163

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

length = self.length
nth_from_end_index = length - 1 - n
return get_at_index(nth_from_end_index)
end

# checks if the linked list has a cycle. A cycle exists if any node in the
# linked list links to a node already visited.
# returns true if a cycle is found, false otherwise.
# Time Complexity: ?
# Space Complexity: ?
def has_cycle
raise NotImplementedError
# checks if the linked list has a cycle. A cycle exists if any node in the
# linked list links to a node already visited.
# returns true if a cycle is found, false otherwise.
# Time Complexity: ?
# Space Complexity: ?
def has_cycle
current = @head
seen_nodes = []
# while current != nil || has_node?(current)
# current = current.next
# if current == nil
# return false
# end
# if has_node
# end
end
def has_node?(array, node)
array.each do |current_node|
if current_node == node
return true
end
end
return false
end


# Additional Exercises
# returns the value in the first node
# returns nil if the list is empty
# Time Complexity: ?
# Space Complexity: ?
def get_first
raise NotImplementedError
# Additional Exercises
# returns the value in the first node
# returns nil if the list is empty
# Time Complexity: ?
# Space Complexity: ?
def get_first
Comment on lines +198 to +200

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

if @head
return @head
else
return nil
end
end

# method that inserts a given value as a new last node in the linked list
# Time Complexity: ?
# Space Complexity: ?
def add_last(value)
raise NotImplementedError
end
# method that inserts a given value as a new last node in the linked list
# Time Complexity: ?
# Space Complexity: ?
def add_last(value)
raise NotImplementedError
end

# method that returns the value of the last node in the linked list
# returns nil if the linked list is empty
# Time Complexity: ?
# Space Complexity: ?
def get_last
raise NotImplementedError
end
# method that returns the value of the last node in the linked list
# returns nil if the linked list is empty
# Time Complexity: ?
# Space Complexity: ?
def get_last
raise NotImplementedError
end

# method to insert a new node with specific data value, assuming the linked
# list is sorted in ascending order
# Time Complexity: ?
# Space Complexity: ?
def insert_ascending(value)
raise NotImplementedError
end

# Helper method for tests
# Creates a cycle in the linked list for testing purposes
# Assumes the linked list has at least one node
def create_cycle
return if @head == nil # don't do anything if the linked list is empty

# method to insert a new node with specific data value, assuming the linked
# list is sorted in ascending order
# Time Complexity: ?
# Space Complexity: ?
def insert_ascending(value)
raise NotImplementedError
# navigate to last node
current = @head
while current.next != nil
current = current.next
end

# Helper method for tests
# Creates a cycle in the linked list for testing purposes
# Assumes the linked list has at least one node
def create_cycle
return if @head == nil # don't do anything if the linked list is empty
current.next = @head # make the last node link to first node
end

# navigate to last node
current = @head
while current.next != nil
current = current.next
private

def get_node_at_index(index)
length = self.length
if length < index
return nil
end
current = @head
(0..(length-1)).each do |i|
if i == index
return current
end
current = current.next
end
return nil
end

current.next = @head # make the last node link to first node
def search_help(value)
current = @head
while current != nil
if current.data == value
return current
else
current = current.next
end
end
return nil
end

end