diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 00000000..8bf4d45d
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,6 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 00000000..a55e7a17
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/linked-list.iml b/.idea/linked-list.iml
new file mode 100644
index 00000000..db98faa2
--- /dev/null
+++ b/.idea/linked-list.iml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 00000000..510e7fcc
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 00000000..a096c061
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 00000000..94a25f7f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/lib/linked_list.rb b/lib/linked_list.rb
index 5e173ebc..3b2610c8 100644
--- a/lib/linked_list.rb
+++ b/lib/linked_list.rb
@@ -12,39 +12,75 @@ 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 this 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
- end
+ def add_first(value)
+ @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
+ def search(value)
+ current = @head
+
+ until current == nil
+ if current.data == value
+ return true
+ end
+ 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
- raise NotImplementedError
+ def find_max
+ current = @head
+
+ return nil if current.nil?
+
+ max = @head.data
+
+ until current == nil
+ if current.data > max
+ max = current.data
+ current = current.next
+ else
+ current = current.next
+ end
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
+ def find_min
+ current = @head
+
+ return nil if @head.nil?
+
+ min = @head.data
+
+ until current == nil
+ if current.data < min
+ min = current.data
+ current = current.next
+ else
+ current = current.next
+ end
end
+ return min
+ end
# Additional Exercises
@@ -52,108 +88,143 @@ def find_min
# returns nil if the list is empty
# Time Complexity: ?
# Space Complexity: ?
- def get_first
- raise NotImplementedError
- end
+ def get_first
+ return @head ? @head.data : nil
+ 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
+ def add_last(value)
+ new_node = Node.new(value)
+
+ if @head.nil?
+ @head = new_node
end
+ current = @head
+
+ until current.next.nil?
+ current = current.next
+ end
+ current.next = new_node
+ end
+
# method that returns the length of the singly linked list
# Time Complexity: ?
# Space Complexity: ?
- def length
- raise NotImplementedError
+ def length
+ current = @head
+
+ length = 0
+
+ until current.nil?
+ current = current.next
+ length += 1
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
# Time Complexity: ?
# Space Complexity: ?
- def get_at_index(index)
- raise NotImplementedError
+ def get_at_index(index)
+ return nil if @head.nil?
+
+ current = @head
+
+ index.times do
+ if current.next.nil?
+ return nil
+ else
+ current = current.next
+ end
end
+ return current.data
+ end
# method to print all the values in the linked list
# Time Complexity: ?
# Space Complexity: ?
- def visit
- raise NotImplementedError
+ def visit
+ current = @head
+
+ while current
+ print current.data
+ current = current.next
end
+ end
# method to delete the first node found with specified value
# Time Complexity: ?
# Space Complexity: ?
- def delete(value)
- raise NotImplementedError
- end
+ def delete(value)
+ raise NotImplementedError
+ 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
- end
+ def reverse
+ 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
+ def get_last
+ raise NotImplementedError
+ 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
+ def find_middle_value
+ 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: ?
# Space Complexity: ?
- def find_nth_from_end(n)
- raise NotImplementedError
- end
+ def find_nth_from_end(n)
+ raise NotImplementedError
+ 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
- end
+ def has_cycle
+ 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
+ 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
-
- # navigate to last node
- current = @head
- while current.next != nil
- current = current.next
- end
+ 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
+ # navigate to last node
+ current = @head
+ while current.next != nil
+ current = current.next
end
+
+ current.next = @head # make the last node link to first node
+ end
end
diff --git a/test/linked_list_test.rb b/test/linked_list_test.rb
index 77423e34..8d47c23c 100644
--- a/test/linked_list_test.rb
+++ b/test/linked_list_test.rb
@@ -5,241 +5,241 @@
describe LinkedList do
# Arrange
- before do
- @list = LinkedList.new
- end
+ before do
+ @list = LinkedList.new
+ end
- describe 'initialize' do
- it 'can be created' do
+ describe 'initialize' do
+ it 'can be created' do
- # Assert
- expect(@list).must_be_kind_of LinkedList
- end
+ # Assert
+ expect(@list).must_be_kind_of LinkedList
end
+ end
- describe 'add_first & get_first' do
- it 'can add values to an empty list' do
- # Act
- @list.add_first(3)
+ describe 'add_first & get_first' do
+ it 'can add values to an empty list' do
+ # Act
+ @list.add_first(3)
- # Assert
- expect(@list.get_at_index(0)).must_equal 3
- end
+ # Assert
+ expect(@list.get_at_index(0)).must_equal 3
+ end
- it 'will put the last added item to the front of the list' do
- # Act
- @list.add_first(1)
- @list.add_first(2)
+ it 'will put the last added item to the front of the list' do
+ # Act
+ @list.add_first(1)
+ @list.add_first(2)
- # Assert
- expect(@list.get_at_index(0)).must_equal 2
+ # Assert
+ expect(@list.get_at_index(0)).must_equal 2
- # Act again
- @list.add_first(3)
+ # Act again
+ @list.add_first(3)
- # Assert
- expect(@list.get_at_index(0)).must_equal 3
- end
+ # Assert
+ expect(@list.get_at_index(0)).must_equal 3
+ end
- it 'will return `nil` for `getFirst` if the list is empty' do
+ it 'will return `nil` for `getFirst` if the list is empty' do
- expect(@list.get_at_index(0)).must_be_nil
- end
+ expect(@list.get_at_index(0)).must_be_nil
end
+ end
- describe "search" do
- it "can find an element" do
- @list = LinkedList.new
- @list.add_first(3)
- @list.add_first(2)
+ describe "search" do
+ it "can find an element" do
+ @list = LinkedList.new
+ @list.add_first(3)
+ @list.add_first(2)
- expect(@list.search(3)).must_equal true
+ expect(@list.search(3)).must_equal true
- expect(@list.search(2)).must_equal true
- end
+ expect(@list.search(2)).must_equal true
+ end
- it "returns false if the element is not in the list" do
- @list = LinkedList.new
- @list.add_first(3)
- @list.add_first(2)
- expect(@list.search("pasta")).must_equal false
- end
+ it "returns false if the element is not in the list" do
+ @list = LinkedList.new
+ @list.add_first(3)
+ @list.add_first(2)
+ expect(@list.search("pasta")).must_equal false
+ end
- it "returns false for an empty list" do
- expect(@list.search(3)).must_equal false
- end
+ it "returns false for an empty list" do
+ expect(@list.search(3)).must_equal false
end
+ end
- describe "length" do
- it "will return 0 for an empty list" do
- expect(@list.length).must_equal 0
- end
+ describe "length" do
+ it "will return 0 for an empty list" do
+ expect(@list.length).must_equal 0
+ end
- it "will return the length for nonempty lists" do
- count = 0
- while count < 5
- @list.add_first(count)
- count += 1
- expect(@list.length).must_equal count
- end
- end
+ it "will return the length for nonempty lists" do
+ count = 0
+ while count < 5
+ @list.add_first(count)
+ count += 1
+ expect(@list.length).must_equal count
+ end
end
+ end
- describe 'get_at_index' do
- it 'returns nil if the index is outside the bounds of the list' do
- expect(@list.get_at_index(3)).must_be_nil
- end
+ describe 'get_at_index' do
+ it 'returns nil if the index is outside the bounds of the list' do
+ expect(@list.get_at_index(3)).must_be_nil
+ end
- it 'can retrieve an item at an index in the list' do
- @list.add_first(1)
- @list.add_first(2)
- @list.add_first(3)
- @list.add_first(4)
+ it 'can retrieve an item at an index in the list' do
+ @list.add_first(1)
+ @list.add_first(2)
+ @list.add_first(3)
+ @list.add_first(4)
- expect(@list.get_at_index(0)).must_equal 4
- expect(@list.get_at_index(1)).must_equal 3
- expect(@list.get_at_index(2)).must_equal 2
- expect(@list.get_at_index(3)).must_equal 1
- end
+ expect(@list.get_at_index(0)).must_equal 4
+ expect(@list.get_at_index(1)).must_equal 3
+ expect(@list.get_at_index(2)).must_equal 2
+ expect(@list.get_at_index(3)).must_equal 1
end
+ end
xdescribe "Optional addLast & getLast" do
- it "will add to the front if the list is empty" do
- @list.add_last(1)
- expect(@list.get_at_index(0)).must_equal 1
- end
-
- it "will put new items to the rear of the list" do
- @list.add_last(2)
- expect(@list.length).must_equal 1
- expect(@list.get_last).must_equal 2
-
- @list.add_last(3)
- expect(@list.get_at_index(0)).must_equal 2
- expect(@list.get_last).must_equal 3
- expect(@list.length).must_equal 2
-
- @list.add_last(4)
- expect(@list.get_at_index(0)).must_equal 2
- expect(@list.get_last).must_equal 4
- expect(@list.length).must_equal 3
- end
- end
-
- describe 'max and min values' do
- it 'returns nil if the list is empty' do
- expect(@list.find_max()).must_be_nil
- expect(@list.find_min()).must_be_nil
- end
-
- it 'can retrieve the max and min values in the list' do
- count = 0
- while count < 5
- @list.add_first(count)
- expect(@list.find_max).must_equal count
- expect(@list.find_min).must_equal 0
- count += 1
- end
-
- @list.add_first(100)
- @list.add_first(-12)
- expect(@list.find_max).must_equal 100
- expect(@list.find_min).must_equal(-12)
- @list.add_last(99)
- expect(@list.find_max).must_equal 100
- @list.add_first(50)
- expect(@list.find_min).must_equal(-12)
- end
- end
-
- describe "delete" do
- it "delete from empty linked list is a no-op" do
- expect(@list.length).must_equal 0
- @list.delete(4)
- expect(@list.length).must_equal 0
- end
-
- it "can delete valid values from list" do
- @list.add_first(9)
- @list.add_first(10)
- @list.add_first(4)
- @list.add_first(3)
- @list.add_first(2)
-
- # delete first node (requires updating head)
- @list.delete(2)
- expect(@list.get_first).must_equal 3
- expect(@list.length).must_equal 4
- expect(@list.get_at_index(@list.length - 1)).must_equal 9
- expect(@list.find_max).must_equal 10
- expect(@list.find_min).must_equal 3
-
- # delete last node
- @list.delete(10)
- expect(@list.get_at_index(0)).must_equal 3
- expect(@list.length).must_equal 3
- expect(@list.get_at_index(@list.length - 1)).must_equal 9
- expect(@list.find_max).must_equal 9
- expect(@list.find_min).must_equal 3
-
- # delete middle node (requires updating head)
- @list.delete(4)
- expect(@list.get_at_index(0)).must_equal 3
- expect(@list.length).must_equal 2
- expect(@list.get_at_index(@list.length - 1)).must_equal 9
- expect(@list.find_max).must_equal 9
- expect(@list.find_min).must_equal 3
- end
-
- it "can delete from the middle" do
- # Arrange
- @list.add_last(9)
- @list.add_last(10)
- @list.add_first(4)
- @list.add_first(3)
- @list.add_first(2)
-
- # Act
- @list.delete(9)
-
- # Assert
- expect(@list.get_last).must_equal 10
- expect(@list.length).must_equal 4
- expect(@list.get_first).must_equal 2
- end
- end
-
- xdescribe "Optional: nth_from_the_end" do
- it 'returns nil if n is outside the bounds of the list' do
- expect(@list.find_nth_from_end(3)).must_be_nil
- end
-
- it 'can retrieve an item at index n from the end in the list' do
- @list.add_first(1)
- @list.add_first(2)
- @list.add_first(3)
- @list.add_first(4)
-
- expect(@list.find_nth_from_end(0)).must_equal 1
- expect(@list.find_nth_from_end(1)).must_equal 2
- expect(@list.find_nth_from_end(2)).must_equal 3
- expect(@list.find_nth_from_end(3)).must_equal 4
- expect(@list.find_nth_from_end(4)).must_be_nil
- end
- end
-
- describe "reverse" do
- it 'can retrieve an item at index n from the end in the list' do
- @list.add_first(4)
- @list.add_first(3)
- @list.add_first(2)
- @list.add_first(1)
- @list.reverse
-
- expect(@list.get_at_index(0)).must_equal 4
- expect(@list.get_at_index(1)).must_equal 3
- expect(@list.get_at_index(2)).must_equal 2
- expect(@list.get_at_index(3)).must_equal 1
- end
+ it "will add to the front if the list is empty" do
+ @list.add_last(1)
+ expect(@list.get_at_index(0)).must_equal 1
+ end
+
+ it "will put new items to the rear of the list" do
+ @list.add_last(2)
+ expect(@list.length).must_equal 1
+ expect(@list.get_last).must_equal 2
+
+ @list.add_last(3)
+ expect(@list.get_at_index(0)).must_equal 2
+ expect(@list.get_last).must_equal 3
+ expect(@list.length).must_equal 2
+
+ @list.add_last(4)
+ expect(@list.get_at_index(0)).must_equal 2
+ expect(@list.get_last).must_equal 4
+ expect(@list.length).must_equal 3
+ end
+ end
+
+ describe 'max and min values' do
+ it 'returns nil if the list is empty' do
+ expect(@list.find_max()).must_be_nil
+ expect(@list.find_min()).must_be_nil
+ end
+
+ it 'can retrieve the max and min values in the list' do
+ count = 0
+ while count < 5
+ @list.add_first(count)
+ expect(@list.find_max).must_equal count
+ expect(@list.find_min).must_equal 0
+ count += 1
+ end
+
+ @list.add_first(100)
+ @list.add_first(-12)
+ expect(@list.find_max).must_equal 100
+ expect(@list.find_min).must_equal(-12)
+ @list.add_last(99)
+ expect(@list.find_max).must_equal 100
+ @list.add_first(50)
+ expect(@list.find_min).must_equal(-12)
+ end
+ end
+
+ xdescribe "delete" do
+ it "delete from empty linked list is a no-op" do
+ expect(@list.length).must_equal 0
+ @list.delete(4)
+ expect(@list.length).must_equal 0
+ end
+
+ it "can delete valid values from list" do
+ @list.add_first(9)
+ @list.add_first(10)
+ @list.add_first(4)
+ @list.add_first(3)
+ @list.add_first(2)
+
+ # delete first node (requires updating head)
+ @list.delete(2)
+ expect(@list.get_first).must_equal 3
+ expect(@list.length).must_equal 4
+ expect(@list.get_at_index(@list.length - 1)).must_equal 9
+ expect(@list.find_max).must_equal 10
+ expect(@list.find_min).must_equal 3
+
+ # delete last node
+ @list.delete(10)
+ expect(@list.get_at_index(0)).must_equal 3
+ expect(@list.length).must_equal 3
+ expect(@list.get_at_index(@list.length - 1)).must_equal 9
+ expect(@list.find_max).must_equal 9
+ expect(@list.find_min).must_equal 3
+
+ # delete middle node (requires updating head)
+ @list.delete(4)
+ expect(@list.get_at_index(0)).must_equal 3
+ expect(@list.length).must_equal 2
+ expect(@list.get_at_index(@list.length - 1)).must_equal 9
+ expect(@list.find_max).must_equal 9
+ expect(@list.find_min).must_equal 3
+ end
+
+ it "can delete from the middle" do
+ # Arrange
+ @list.add_last(9)
+ @list.add_last(10)
+ @list.add_first(4)
+ @list.add_first(3)
+ @list.add_first(2)
+
+ # Act
+ @list.delete(9)
+
+ # Assert
+ expect(@list.get_last).must_equal 10
+ expect(@list.length).must_equal 4
+ expect(@list.get_first).must_equal 2
+ end
+ end
+
+ xdescribe "Optional: nth_from_the_end" do
+ it 'returns nil if n is outside the bounds of the list' do
+ expect(@list.find_nth_from_end(3)).must_be_nil
+ end
+
+ it 'can retrieve an item at index n from the end in the list' do
+ @list.add_first(1)
+ @list.add_first(2)
+ @list.add_first(3)
+ @list.add_first(4)
+
+ expect(@list.find_nth_from_end(0)).must_equal 1
+ expect(@list.find_nth_from_end(1)).must_equal 2
+ expect(@list.find_nth_from_end(2)).must_equal 3
+ expect(@list.find_nth_from_end(3)).must_equal 4
+ expect(@list.find_nth_from_end(4)).must_be_nil
+ end
+ end
+
+ xdescribe "reverse" do
+ it 'can retrieve an item at index n from the end in the list' do
+ @list.add_first(4)
+ @list.add_first(3)
+ @list.add_first(2)
+ @list.add_first(1)
+ @list.reverse
+
+ expect(@list.get_at_index(0)).must_equal 4
+ expect(@list.get_at_index(1)).must_equal 3
+ expect(@list.get_at_index(2)).must_equal 2
+ expect(@list.get_at_index(3)).must_equal 1
end
+ end
end