I also decided to make my own enumerator for the linked list. Here is what I wrote:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
namespace LinkedList | |
{ | |
class Node<T> | |
{ | |
public T data; | |
public Node<T> next, previous; | |
public Node(T data, Node<T> next = null, Node<T> previous = null) | |
{ | |
this.data = data; | |
this.next = next; | |
this.previous = previous; | |
} | |
} | |
class LinkedList<T> : IEnumerable<T> | |
{ | |
public Node<T> head, tail; | |
public int length; | |
public LinkedList() | |
{ | |
head = null; | |
tail = null; | |
length = 0; | |
} | |
public void insertAfter(Node<T> node, T value) | |
{ | |
if (node == tail) | |
addLast(value); | |
else | |
{ | |
Node<T> new_node = new Node<T>(value, node.next, node); | |
node.next = new_node; | |
new_node.next.previous = new_node; | |
length += 1; | |
} | |
} | |
public void insertBefore(Node<T> node, T value) | |
{ | |
if (node == head) | |
addFirst(value); | |
else | |
{ | |
Node<T> new_node = new Node<T>(value, node, node.previous); | |
node.previous = new_node; | |
new_node.previous.next = new_node; | |
length += 1; | |
} | |
} | |
public void addFirst(T value) | |
{ | |
Node<T> new_node = new Node<T>(value, head, null); | |
if (tail == null) | |
tail = new_node; | |
else | |
head.previous = new_node; | |
head = new_node; | |
length += 1; | |
} | |
public void addLast(T value) | |
{ | |
Node<T> new_node = new Node<T>(value, null, tail); | |
if (head == null) | |
head = new_node; | |
else | |
tail.next = new_node; | |
tail = new_node; | |
length += 1; | |
} | |
public Node<T> find(T value) | |
{ | |
Node<T> runner = head; | |
while (runner != null) | |
{ | |
if (EqualityComparer<T>.Default.Equals(runner.data, value)) | |
return runner; | |
runner = runner.next; | |
} | |
return null; | |
} | |
public void remove(Node<T> node) | |
{ | |
try | |
{ | |
if (node == head) | |
{ | |
head = node.next; | |
head.previous = null; | |
} | |
else if (node == tail) | |
{ | |
tail = node.previous; | |
tail.next = null; | |
} | |
else | |
{ | |
node.next.previous = node.previous; | |
node.previous.next = node.next; | |
} | |
length -= 1; | |
} | |
catch (NullReferenceException) | |
{ | |
Console.WriteLine("Could not find the node you want to remove.\n"); | |
} | |
} | |
public Node<T> first() | |
{ | |
return head; | |
} | |
public Node<T> last() | |
{ | |
return tail; | |
} | |
public int Count | |
{ | |
get | |
{ | |
return length; | |
} | |
} | |
public IEnumerator<T> GetEnumerator() | |
{ | |
return new myEnumerator(this); | |
} | |
IEnumerator IEnumerable.GetEnumerator() | |
{ | |
return new myEnumerator(this); | |
} | |
private class myEnumerator : IEnumerator<T> | |
{ | |
private LinkedList<T> linkedList; | |
private Node<T> runner; | |
bool started = false; | |
public myEnumerator(LinkedList<T> linkedList) | |
{ | |
this.linkedList = linkedList; | |
runner = linkedList.head; | |
} | |
public T Current | |
{ | |
get | |
{ | |
return runner.data; | |
} | |
} | |
object IEnumerator.Current | |
{ | |
get | |
{ | |
return runner.data; | |
} | |
} | |
public void Dispose() | |
{ | |
//Not needed | |
} | |
public bool MoveNext() | |
{ | |
if (started && runner != null) | |
runner = runner.next; | |
started = true; | |
return runner != null; | |
} | |
public void Reset() | |
{ | |
started = false; | |
runner = linkedList.head; | |
} | |
} | |
} | |
} |
No comments:
Post a Comment