├── .circleci
└── config.yml
├── .gitignore
├── LICENSE
├── README.md
├── docs
├── LinkedList.html
├── LinkedList
│ └── Node.html
├── css
│ └── style.css
├── index.html
├── index.json
├── js
│ └── doc.js
└── search-index.js
├── shard.lock
├── shard.yml
├── spec
├── linked_list_spec.cr
└── spec_helper.cr
└── src
├── linked_list.cr
└── linked_list_benchmark.cr
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | version: 2 # use CircleCI 2.0
2 | jobs: # a collection of jobs
3 | build:
4 | docker: # run build steps with docker
5 | - image: crystallang/crystal:0.33.0 # primary docker container; all `steps` will run here.
6 | steps: # a collection of executable steps
7 | - checkout # checks out source code to working directory
8 | - restore_cache: # Restore dependency cache
9 | # Read about caching dependencies: https://circleci.com/docs/2.0/caching/
10 | key: dependency-cache-{{ checksum "shard.lock" }}
11 | - run:
12 | name: Install dependencies.
13 | command: shards install
14 | - save_cache: # Step to save dependency cache
15 | key: dependency-cache-{{ checksum "shard.lock" }}
16 | paths:
17 | - ./lib
18 | - run:
19 | name: test
20 | command: crystal spec
21 | # See https://circleci.com/docs/2.0/deployment-integrations/ for deploy exampl
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | bin
2 | lib
3 | linked_list
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 abvdasker
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Crystal Linked List [](https://circleci.com/gh/abvdasker/crystal-linked-list)
2 |
3 | A simple linked list implementation in Crystal
4 |
5 | ## Installation
6 |
7 | Add this to a project's `shards.yml`
8 |
9 | ```yml
10 | dependencies:
11 | linked_list:
12 | git: https://github.com/abvdasker/crystal-linked-list.git
13 | ```
14 |
15 | Then run `shards`
16 |
17 | ## Usage
18 |
19 | ```crystal
20 | require "linked_list"
21 |
22 | list = LinkedList(Int32 | String).new
23 | list.append(1)
24 | list.push(2)
25 | list << "foo"
26 |
27 | list.peek # "foo"
28 | list.pop # "foo"
29 | list.pop # 2
30 | list.unshift(1)
31 | list.shift # 1
32 | ```
33 |
--------------------------------------------------------------------------------
/docs/LinkedList.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
A linked list is a Enumerable (see the Enumerable module) data structure
76 | that stores multiple pieces of data in non contiguous locations in memory.
77 |
78 |
To create a linked list:
79 |
80 |
list =LinkedList(Int32).new
81 | list.push(2)
82 | puts list.pop
90 |
91 |
92 |
--------------------------------------------------------------------------------
/docs/index.json:
--------------------------------------------------------------------------------
1 | {"repository_name":"github.com/reduced-reptile/crystal-linked-list","body":"# Crystal Linked List [](https://circleci.com/gh/abvdasker/crystal-linked-list)\n\nA simple linked list implementation in Crystal\n\n## Installation\n\nAdd this to a project's `shards.yml`\n\n```yml\ndependencies:\n linked_list:\n git: https://github.com/abvdasker/linked_list.git\n```\n\nThen run `crystal deps`\n\n## Usage\n\n```crystal\nrequire \"linked_list\"\n\nlist = LinkedList(Int32 | String).new\nlist.append(1)\nlist.push(2)\nlist << \"foo\"\n\nlist.peek # \"foo\"\nlist.pop # \"foo\"\nlist.pop # 2\nlist.unshift(1)\nlist.shift # 1\n```\n","program":{"html_id":"github.com/reduced-reptile/crystal-linked-list/toplevel","path":"toplevel.html","kind":"module","full_name":"Top Level Namespace","name":"Top Level Namespace","abstract":false,"superclass":null,"ancestors":[],"locations":[],"repository_name":"github.com/reduced-reptile/crystal-linked-list","program":true,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":null,"doc":null,"summary":null,"class_methods":[],"constructors":[],"instance_methods":[],"macros":[],"types":[{"html_id":"github.com/reduced-reptile/crystal-linked-list/LinkedList","path":"LinkedList.html","kind":"class","full_name":"LinkedList(A)","name":"LinkedList","abstract":false,"superclass":{"html_id":"github.com/reduced-reptile/crystal-linked-list/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"github.com/reduced-reptile/crystal-linked-list/Enumerable","kind":"module","full_name":"Enumerable","name":"Enumerable"},{"html_id":"github.com/reduced-reptile/crystal-linked-list/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"github.com/reduced-reptile/crystal-linked-list/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"linked_list.cr","line_number":17,"url":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr"}],"repository_name":"github.com/reduced-reptile/crystal-linked-list","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[{"html_id":"github.com/reduced-reptile/crystal-linked-list/Enumerable","kind":"module","full_name":"Enumerable","name":"Enumerable"}],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":null,"doc":"A linked list is a **Enumerable** (see the `Enumerable` module) data structure\nthat stores multiple pieces of data in non contiguous locations in memory.\n\nTo create a linked list:\n\n```\nlist = LinkedList(Int32).new\nlist.push(2)\nputs list.pop\n```\n\nThe above produces:\n\n```text\n2\n```","summary":"
A linked list is a Enumerable (see the Enumerable module) data structure that stores multiple pieces of data in non contiguous locations in memory.
","class_methods":[],"constructors":[{"id":"new(values:Enumerable(A))-class-method","html_id":"new(values:Enumerable(A))-class-method","name":"new","doc":"Creates a linked list with the *values* as the values of the nodes.","summary":"
Creates a linked list with the values as the values of the nodes.
","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L21","def":{"name":"new","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = LinkedList(A).allocate\n_.initialize\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"id":"new(*values)-class-method","html_id":"new(*values)-class-method","name":"new","doc":"Creates a linked list with the *values* as the values of the nodes.","summary":"
Creates a linked list with the values as the values of the nodes.
","abstract":false,"args":[{"name":"values","doc":null,"default_value":"","external_name":"values","restriction":""}],"args_string":"(*values)","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L27","def":{"name":"new","args":[{"name":"values","doc":null,"default_value":"","external_name":"values","restriction":""}],"double_splat":null,"splat_index":0,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = LinkedList(A).allocate\n_.initialize(*values)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"id":"+(list:Enumerable(C))forallC-instance-method","html_id":"+(list:Enumerable(C))forallC-instance-method","name":"+","doc":"Returns a new `LinkedList` with all of the elements from the first list\nfollowed by all of the elements in the second *list*.\n\n```\nfirst_list = LinkedList(Int32).new(1, 2)\nsecond_list = LinkedList(String).new(\"foo\", \"bar\")\ncombined_list = first_list + second_list\ncombined_list.peek() # => \"bar\"\ncombined_list.shift() # => 1\n```","summary":"
Returns a new LinkedList with all of the elements from the first list followed by all of the elements in the second list.
","abstract":false,"args":[{"name":"list","doc":null,"default_value":"","external_name":"list","restriction":"Enumerable(C)"}],"args_string":"(list : Enumerable(C)) forall C","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L191","def":{"name":"+","args":[{"name":"list","doc":null,"default_value":"","external_name":"list","restriction":"Enumerable(C)"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"LinkedList(A | C).new.tap do |new_list|\n each do |value|\n new_list.append(value)\n end\n list.each do |value|\n new_list.append(value)\n end\nend"}},{"id":"<<(value:A)-instance-method","html_id":"<<(value:A)-instance-method","name":"<<","doc":"Override the << (shift) operator to add a *value* to the end of a\nlinked list. This method returns itself so it can be chained.\n\n```\nlist = LinkedList(Int32).new(1)\nlist << 2 << 3\nlist.pop() # => 3\nlist.pop() # => 2\nlist.pop() # => 1\n```","summary":"
Override the << (shift) operator to add a value to the end of a linked list.
","abstract":false,"args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":"A"}],"args_string":"(value : A)","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L71","def":{"name":"<<","args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":"A"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"append(value)\nself\n"}},{"id":"append(value:A)-instance-method","html_id":"append(value:A)-instance-method","name":"append","doc":"Adds a *value* to the end of a linked list.\n\n```\nlist = LinkedList(Int32).new\nlist.append(1)\nlist.push(2)\nlist.pop() # => 2\nlist.pop() # => 1\n```","summary":"
Adds a value to the end of a linked list.
","abstract":false,"args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":"A"}],"args_string":"(value : A)","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L49","def":{"name":"append","args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":"A"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"new_node = Node(A).new(value)\n@tail.next = new_node\n@tail = new_node\nnew_node.value\n"}},{"id":"append(*values)-instance-method","html_id":"append(*values)-instance-method","name":"append","doc":"Adds a list of *values* to the end of a linked list.\n\n```\nlist = LinkedList(Int32 | String).new\nlist.append(1, \"foo\")\nlist.pop() # => \"foo\"\nlist.pop() # => 1\n```","summary":"
Adds a list of values to the end of a linked list.
","abstract":false,"args":[{"name":"values","doc":null,"default_value":"","external_name":"values","restriction":""}],"args_string":"(*values)","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L84","def":{"name":"append","args":[{"name":"values","doc":null,"default_value":"","external_name":"values","restriction":""}],"double_splat":null,"splat_index":0,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"values.each do |value|\n append(value)\nend"}},{"id":"concat(list:LinkedList(A))-instance-method","html_id":"concat(list:LinkedList(A))-instance-method","name":"concat","doc":"Adds all the elemenets of the *list* to the end of the current linked list.\n\n```\nfirst_list = LinkedList(Int32).new(1, 2)\nsecond_list = LinkedList(Int32).new(3, 4)\ncombined_list = first_list.concat(second_list)\ncombined_list.peek() # => 4\ncombined_list.shift() # => 1\n```","summary":"
Adds all the elemenets of the list to the end of the current linked list.
","abstract":false,"args":[{"name":"list","doc":null,"default_value":"","external_name":"list","restriction":"LinkedList(A)"}],"args_string":"(list : LinkedList(A))","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L211","def":{"name":"concat","args":[{"name":"list","doc":null,"default_value":"","external_name":"list","restriction":"LinkedList(A)"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@tail.next = list.head.next\n@tail = list.tail\nself\n"}},{"id":"each(&block)-instance-method","html_id":"each(&block)-instance-method","name":"each","doc":"Iterates over all the values in the linked list.\n\n```\nvalues = [1, 2, 3]\nlist = LinkedList(Int32).new(values)\nlist.each do |elem|\n puts elem\nend\n\nThe above produces:\n\n```text\n1\n2\n3\n```","summary":"
Iterates over all the values in the linked list.
","abstract":false,"args":[],"args_string":"(&block)","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L174","def":{"name":"each","args":[],"double_splat":null,"splat_index":null,"yields":1,"block_arg":null,"return_type":"","visibility":"Public","body":"each_node do |node|\n yield node.value\nend\nself\n"}},{"id":"empty?-instance-method","html_id":"empty?-instance-method","name":"empty?","doc":"Returns true if and only if there are no elements in the list.\n\n```\nlist = LinkedList(Int32).new\nlist.empty? # => true\nlist.push(1)\nlist.empty? # => false\n```","summary":"
Returns true if and only if there are no elements in the list.
","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L225","def":{"name":"empty?","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@head == @tail"}},{"id":"peek-instance-method","html_id":"peek-instance-method","name":"peek","doc":"Returns the value of the tail of the linked list,\nor nil if no value was supplied.\n\n```\nlist = LinkedList(Float64).new(1.23)\nlist.push(4.56)\nlist.peek() # => 4.56\n```","summary":"
Returns the value of the tail of the linked list, or nil if no value was supplied.
","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L132","def":{"name":"peek","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@tail.value"}},{"id":"pop-instance-method","html_id":"pop-instance-method","name":"pop","doc":"Returns the last `Node` from the list and removes it.\n\n```\nlist = LinkedList(Float64).new(1.23)\nlist.push(4.56)\nlist.pop() # => 4.56\nlist.peek() # => 1.23\n```","summary":"
Returns the last Node from the list and removes it.
","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L144","def":{"name":"pop","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"if @head == @tail\n return nil\nend\nlast = @tail\ncurrent = @head\nwhile current.next != last\n current = current.next.not_nil!\nend\ncurrent.next = nil\n@tail = current\nlast.value\n"}},{"id":"push(value:A)-instance-method","html_id":"push(value:A)-instance-method","name":"push","doc":"Adds a *value* to the end of a linked list.\n\n```\nlist = LinkedList(Int32).new\nlist.append(1)\nlist.push(2)\nlist.pop() # => 2\nlist.pop() # => 1\n```","summary":"
Adds a value to the end of a linked list.
","abstract":false,"args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":"A"}],"args_string":"(value : A)","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L57","def":{"name":"push","args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":"A"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"append(value)"}},{"id":"reverse-instance-method","html_id":"reverse-instance-method","name":"reverse","doc":"Creates a copy of the `LinkedList` with the order reversed.\n\n```\nlist = LinkedList(Int32).new(1, 2, 3)\nreversed_list = list.reverse\nlist.pop() # => 1\nlist.pop() # => 2\nlist.pop() # => 3\n```","summary":"
Creates a copy of the LinkedList with the order reversed.
","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L238","def":{"name":"reverse","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"LinkedList(A).new.tap do |new_list|\n each do |value|\n new_list.unshift(value.not_nil!)\n end\nend"}},{"id":"shift-instance-method","html_id":"shift-instance-method","name":"shift","doc":"Returns the first `Node` from the list and removes it.\n\n```\nlist = LinkedList(Float64).new(1.23)\nlist.push(4.56)\nlist.shift() # => 1.23\nlist.peek() # => 4.56\n```","summary":"
Returns the first Node from the list and removes it.
","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L116","def":{"name":"shift","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"if @head.next.nil?\n return\nend\nfirst = @head.next.not_nil!\n@head.next = first.next\nfirst.value\n"}},{"id":"unshift(value:A)-instance-method","html_id":"unshift(value:A)-instance-method","name":"unshift","doc":"Adds a *value* to the beginning of a linked list.\n\n```\nlist = LinkedList(Int32).new(1)\nlist.unshift(2)\nlist.pop() # => 1\nlist.pop() # => 2\n```","summary":"
Adds a value to the beginning of a linked list.
","abstract":false,"args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":"A"}],"args_string":"(value : A)","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L98","def":{"name":"unshift","args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":"A"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"new_top = Node(A).new(value)\nif @tail == @head\n @tail = new_top\nend\nnew_top.next = @head.next\n@head.next = new_top\nnew_top.value\n"}}],"macros":[],"types":[{"html_id":"github.com/reduced-reptile/crystal-linked-list/LinkedList/Node","path":"LinkedList/Node.html","kind":"class","full_name":"LinkedList::Node(T)","name":"Node","abstract":false,"superclass":{"html_id":"github.com/reduced-reptile/crystal-linked-list/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"github.com/reduced-reptile/crystal-linked-list/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"github.com/reduced-reptile/crystal-linked-list/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"linked_list.cr","line_number":308,"url":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr"}],"repository_name":"github.com/reduced-reptile/crystal-linked-list","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/reduced-reptile/crystal-linked-list/LinkedList","kind":"class","full_name":"LinkedList(A)","name":"LinkedList"},"doc":"A node is the building block of linked lists consisting of a values\nand a pointer to the next node in the linked list.\n\nTo create a node:\n\n```\nnode = Node.new(5)\nputs node.value\n```\n\nThe above produces:\n\n```text\n5\n```\n\nCheck the value of the node with `#value`.\nGet the next node in the list with `#next`.","summary":"
A node is the building block of linked lists consisting of a values and a pointer to the next node in the linked list.
","class_methods":[],"constructors":[{"id":"new(value:T)-class-method","html_id":"new(value:T)-class-method","name":"new","doc":"Creates a node with the specified *value*.","summary":"
Creates a node with the specified value.
","abstract":false,"args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":"T"}],"args_string":"(value : T)","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L317","def":{"name":"new","args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":"T"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = Node(T).allocate\n_.initialize(value)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"id":"new-class-method","html_id":"new-class-method","name":"new","doc":"Creates a node with no value.","summary":"
Creates a node with no value.
","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L313","def":{"name":"new","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = Node(T).allocate\n_.initialize\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"id":"next-instance-method","html_id":"next-instance-method","name":"next","doc":"Returns the next node in the linked list, or nil if it is the tail.\n\n```\nnode = Node.new(1)\nnode.next = Node.new(2)\nnode.next.value # => 2\n```","summary":"
Returns the next node in the linked list, or nil if it is the tail.
","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L336","def":{"name":"next","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@next"}},{"id":"next=(next_node:LinkedList::Node(T)?)-instance-method","html_id":"next=(next_node:LinkedList::Node(T)?)-instance-method","name":"next=","doc":"Sets the next node in the linked list to *next_node*\n\n```\nnode = Node.new(1)\nnode.next = Node.new(2)\nnode.next.value # => 2\n```","summary":"
Sets the next node in the linked list to next_node
","abstract":false,"args":[{"name":"next_node","doc":null,"default_value":"","external_name":"next_node","restriction":"Node(T) | Nil"}],"args_string":"(next_node : LinkedList::Node(T)?)","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L347","def":{"name":"next=","args":[{"name":"next_node","doc":null,"default_value":"","external_name":"next_node","restriction":"Node(T) | Nil"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@next = next_node"}},{"id":"value-instance-method","html_id":"value-instance-method","name":"value","doc":"Returns the value of the node, or nil if no value was supplied\n\n```\nNode.new(1).value # => 1\n```","summary":"
Returns the value of the node, or nil if no value was supplied
'
974 | );
975 |
976 | function handleShortkeys(event) {
977 | var element = event.target || event.srcElement;
978 |
979 | if(element.tagName == "INPUT" || element.tagName == "TEXTAREA" || element.parentElement.tagName == "TEXTAREA"){
980 | return;
981 | }
982 |
983 | switch(event.key) {
984 | case "?":
985 | usageModal.show();
986 | break;
987 |
988 | case "Escape":
989 | usageModal.hide();
990 | break;
991 |
992 | case "s":
993 | case "/":
994 | if(usageModal.isVisible()) {
995 | return;
996 | }
997 | event.stopPropagation();
998 | navigator.focus();
999 | performSearch();
1000 | break;
1001 | }
1002 | }
1003 |
1004 | document.addEventListener('keyup', handleShortkeys);
1005 |
1006 | var scrollToEntryFromLocationHash = function() {
1007 | var hash = window.location.hash;
1008 | if (hash) {
1009 | var targetAnchor = unescape(hash.substr(1));
1010 | var targetEl = document.querySelectorAll('.entry-detail[id="' + targetAnchor + '"]');
1011 |
1012 | if (targetEl && targetEl.length > 0) {
1013 | targetEl[0].offsetParent.scrollTop = targetEl[0].offsetTop;
1014 | }
1015 | }
1016 | };
1017 | window.addEventListener("hashchange", scrollToEntryFromLocationHash, false);
1018 | scrollToEntryFromLocationHash();
1019 | });
1020 |
--------------------------------------------------------------------------------
/docs/search-index.js:
--------------------------------------------------------------------------------
1 | crystal_doc_search_index_callback({"repository_name":"github.com/reduced-reptile/crystal-linked-list","body":"# Crystal Linked List [](https://circleci.com/gh/abvdasker/crystal-linked-list)\n\nA simple linked list implementation in Crystal\n\n## Installation\n\nAdd this to a project's `shards.yml`\n\n```yml\ndependencies:\n linked_list:\n git: https://github.com/abvdasker/linked_list.git\n```\n\nThen run `crystal deps`\n\n## Usage\n\n```crystal\nrequire \"linked_list\"\n\nlist = LinkedList(Int32 | String).new\nlist.append(1)\nlist.push(2)\nlist << \"foo\"\n\nlist.peek # \"foo\"\nlist.pop # \"foo\"\nlist.pop # 2\nlist.unshift(1)\nlist.shift # 1\n```\n","program":{"html_id":"github.com/reduced-reptile/crystal-linked-list/toplevel","path":"toplevel.html","kind":"module","full_name":"Top Level Namespace","name":"Top Level Namespace","abstract":false,"superclass":null,"ancestors":[],"locations":[],"repository_name":"github.com/reduced-reptile/crystal-linked-list","program":true,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":null,"doc":null,"summary":null,"class_methods":[],"constructors":[],"instance_methods":[],"macros":[],"types":[{"html_id":"github.com/reduced-reptile/crystal-linked-list/LinkedList","path":"LinkedList.html","kind":"class","full_name":"LinkedList(A)","name":"LinkedList","abstract":false,"superclass":{"html_id":"github.com/reduced-reptile/crystal-linked-list/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"github.com/reduced-reptile/crystal-linked-list/Enumerable","kind":"module","full_name":"Enumerable","name":"Enumerable"},{"html_id":"github.com/reduced-reptile/crystal-linked-list/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"github.com/reduced-reptile/crystal-linked-list/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"linked_list.cr","line_number":17,"url":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr"}],"repository_name":"github.com/reduced-reptile/crystal-linked-list","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[{"html_id":"github.com/reduced-reptile/crystal-linked-list/Enumerable","kind":"module","full_name":"Enumerable","name":"Enumerable"}],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":null,"doc":"A linked list is a **Enumerable** (see the `Enumerable` module) data structure\nthat stores multiple pieces of data in non contiguous locations in memory.\n\nTo create a linked list:\n\n```\nlist = LinkedList(Int32).new\nlist.push(2)\nputs list.pop\n```\n\nThe above produces:\n\n```text\n2\n```","summary":"
A linked list is a Enumerable (see the Enumerable module) data structure that stores multiple pieces of data in non contiguous locations in memory.
","class_methods":[],"constructors":[{"id":"new(values:Enumerable(A))-class-method","html_id":"new(values:Enumerable(A))-class-method","name":"new","doc":"Creates a linked list with the *values* as the values of the nodes.","summary":"
Creates a linked list with the values as the values of the nodes.
","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L21","def":{"name":"new","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = LinkedList(A).allocate\n_.initialize\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"id":"new(*values)-class-method","html_id":"new(*values)-class-method","name":"new","doc":"Creates a linked list with the *values* as the values of the nodes.","summary":"
Creates a linked list with the values as the values of the nodes.
","abstract":false,"args":[{"name":"values","doc":null,"default_value":"","external_name":"values","restriction":""}],"args_string":"(*values)","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L27","def":{"name":"new","args":[{"name":"values","doc":null,"default_value":"","external_name":"values","restriction":""}],"double_splat":null,"splat_index":0,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = LinkedList(A).allocate\n_.initialize(*values)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"id":"+(list:Enumerable(C))forallC-instance-method","html_id":"+(list:Enumerable(C))forallC-instance-method","name":"+","doc":"Returns a new `LinkedList` with all of the elements from the first list\nfollowed by all of the elements in the second *list*.\n\n```\nfirst_list = LinkedList(Int32).new(1, 2)\nsecond_list = LinkedList(String).new(\"foo\", \"bar\")\ncombined_list = first_list + second_list\ncombined_list.peek() # => \"bar\"\ncombined_list.shift() # => 1\n```","summary":"
Returns a new LinkedList with all of the elements from the first list followed by all of the elements in the second list.
","abstract":false,"args":[{"name":"list","doc":null,"default_value":"","external_name":"list","restriction":"Enumerable(C)"}],"args_string":"(list : Enumerable(C)) forall C","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L191","def":{"name":"+","args":[{"name":"list","doc":null,"default_value":"","external_name":"list","restriction":"Enumerable(C)"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"LinkedList(A | C).new.tap do |new_list|\n each do |value|\n new_list.append(value)\n end\n list.each do |value|\n new_list.append(value)\n end\nend"}},{"id":"<<(value:A)-instance-method","html_id":"<<(value:A)-instance-method","name":"<<","doc":"Override the << (shift) operator to add a *value* to the end of a\nlinked list. This method returns itself so it can be chained.\n\n```\nlist = LinkedList(Int32).new(1)\nlist << 2 << 3\nlist.pop() # => 3\nlist.pop() # => 2\nlist.pop() # => 1\n```","summary":"
Override the << (shift) operator to add a value to the end of a linked list.
","abstract":false,"args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":"A"}],"args_string":"(value : A)","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L71","def":{"name":"<<","args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":"A"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"append(value)\nself\n"}},{"id":"append(value:A)-instance-method","html_id":"append(value:A)-instance-method","name":"append","doc":"Adds a *value* to the end of a linked list.\n\n```\nlist = LinkedList(Int32).new\nlist.append(1)\nlist.push(2)\nlist.pop() # => 2\nlist.pop() # => 1\n```","summary":"
Adds a value to the end of a linked list.
","abstract":false,"args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":"A"}],"args_string":"(value : A)","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L49","def":{"name":"append","args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":"A"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"new_node = Node(A).new(value)\n@tail.next = new_node\n@tail = new_node\nnew_node.value\n"}},{"id":"append(*values)-instance-method","html_id":"append(*values)-instance-method","name":"append","doc":"Adds a list of *values* to the end of a linked list.\n\n```\nlist = LinkedList(Int32 | String).new\nlist.append(1, \"foo\")\nlist.pop() # => \"foo\"\nlist.pop() # => 1\n```","summary":"
Adds a list of values to the end of a linked list.
","abstract":false,"args":[{"name":"values","doc":null,"default_value":"","external_name":"values","restriction":""}],"args_string":"(*values)","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L84","def":{"name":"append","args":[{"name":"values","doc":null,"default_value":"","external_name":"values","restriction":""}],"double_splat":null,"splat_index":0,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"values.each do |value|\n append(value)\nend"}},{"id":"concat(list:LinkedList(A))-instance-method","html_id":"concat(list:LinkedList(A))-instance-method","name":"concat","doc":"Adds all the elemenets of the *list* to the end of the current linked list.\n\n```\nfirst_list = LinkedList(Int32).new(1, 2)\nsecond_list = LinkedList(Int32).new(3, 4)\ncombined_list = first_list.concat(second_list)\ncombined_list.peek() # => 4\ncombined_list.shift() # => 1\n```","summary":"
Adds all the elemenets of the list to the end of the current linked list.
","abstract":false,"args":[{"name":"list","doc":null,"default_value":"","external_name":"list","restriction":"LinkedList(A)"}],"args_string":"(list : LinkedList(A))","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L211","def":{"name":"concat","args":[{"name":"list","doc":null,"default_value":"","external_name":"list","restriction":"LinkedList(A)"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@tail.next = list.head.next\n@tail = list.tail\nself\n"}},{"id":"each(&block)-instance-method","html_id":"each(&block)-instance-method","name":"each","doc":"Iterates over all the values in the linked list.\n\n```\nvalues = [1, 2, 3]\nlist = LinkedList(Int32).new(values)\nlist.each do |elem|\n puts elem\nend\n\nThe above produces:\n\n```text\n1\n2\n3\n```","summary":"
Iterates over all the values in the linked list.
","abstract":false,"args":[],"args_string":"(&block)","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L174","def":{"name":"each","args":[],"double_splat":null,"splat_index":null,"yields":1,"block_arg":null,"return_type":"","visibility":"Public","body":"each_node do |node|\n yield node.value\nend\nself\n"}},{"id":"empty?-instance-method","html_id":"empty?-instance-method","name":"empty?","doc":"Returns true if and only if there are no elements in the list.\n\n```\nlist = LinkedList(Int32).new\nlist.empty? # => true\nlist.push(1)\nlist.empty? # => false\n```","summary":"
Returns true if and only if there are no elements in the list.
","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L225","def":{"name":"empty?","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@head == @tail"}},{"id":"peek-instance-method","html_id":"peek-instance-method","name":"peek","doc":"Returns the value of the tail of the linked list,\nor nil if no value was supplied.\n\n```\nlist = LinkedList(Float64).new(1.23)\nlist.push(4.56)\nlist.peek() # => 4.56\n```","summary":"
Returns the value of the tail of the linked list, or nil if no value was supplied.
","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L132","def":{"name":"peek","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@tail.value"}},{"id":"pop-instance-method","html_id":"pop-instance-method","name":"pop","doc":"Returns the last `Node` from the list and removes it.\n\n```\nlist = LinkedList(Float64).new(1.23)\nlist.push(4.56)\nlist.pop() # => 4.56\nlist.peek() # => 1.23\n```","summary":"
Returns the last Node from the list and removes it.
","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L144","def":{"name":"pop","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"if @head == @tail\n return nil\nend\nlast = @tail\ncurrent = @head\nwhile current.next != last\n current = current.next.not_nil!\nend\ncurrent.next = nil\n@tail = current\nlast.value\n"}},{"id":"push(value:A)-instance-method","html_id":"push(value:A)-instance-method","name":"push","doc":"Adds a *value* to the end of a linked list.\n\n```\nlist = LinkedList(Int32).new\nlist.append(1)\nlist.push(2)\nlist.pop() # => 2\nlist.pop() # => 1\n```","summary":"
Adds a value to the end of a linked list.
","abstract":false,"args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":"A"}],"args_string":"(value : A)","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L57","def":{"name":"push","args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":"A"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"append(value)"}},{"id":"reverse-instance-method","html_id":"reverse-instance-method","name":"reverse","doc":"Creates a copy of the `LinkedList` with the order reversed.\n\n```\nlist = LinkedList(Int32).new(1, 2, 3)\nreversed_list = list.reverse\nlist.pop() # => 1\nlist.pop() # => 2\nlist.pop() # => 3\n```","summary":"
Creates a copy of the LinkedList with the order reversed.
","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L238","def":{"name":"reverse","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"LinkedList(A).new.tap do |new_list|\n each do |value|\n new_list.unshift(value.not_nil!)\n end\nend"}},{"id":"shift-instance-method","html_id":"shift-instance-method","name":"shift","doc":"Returns the first `Node` from the list and removes it.\n\n```\nlist = LinkedList(Float64).new(1.23)\nlist.push(4.56)\nlist.shift() # => 1.23\nlist.peek() # => 4.56\n```","summary":"
Returns the first Node from the list and removes it.
","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L116","def":{"name":"shift","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"if @head.next.nil?\n return\nend\nfirst = @head.next.not_nil!\n@head.next = first.next\nfirst.value\n"}},{"id":"unshift(value:A)-instance-method","html_id":"unshift(value:A)-instance-method","name":"unshift","doc":"Adds a *value* to the beginning of a linked list.\n\n```\nlist = LinkedList(Int32).new(1)\nlist.unshift(2)\nlist.pop() # => 1\nlist.pop() # => 2\n```","summary":"
Adds a value to the beginning of a linked list.
","abstract":false,"args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":"A"}],"args_string":"(value : A)","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L98","def":{"name":"unshift","args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":"A"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"new_top = Node(A).new(value)\nif @tail == @head\n @tail = new_top\nend\nnew_top.next = @head.next\n@head.next = new_top\nnew_top.value\n"}}],"macros":[],"types":[{"html_id":"github.com/reduced-reptile/crystal-linked-list/LinkedList/Node","path":"LinkedList/Node.html","kind":"class","full_name":"LinkedList::Node(T)","name":"Node","abstract":false,"superclass":{"html_id":"github.com/reduced-reptile/crystal-linked-list/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"github.com/reduced-reptile/crystal-linked-list/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"github.com/reduced-reptile/crystal-linked-list/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"linked_list.cr","line_number":308,"url":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr"}],"repository_name":"github.com/reduced-reptile/crystal-linked-list","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/reduced-reptile/crystal-linked-list/LinkedList","kind":"class","full_name":"LinkedList(A)","name":"LinkedList"},"doc":"A node is the building block of linked lists consisting of a values\nand a pointer to the next node in the linked list.\n\nTo create a node:\n\n```\nnode = Node.new(5)\nputs node.value\n```\n\nThe above produces:\n\n```text\n5\n```\n\nCheck the value of the node with `#value`.\nGet the next node in the list with `#next`.","summary":"
A node is the building block of linked lists consisting of a values and a pointer to the next node in the linked list.
","class_methods":[],"constructors":[{"id":"new(value:T)-class-method","html_id":"new(value:T)-class-method","name":"new","doc":"Creates a node with the specified *value*.","summary":"
Creates a node with the specified value.
","abstract":false,"args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":"T"}],"args_string":"(value : T)","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L317","def":{"name":"new","args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":"T"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = Node(T).allocate\n_.initialize(value)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"id":"new-class-method","html_id":"new-class-method","name":"new","doc":"Creates a node with no value.","summary":"
Creates a node with no value.
","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L313","def":{"name":"new","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = Node(T).allocate\n_.initialize\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"id":"next-instance-method","html_id":"next-instance-method","name":"next","doc":"Returns the next node in the linked list, or nil if it is the tail.\n\n```\nnode = Node.new(1)\nnode.next = Node.new(2)\nnode.next.value # => 2\n```","summary":"
Returns the next node in the linked list, or nil if it is the tail.
","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L336","def":{"name":"next","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@next"}},{"id":"next=(next_node:LinkedList::Node(T)?)-instance-method","html_id":"next=(next_node:LinkedList::Node(T)?)-instance-method","name":"next=","doc":"Sets the next node in the linked list to *next_node*\n\n```\nnode = Node.new(1)\nnode.next = Node.new(2)\nnode.next.value # => 2\n```","summary":"
Sets the next node in the linked list to next_node
","abstract":false,"args":[{"name":"next_node","doc":null,"default_value":"","external_name":"next_node","restriction":"Node(T) | Nil"}],"args_string":"(next_node : LinkedList::Node(T)?)","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L347","def":{"name":"next=","args":[{"name":"next_node","doc":null,"default_value":"","external_name":"next_node","restriction":"Node(T) | Nil"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@next = next_node"}},{"id":"value-instance-method","html_id":"value-instance-method","name":"value","doc":"Returns the value of the node, or nil if no value was supplied\n\n```\nNode.new(1).value # => 1\n```","summary":"
Returns the value of the node, or nil if no value was supplied
","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/reduced-reptile/crystal-linked-list/blob/ab6f247b4f63ae12cc36090dcab55597b4d0b88a/src/linked_list.cr#L325","def":{"name":"value","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@value"}}],"macros":[],"types":[]}]}]}})
--------------------------------------------------------------------------------
/shard.lock:
--------------------------------------------------------------------------------
1 | version: 1.0
2 | shards:
3 | ameba:
4 | github: crystal-ameba/ameba
5 | version: 0.11.0
6 |
7 |
--------------------------------------------------------------------------------
/shard.yml:
--------------------------------------------------------------------------------
1 | name: linked_list
2 | version: 0.2.0
3 |
4 | crystal: 0.21.1
5 | license: MIT
6 |
7 | authors:
8 | - abvdasker
9 |
10 | development_dependencies:
11 | ameba:
12 | github: crystal-ameba/ameba
13 | version: ~> 0.11.0
14 |
15 | targets:
16 | linked_list:
17 | main: src/linked_list.cr
18 | linked_list_benchmark:
19 | main: src/linked_list_benchmark.cr
20 |
21 | description: Simple linked list implementation
--------------------------------------------------------------------------------
/spec/linked_list_spec.cr:
--------------------------------------------------------------------------------
1 | require "./spec_helper"
2 |
3 | describe LinkedList do
4 | describe "#initialize" do
5 | it "initializes the list" do
6 | list = LinkedList(Nil).new
7 | list.size.should eq 0
8 | end
9 |
10 | it "initializes the list with the given values" do
11 | list = LinkedList(Nil | Int32 | String).new(1, 13, "foo")
12 |
13 | list_array = list.to_a
14 | list_array[0].should eq 1
15 | list_array[1].should eq 13
16 | list_array[2].should eq "foo"
17 | end
18 | end
19 |
20 | describe "#size" do
21 | it "returns 0 when the list is newly initialized" do
22 | list = LinkedList(Nil).new
23 | list.size.should eq 0
24 | end
25 |
26 | it "returns 1 when the list is newly initialized with a single value" do
27 | list = LinkedList(Int32).new(1)
28 | list.size.should eq 1
29 | end
30 | end
31 |
32 | describe "#append" do
33 | it "increases the size of the list by 1" do
34 | list = LinkedList(Nil).new(nil)
35 |
36 | list.append(nil)
37 |
38 | list.peek.should eq nil
39 | list.size.should eq 2
40 | end
41 |
42 | it "appends multiple elements to the list" do
43 | list = LinkedList(Int32 | String).new
44 |
45 | list.append(1, "foo")
46 |
47 | list.peek.should eq "foo"
48 | list.size.should eq 2
49 | end
50 | end
51 |
52 | describe "#push" do
53 | it "increases the size of the list by 1" do
54 | list = LinkedList(Nil).new(nil)
55 |
56 | list.push(nil)
57 |
58 | list.peek.should eq nil
59 | list.size.should eq 2
60 | end
61 |
62 | it "adds the element to the end of the list" do
63 | list = LinkedList(Int32).new(1)
64 | list.peek.should eq 1
65 |
66 | list.push(2)
67 |
68 | list.peek.should eq 2
69 | list.size.should eq 2
70 | end
71 |
72 | it "push multiple elements to the list" do
73 | list = LinkedList(Int32).new
74 | list.peek.should eq nil
75 |
76 | list.push(1, 2)
77 |
78 | list.peek.should eq 2
79 | list.size.should eq 2
80 | end
81 | end
82 |
83 | describe "#insert_at" do
84 | it "insert into an empty list at index 0" do
85 | list = LinkedList(Int32).new
86 | list.insert_at(1, 0)
87 |
88 | list.size.should eq 1
89 |
90 | list[0].should eq 1
91 | end
92 |
93 | it "insert fails if not contiguous" do
94 | list = LinkedList(Int32).new
95 | list.insert_at(1, 1)
96 | list.size.should eq 0
97 | end
98 |
99 | it "insert into a populated list at index 0 ( unshift )" do
100 | list = LinkedList(Int32).new(1, 2)
101 | list.insert_at(3, 0)
102 |
103 | list.size.should eq 3
104 |
105 | list[0].should eq 3
106 | list[1].should eq 1
107 | list[2].should eq 2
108 | end
109 |
110 | it "insert into a populated list at index n" do
111 | list = LinkedList(Int32).new(1, 2)
112 | list.insert_at(3, 1)
113 |
114 | list.size.should eq 3
115 |
116 | list[0].should eq 1
117 | list[1].should eq 3
118 | list[2].should eq 2
119 | end
120 | end
121 |
122 | describe "#insert_at" do
123 | it "insert into an empty list at index 0" do
124 | list = LinkedList(Int32).new
125 | list.insert_at(1, 0)
126 |
127 | list.size.should eq 1
128 |
129 | list_a = list.to_a
130 |
131 | list_a[0].should eq 1
132 | end
133 |
134 | it "insert fails if not contiguous" do
135 | list = LinkedList(Int32).new
136 | list.insert_at(1, 1)
137 | list.size.should eq 0
138 | end
139 |
140 | it "insert into a populated list at index 0 ( unshift )" do
141 | list = LinkedList(Int32).new(1, 2)
142 | list.insert_at(3, 0)
143 |
144 | list.size.should eq 3
145 |
146 | list_a = list.to_a
147 |
148 | list_a[0].should eq 3
149 | list_a[1].should eq 1
150 | list_a[2].should eq 2
151 | end
152 |
153 | it "insert into a populated list at index n" do
154 | list = LinkedList(Int32).new(1, 2)
155 | list.insert_at(3, 1)
156 |
157 | list.size.should eq 3
158 |
159 | list_a = list.to_a
160 |
161 | list_a[0].should eq 1
162 | list_a[1].should eq 3
163 | list_a[2].should eq 2
164 | end
165 | end
166 |
167 | describe "#<<" do
168 | it "increases the size of the list by 1" do
169 | list = LinkedList(Nil).new(nil)
170 | list << nil
171 |
172 | list.peek.should eq nil
173 | list.size.should eq 2
174 | end
175 |
176 | it "adds the element to the end of the list" do
177 | list = LinkedList(Int32).new(1)
178 | list << 2 << 3
179 |
180 | list.peek.should eq 3
181 | list.size.should eq 3
182 | end
183 | end
184 |
185 | describe "#peek" do
186 | it "returns nil when list is empty" do
187 | list = LinkedList(Int32).new
188 | list.peek.should eq nil
189 | list.size.should eq 0
190 | end
191 |
192 | it "returns the last element of the list without removing it" do
193 | list = LinkedList(Int32).new(100, 12)
194 | list.peek.should eq 12
195 | list.size.should eq 2
196 | end
197 | end
198 |
199 | describe "#pop" do
200 | it "returns nil when list is empty" do
201 | list = LinkedList(Int32).new
202 | list.pop.should eq nil
203 | list.size.should eq 0
204 | end
205 |
206 | it "returns the last element of the list and removes it" do
207 | list = LinkedList(Int32).new(100, 12)
208 | list.pop.should eq 12
209 | list.peek.should eq 100
210 | list.size.should eq 1
211 | end
212 |
213 | it "returns nil when the list is empty" do
214 | list = LinkedList(Int32).new(100)
215 | list.pop()
216 | list.size.should eq 0
217 | list.pop().should eq nil
218 | end
219 | end
220 |
221 | describe "#empty?" do
222 | it "returns true when there are no elements in the list" do
223 | list = LinkedList(Int32).new
224 |
225 | list.empty?.should be_true
226 | end
227 |
228 | it "returns false" do
229 | list = LinkedList(Int32).new(1, 2)
230 |
231 | list.empty?.should be_false
232 | end
233 |
234 | it "returns true when all elements have been removed from the list" do
235 | list = LinkedList(Int32).new(1, 2)
236 | list.empty?.should be_false
237 |
238 | list.pop()
239 | list.empty?.should be_false
240 |
241 | list.pop()
242 | list.empty?.should be_true
243 | end
244 | end
245 |
246 | describe "#unshift" do
247 | it "prepends an element to the list" do
248 | list = LinkedList(String).new
249 | list.size.should eq 0
250 | list.unshift("foo")
251 | list.size.should eq 1
252 | list.peek.should eq "foo"
253 | end
254 |
255 | it "prepends an element to the list multiple times" do
256 | list = LinkedList(String).new
257 | list.size.should eq 0
258 | list.unshift("foo")
259 | list.size.should eq 1
260 | list.unshift("bar")
261 | list.size.should eq 2
262 | list.peek.should eq "foo"
263 | end
264 |
265 | it "prepends an element to populated list" do
266 | list = LinkedList(String).new("blah")
267 | list.size.should eq 1
268 | list.unshift("foo")
269 | list.size.should eq 2
270 | list.unshift("bar")
271 | list.size.should eq 3
272 | list.peek.should eq "blah"
273 | end
274 | end
275 |
276 | describe "#shift" do
277 | it "returns nil when list is empty" do
278 | list = LinkedList(Float64).new
279 | list.shift.should eq nil
280 | end
281 |
282 | it "returns the first element from the list and removes it" do
283 | list = LinkedList(Float64).new(32.1)
284 | list.shift.should eq 32.1
285 | list.shift.should eq nil
286 | end
287 |
288 | it "returns the first element from the list and removes it, multiple values" do
289 | list = LinkedList(Float64).new(32.1, 64.2)
290 | list.shift.should eq 32.1
291 | list.shift.should eq 64.2
292 | list.shift.should eq nil
293 | end
294 | end
295 |
296 | describe "#index_operator" do
297 | it "get multiple elements via the index" do
298 | list = LinkedList(Int32).new
299 | list.append(1)
300 | list.append(2)
301 | list[0].should eq 1
302 | list[1].should eq 2
303 | end
304 | end
305 |
306 | describe "#to_a" do
307 | it "linked list converted into an array" do
308 | list = LinkedList(Int32).new(1, 2)
309 |
310 | list_a = list.to_a
311 |
312 | list_a[0] = 1
313 | list_a[1] = 2
314 | end
315 | end
316 |
317 | describe "#+" do
318 | it "concatenates two lists and returns a new list" do
319 | first_list = LinkedList(Int32).new(1, 2)
320 | second_list = LinkedList(String).new("foo", "bar")
321 |
322 | result = first_list + second_list
323 | result.size.should eq 4
324 |
325 | result_array = result.to_a
326 |
327 | result_array[0].should eq 1
328 | result_array[1].should eq 2
329 | result_array[-1].should eq "bar"
330 | result_array[-2].should eq "foo"
331 | end
332 |
333 | it "concatenates an array with a list and retuns a new list" do
334 | first_list = LinkedList(Int32).new(1, 2)
335 | array = ["foo", "bar"]
336 |
337 | result = first_list + array
338 | result.size.should eq 4
339 |
340 | result[0].should eq 1
341 | result[1].should eq 2
342 | result[2].should eq "foo"
343 | result[3].should eq "bar"
344 | end
345 | end
346 |
347 | describe "#concat" do
348 | it "concatenates two lists modifying the first list" do
349 | first_list = LinkedList(Int32).new(1, 2)
350 | second_list = LinkedList(Int32).new(3, 4)
351 |
352 | first_list.concat(second_list)
353 | first_list.size.should eq 4
354 |
355 | first_list[0].should eq 1
356 | first_list[1].should eq 2
357 | first_list[2].should eq 3
358 | first_list[3].should eq 4
359 | end
360 | end
361 |
362 | describe "#reverse" do
363 | it "creates a copy of the linked list with the order reversed" do
364 | list = LinkedList(Int32).new(1, 2, 3)
365 | reversed_list = list.reverse
366 |
367 | reversed_list.shift.should eq 3
368 | reversed_list.shift.should eq 2
369 | reversed_list.shift.should eq 1
370 | end
371 | end
372 |
373 | describe "#each" do
374 | it "iterates over each value" do
375 | values = [1, 2, "test"]
376 | list = LinkedList(Int32 | String).new(values)
377 |
378 | list.each do |elem|
379 | values.shift.should eq elem
380 | end
381 | end
382 |
383 | it "iterates over nothing" do
384 | list = LinkedList(Int32 | String).new
385 |
386 | list.each do |_|
387 | false.should be_true
388 | end
389 | end
390 | end
391 |
392 | describe "#to_s" do
393 | it "confirm the string output for a linked list" do
394 | list = LinkedList(Int32 | String).new
395 | list.append(1)
396 | list.append(2)
397 | list.append("test")
398 | list.to_s.should eq "[ 1, 2, test ]"
399 | end
400 | end
401 |
402 | describe "continuously populate and empty" do
403 | # testing that pop sets the list to nil
404 | it "init and pop" do
405 | list = LinkedList(Int32).new(1,2,3)
406 |
407 | list.pop()
408 | list.pop()
409 | list.pop()
410 |
411 | list.append(4)
412 | list.size.should eq 1
413 |
414 | list[0].should eq 4
415 |
416 | end
417 |
418 | it "init and shift" do
419 | list = LinkedList(Int32).new(1,2,3)
420 |
421 | list.shift()
422 | list.shift()
423 | list.shift()
424 |
425 | list.append(4)
426 | list.size.should eq 1
427 |
428 | list[0].should eq 4
429 |
430 | end
431 |
432 | it "init and reverse and shift" do
433 | list = LinkedList(Int32).new(1,2,3)
434 |
435 | reversed_list = list.reverse
436 |
437 | reversed_list.shift()
438 | reversed_list.shift()
439 | reversed_list.shift()
440 |
441 | reversed_list.append(4)
442 | reversed_list.size.should eq 1
443 |
444 | reversed_list[0].should eq 4
445 | end
446 | end
447 |
448 | end
449 |
--------------------------------------------------------------------------------
/spec/spec_helper.cr:
--------------------------------------------------------------------------------
1 | require "spec"
2 | require "../src/linked_list"
3 |
--------------------------------------------------------------------------------
/src/linked_list.cr:
--------------------------------------------------------------------------------
1 | # A linked list is a **Enumerable** (see the `Enumerable` module) data structure
2 | # that stores multiple pieces of data in non contiguous locations in memory.
3 | #
4 | # To create a linked list:
5 | #
6 | # ```
7 | # list = LinkedList(Int32).new
8 | # list.push(2)
9 | # puts list.pop
10 | # ```
11 | #
12 | # The above produces:
13 | #
14 | # ```text
15 | # 2
16 | # ```
17 | class LinkedList(A)
18 | @head : Node(A) | Nil
19 | @tail : Node(A) | Nil
20 |
21 | include Enumerable(A | Nil)
22 |
23 | # Creates an empty linked list.
24 | def initialize
25 | @head = nil
26 | @tail = @head
27 | end
28 |
29 | # Creates a linked list with the *values* as the values of the nodes.
30 | def initialize(*values)
31 | initialize(values)
32 | end
33 |
34 | # ditto
35 | def initialize(values : Enumerable(A))
36 | @head = nil
37 | @tail = @head
38 | values.each do |value|
39 | append(value)
40 | end
41 | end
42 |
43 | # Adds a *value* to the end of a linked list.
44 | #
45 | # ```
46 | # list = LinkedList(Int32).new
47 | # list.append(1)
48 | # list.push(2)
49 | # list.pop() # => 2
50 | # list.pop() # => 1
51 | # ```
52 | def append(value : A)
53 | if @head.nil?
54 | @head = Node(A).new(value)
55 | @tail = @head
56 | else
57 | new_node = Node(A).new(value)
58 | @tail.not_nil!.next = new_node
59 | @tail = new_node
60 | new_node.value
61 | end
62 | end
63 |
64 | # ditto
65 | def push(value : A)
66 | append(value)
67 | end
68 |
69 | # Adds a *value* to the linked list at a specified index.
70 | #
71 | # ```
72 | # list = LinkedList(Int32).new
73 | # list.append(1)
74 | # list.append(2)
75 | # list.insert_at(3, 1)
76 | # ```
77 | def insert_at(value : A, index : Int32)
78 | # non-contiguous
79 | return nil if index > size
80 |
81 | # inserting at the beginning is the unshift function
82 | if index == 0
83 | unshift(value)
84 | return
85 | end
86 |
87 | # not index 0, but list is empty
88 | # non-contiguous
89 | if @head.nil?
90 | return nil
91 | end
92 |
93 | # start at head and move to the index
94 | last = @tail
95 | previous = @head
96 | current = @head.not_nil!.next.not_nil!
97 |
98 | search = 1
99 |
100 | while current != last && search < index
101 | previous = current
102 | current = current.next.not_nil!
103 | search += 1
104 | end
105 |
106 | # made it to the desired index
107 | if search != index
108 | return nil
109 | end
110 |
111 | new_node = Node(A).new(value)
112 |
113 | previous.not_nil!.next = new_node
114 | new_node.next = current
115 | end
116 |
117 | # Override the << (shift) operator to add a *value* to the end of a
118 | # linked list. This method returns itself so it can be chained.
119 | #
120 | # ```
121 | # list = LinkedList(Int32).new(1)
122 | # list << 2 << 3
123 | # list.pop() # => 3
124 | # list.pop() # => 2
125 | # list.pop() # => 1
126 | # ```
127 | def <<(value : A)
128 | append(value)
129 | self
130 | end
131 |
132 | # Adds a list of *values* to the end of a linked list.
133 | #
134 | # ```
135 | # list = LinkedList(Int32 | String).new
136 | # list.append(1, "foo")
137 | # list.pop() # => "foo"
138 | # list.pop() # => 1
139 | # ```
140 | def append(*values)
141 | values.each do |value|
142 | append(value)
143 | end
144 | end
145 |
146 | # same as append
147 | def push(*values)
148 | values.each do |value|
149 | push(value)
150 | end
151 | end
152 |
153 | # Adds a *value* to the beginning of a linked list.
154 | #
155 | # ```
156 | # list = LinkedList(Int32).new(1)
157 | # list.unshift(2)
158 | # list.pop() # => 1
159 | # list.pop() # => 2
160 | # ```
161 | def unshift(value : A)
162 | if @head.nil?
163 | append(value)
164 | return
165 | end
166 | new_top = Node(A).new(value)
167 | new_top.next = @head
168 | @head = new_top
169 | new_top.value
170 | end
171 |
172 | # Returns the first `Node` from the list and removes it.
173 | #
174 | # ```
175 | # list = LinkedList(Float64).new(1.23)
176 | # list.push(4.56)
177 | # list.shift() # => 1.23
178 | # list.peek() # => 4.56
179 | # ```
180 | def shift
181 | return if @head.nil?
182 |
183 | first = @head.not_nil!
184 | @head = head.not_nil!.next
185 | first.value
186 | end
187 |
188 | # Returns the value of the tail of the linked list,
189 | # or nil if no value was supplied.
190 | #
191 | # ```
192 | # list = LinkedList(Float64).new(1.23)
193 | # list.push(4.56)
194 | # list.peek() # => 4.56
195 | # ```
196 | def peek
197 | return nil if @tail.nil?
198 | @tail.not_nil!.value
199 | end
200 |
201 | # Returns the last `Node` from the list and removes it.
202 | #
203 | # ```
204 | # list = LinkedList(Float64).new(1.23)
205 | # list.push(4.56)
206 | # list.pop() # => 4.56
207 | # list.peek() # => 1.23
208 | # ```
209 | def pop
210 | return nil if @head.nil?
211 |
212 | if @head == @tail
213 | current = @head
214 | @head = nil
215 | @tail = nil
216 | return current.not_nil!.value
217 | end
218 |
219 | last = @tail
220 | current = @head
221 | while current.not_nil!.next != last
222 | current = current.not_nil!.next.not_nil!
223 | end
224 |
225 | current.not_nil!.next = nil
226 | @tail = current
227 | last.not_nil!.value
228 | end
229 |
230 | # Iterates over all the values in the linked list.
231 | #
232 | # ```
233 | # values = [1, 2, 3]
234 | # list = LinkedList(Int32).new(values)
235 | # list.each do |elem|
236 | # puts elem
237 | # end
238 | #
239 | # The above produces:
240 | #
241 | # ```text
242 | # 1
243 | # 2
244 | # 3
245 | # ```
246 | def each
247 | each_node do |node|
248 | yield node.value
249 | end
250 | self
251 | end
252 |
253 | # Returns a new `LinkedList` with all of the elements from the first list
254 | # followed by all of the elements in the second *list*.
255 | #
256 | # ```
257 | # first_list = LinkedList(Int32).new(1, 2)
258 | # second_list = LinkedList(String).new("foo", "bar")
259 | # combined_list = first_list + second_list
260 | # combined_list.peek() # => "bar"
261 | # combined_list.shift() # => 1
262 | # ```
263 | def +(list : Enumerable(C)) forall C
264 | LinkedList(A | C).new.tap do |new_list|
265 | each do |value|
266 | new_list.append(value)
267 | end
268 | list.each do |value|
269 | new_list.append(value)
270 | end
271 | end
272 | end
273 |
274 | def [](index : Int32)
275 | return nil if @head.nil?
276 |
277 | search = 0
278 | each_node do |node|
279 | if search == index
280 | return node.value
281 | end
282 |
283 | search += 1
284 | end
285 | end
286 |
287 | # Adds all the elemenets of the *list* to the end of the current linked list.
288 | #
289 | # ```
290 | # first_list = LinkedList(Int32).new(1, 2)
291 | # second_list = LinkedList(Int32).new(3, 4)
292 | # combined_list = first_list.concat(second_list)
293 | # combined_list.peek() # => 4
294 | # combined_list.shift() # => 1
295 | # ```
296 | def concat(list : LinkedList(A))
297 | @tail.not_nil!.next = list.head
298 | @tail = list.tail
299 | self
300 | end
301 |
302 | # Returns true if and only if there are no elements in the list.
303 | #
304 | # ```
305 | # list = LinkedList(Int32).new
306 | # list.empty? # => true
307 | # list.push(1)
308 | # list.empty? # => false
309 | # ```
310 | def empty?
311 | @head.nil?
312 | end
313 |
314 | # Creates a copy of the `LinkedList` with the order reversed.
315 | #
316 | # ```
317 | # list = LinkedList(Int32).new(1, 2, 3)
318 | # reversed_list = list.reverse
319 | # list.pop() # => 1
320 | # list.pop() # => 2
321 | # list.pop() # => 3
322 | # ```
323 | def reverse
324 | LinkedList(A).new.tap do |new_list|
325 | each do |value|
326 | new_list.unshift(value.not_nil!)
327 | end
328 | end
329 | end
330 |
331 | # Returns the first node in the list, or nil if the list is empty.
332 | #
333 | # ```
334 | # list = LinkedList(Int32).new(1, 2, 3)
335 | # list.head.value # => 1
336 | # ```
337 | protected def head
338 | @head
339 | end
340 |
341 | # Returns the last node in the list, or nil if the list is empty.
342 | #
343 | # ```
344 | # list = LinkedList(Int32).new(1, 2, 3)
345 | # list.tail.value # => 3
346 | # ```
347 | protected def tail
348 | @tail
349 | end
350 |
351 | # Iterates over all the nodes in the linked list.
352 | #
353 | # ```
354 | # values = [1, 2, 3]
355 | # list = LinkedList(Int32).new(values)
356 | # list.each_node do |elem|
357 | # puts elem.value
358 | # end
359 | #
360 | # The above produces:
361 | #
362 | # ```text
363 | # 1
364 | # 2
365 | # 3
366 | # ```
367 | private def each_node
368 | return nil if @head.nil?
369 |
370 | current = @head
371 | loop do
372 | yield current.not_nil!
373 | current = current.not_nil!.next
374 | break if current.nil?
375 | end
376 | end
377 |
378 | # Overloading the to_s function to print the contents
379 | # of the linked list
380 | # This calls the to_s function of each node in the
381 | # linked list
382 | #
383 | # ```
384 | # values = [1, 2, 3]
385 | # puts values
386 | #
387 | # The above produces:
388 | #
389 | # ```text
390 | # [ 1, 2, 3 ]
391 | # ```
392 | def to_s(io)
393 | io << "[ "
394 |
395 | # iterate through the nodes in the linked list
396 | each_node do |elem|
397 | io << elem.value
398 | # kind of clunky, if this is the tail node
399 | # don't print the comma
400 | if elem != @tail
401 | io << ", "
402 | end
403 | end
404 |
405 | io << " ]"
406 | end
407 |
408 | # A node is the building block of linked lists consisting of a values
409 | # and a pointer to the next node in the linked list.
410 | #
411 | # To create a node:
412 | #
413 | # ```
414 | # node = Node.new(5)
415 | # puts node.value
416 | # ```
417 | #
418 | # The above produces:
419 | #
420 | # ```text
421 | # 5
422 | # ```
423 | #
424 | # Check the value of the node with `#value`.
425 | # Get the next node in the list with `#next`.
426 | class Node(T)
427 | @next = nil
428 | @value = nil
429 |
430 | # Creates a node with no value.
431 | def initialize
432 | end
433 |
434 | # Creates a node with the specified *value*.
435 | def initialize(@value : T)
436 | end
437 |
438 | # Returns the value of the node, or nil if no value was supplied
439 | #
440 | # ```
441 | # Node.new(1).value # => 1
442 | # ```
443 | def value
444 | @value
445 | end
446 |
447 | # Returns the next node in the linked list, or nil if it is the tail.
448 | #
449 | # ```
450 | # node = Node.new(1)
451 | # node.next = Node.new(2)
452 | # node.next.value # => 2
453 | # ```
454 | def next
455 | @next
456 | end
457 |
458 | # Sets the next node in the linked list to *next_node*
459 | #
460 | # ```
461 | # node = Node.new(1)
462 | # node.next = Node.new(2)
463 | # node.next.value # => 2
464 | # ```
465 | def next=(next_node : Node(T) | Nil)
466 | @next = next_node
467 | end
468 |
469 | # Overloading the to_s function to print the contents
470 | # of the node
471 | def to_s(io)
472 | io << @value
473 | end
474 | end
475 | end
476 |
--------------------------------------------------------------------------------
/src/linked_list_benchmark.cr:
--------------------------------------------------------------------------------
1 | # TODO: Write documentation for `Benchmark`
2 |
3 | require "./linked_list"
4 | require "benchmark"
5 |
6 | module LinkedListBenchmark
7 | VERSION = "0.1.0"
8 |
9 | # TODO: Put your code here
10 |
11 | # ========================================
12 | # benchmark appending
13 | list1 = LinkedList(Int32).new
14 | list2 = LinkedList(Int32).new
15 | list3 = LinkedList(Int32).new
16 | # Benchmark.ips do |x|
17 | # x.report("append") { 1000.times{ list.append(1) } }
18 | # end
19 |
20 | puts Benchmark.measure { 100.times{ list1.append(1) } }
21 | puts Benchmark.measure { 10_000.times{ list2.append(1) } }
22 | puts Benchmark.measure { 1_000_000.times{ list3.append(1) } }
23 |
24 | puts Benchmark.measure { list1.insert_at(1, 1) }
25 | puts Benchmark.measure { list2.insert_at(1, 1) }
26 | puts Benchmark.measure { list3.insert_at(1, 1) }
27 | # ========================================
28 |
29 | end
--------------------------------------------------------------------------------