Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Branches - Eve #30

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions lib/doubly_linked_list.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
class DoublyNode
attr_reader :data
attr_accessor :next, :previous

def initialize(value)
@data = value
@next = nil
@previous = nil
end
end

class DoublyLinkedList
def initialize
@head = nil
@tail = nil

Choose a reason for hiding this comment

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

Great idea to have a @tail attribute!

@size = 0
end

def length
return @size
# raise NotImplementedError
end

def add_first(value)

Choose a reason for hiding this comment

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

👍

new_node = DoublyNode.new(value)

if @head
@head.previous = new_node
new_node.next = @head
else
@tail = new_node
end
@head = new_node
@size += 1
end

def add_last(value)

Choose a reason for hiding this comment

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

👍

new_node = DoublyNode.new(value)

if @tail
@tail.next = new_node
new_node.previous = @tail
else
@head = new_node
end
@tail = new_node
@size += 1
end

def get_first

Choose a reason for hiding this comment

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

👍

return @head.data if @head
return @head
end

def get_last
return @tail.data if @tail
return @tail

Choose a reason for hiding this comment

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

This method works, but if @tail is nil, I suggest explicitly returning nil here.

Suggested change
return @tail
return nil

end

def get_at_index(index)

Choose a reason for hiding this comment

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

👍

if @head && index < @size && index >= 0
current = @head
count = 0
while count < index
current = current.next
count += 1
end
return current.data
end
return nil
end

def reverse

Choose a reason for hiding this comment

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

👍

if @head
@tail = @head
current = @head
while current
previous_node = current.previous
current.previous = current.next
current.next = previous_node
@head = current
current = current.previous
end
end
end

def delete(value)

Choose a reason for hiding this comment

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

👍

current = @head
while current
if current.data == value
previous_node = current.previous
next_node = current.next

if previous_node
previous_node.next = next_node
else
@head = next_node
end

if next_node
next_node.previous = previous_node
else
@tail = previous_node
end

@size -= 1
break
end
current = current.next
end
end

end
157 changes: 141 additions & 16 deletions lib/linked_list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,99 +19,197 @@ def initialize
# 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
def add_first(value)
raise NotImplementedError
@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
def search(value)
raise NotImplementedError
return find_node_and_previous_node(value).first != nil
end

# method to return the max value in the linked list
# returns the data value and not the node
def find_max

Choose a reason for hiding this comment

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

👍

raise NotImplementedError
current = @head
if current.nil?
return nil
else
max = current.data
while !current.next.nil?
current = current.next
max = current.data if (current.data > max)
end
return max
end
end

# method to return the min value in the linked list
# returns the data value and not the node
def find_min

Choose a reason for hiding this comment

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

👍

raise NotImplementedError
current = @head
if current.nil?
return nil
else
min = current.data
while !current.next.nil?
current = current.next
min = current.data if (current.data < min)
end
return min
end
end


# method that returns the length of the singly linked list
def length

Choose a reason for hiding this comment

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

👍

raise NotImplementedError
length = 0
current = @head
while !current.nil?
length += 1
current = current.next
end
return length
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
def get_at_index(index)

Choose a reason for hiding this comment

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

👍

raise NotImplementedError
return nil if index > (length() - 1) || index < 0

current = @head
index.times do
current = current.next
end
return current.data
end

# method to print all the values in the linked list
def visit

Choose a reason for hiding this comment

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

👍

raise NotImplementedError
current = @head
while current
puts current.data
current = current.next
end
end

# method to delete the first node found with specified value
def delete(value)
raise NotImplementedError
node_and_previous_node_pair = find_node_and_previous_node(value)
if node_and_previous_node_pair.first
previous = node_and_previous_node_pair[1]
current = node_and_previous_node_pair[0]

if !previous
@head = current.next
else
previous.next = current.next
end
end
end

# method to reverse the singly linked list
# note: the nodes should be moved and not just the values in the nodes
def reverse

Choose a reason for hiding this comment

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

👍

raise NotImplementedError
previous = nil
current = @head
while current
next_node = current.next

current.next = previous
previous = current
current = next_node
end

@head = previous
end


## Advanced Exercises
# returns the value at the middle element in the singly linked list
def find_middle_value

Choose a reason for hiding this comment

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

👍

raise NotImplementedError
return get_at_index((length() - 1 )/ 2)
end

# find the nth node from the end and return its value
# assume indexing starts at 0 while counting to n
def find_nth_from_end(n)

Choose a reason for hiding this comment

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

👍

raise NotImplementedError
return get_at_index(length() - 1 - n)
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.
def has_cycle

Choose a reason for hiding this comment

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

👍

raise NotImplementedError
single = @head
if single && single.next && single.next.next
double = single.next.next
while single && double
return true if single == double
2.times do
double = double.next
return false if !double
end
single = single.next
end
end
return false
end


# Additional Exercises
# returns the value in the first node
# returns nil if the list is empty
def get_first

Choose a reason for hiding this comment

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

👍

raise NotImplementedError
return nil if !@head
return @head.data
end

# method that inserts a given value as a new last node in the linked list
def add_last(value)

Choose a reason for hiding this comment

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

👍

raise NotImplementedError
last_node = find_last_node
if last_node
last_node.next = Node.new(value)
else
@head = Node.new(value)
end
end

# method that returns the value of the last node in the linked list
# returns nil if the linked list is empty
def get_last

Choose a reason for hiding this comment

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

👍

raise NotImplementedError
last_node = find_last_node()
if last_node
return last_node.data
else
return last_node

Choose a reason for hiding this comment

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

Suggested change
return last_node
return nil

end
end

# method to insert a new node with specific data value, assuming the linked
# list is sorted in ascending order
def insert_ascending(value)

Choose a reason for hiding this comment

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

👍

raise NotImplementedError
new_node = Node.new(value)
if @head
current = @head
previous = nil

while current
break if current.data >= value
previous = current
current = current.next
end

if previous
previous.next = new_node
else
@head = new_node
end
new_node.next = current
else
@head = new_node
end
end

# Helper method for tests
Expand All @@ -128,4 +226,31 @@ def create_cycle

current.next = @head # make the last node link to first node
end

private
def find_last_node
current = @head
while current && current.next
current = current.next
end
return current
end

def find_node_and_previous_node(value)
current = @head

if current && current.data == value
return [current, nil]
end

while current && current.next
previous = current
current = current.next
if current.data == value
return [current, previous]
end
end

return [nil, nil]
end
end
Loading