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

Leaves - Yitgop #41

Open
wants to merge 2 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
16 changes: 16 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Listen for rdebug-ide",
"type": "Ruby",
"request": "attach",
"remoteHost": "127.0.0.1",
"remotePort": "1234",
"remoteWorkspaceRoot": "${workspaceRoot}"
}
]
}
185 changes: 167 additions & 18 deletions lib/linked_list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,99 +19,248 @@ 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)

Choose a reason for hiding this comment

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

👍

raise NotImplementedError
# circular linked list, therefore @head point to itself
@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)

Choose a reason for hiding this comment

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

👍

raise NotImplementedError
current = @head

until current.nil?
return true if current.data == value
current = current.next
end

return false
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
# 1. if linked list is empty:
return nil if @head.nil?

# 2. if not empty:
max = @head.data
upcoming = @head.next

until upcoming.nil?
max = upcoming.data if upcoming.data > max
upcoming = upcoming.next
end

return max
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
# 1. if linked list is empty:
return nil if @head.nil?

# 2. if not empty:
min = @head.data
upcoming = @head.next

until upcoming.nil?
min = upcoming.data if upcoming.data < min
upcoming = upcoming.next
end

return min
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

until 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
# rule out input error: index > length || index < 0
return nil if index > self.length || 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
# if linked list is empty:
return nil if @head.nil?

current = @head
until current.nil?
# p instead of return to continue the loop
p current.data
current = current.next
end
end

# method to delete the first node found with specified value
def delete(value)
raise NotImplementedError
# if linked list is empty:
return nil if @head.nil?

current = @head
@head = @head.next if current.data == value

until current.next.nil?
if current.next.data == value
current.next = current.next.next
return
end
current = current.next
end

return
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.

This doesn't seem to work as you never change @head

raise NotImplementedError
# nothing to be reversed if list is empty or only has one node:
return if @head.nil? || @head.next.nil?

current = @head
prev = nil

until current.nil?
temp = current.next
current.next = prev
prev = current
current = temp
end

@head = prev
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 nil if @head.nil?

slow = @head
fast = @head.next

until fast.nil?
slow = slow.next
fast = fast.next.next
end

return slow.data
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 nil if @head.nil? || self.length < n

slow = @head
fast = @head

(n - 1).times do
fast = fast.next
end

until fast.next.nil?
slow = slow.next
fast = fast.next
end

return slow.data
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.
# linked list links to a node already visited < different def than circular LI >
# 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.

This doesn't quite work as the cycle doesn't have to connect the head to the tail, it could be a circle starting toward the end. Like if the last node points to the 2nd to last node.

raise NotImplementedError
end
return false if @head.nil?

slow = @head.next
fast = @head.next.next

until fast.nil?
return true if fast == slow
fast = fast.next
slow = slow.next
end

return false
end

# Additional Exercises
# returns the value in the first node
# returns nil if the list is empty
def get_first
raise NotImplementedError
return nil if @head.nil?
return @head.data
end

# method that inserts a given value as a new last node in the linked list
def add_last(value)
raise NotImplementedError
# 1. if list is empty:
self.add_first(value) if @head.nil?

# 2. if not empty:
curr = @head
(self.length - 1).times do
curr = curr.next
end
curr.next = Node.new(value)
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
raise NotImplementedError
return nil if @head.nil?

curr = @head
until curr.next.nil?
curr = curr.next
end

return curr.data
end

# method to insert a new node with specific data value, assuming the linked
# list is sorted in ascending order
def insert_ascending(value)
raise NotImplementedError
@head = Node.new(value) if @head.nil?

if @head.data > value
temp = @head
@head = Node.new(value)
@head.next = temp
else
curr = @head
until curr.nil?
if value >= curr.data
new = Node.new(value,curr.next.next)
curr.next = new

Choose a reason for hiding this comment

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

You'll want to leave the loop when you add the new node.

Suggested change
curr.next = new
curr.next = new
return

return
end
curr = curr.next
end
end
end

# Helper method for tests
Expand Down