Пишу свой класс DoubleLinkedList, застрял на реализации IDoubleLinkedList,IEnumerable
Делаю д/з, нужно написать свой класс DoubleLinkedList и реализовать к нему методы И плюс к методам еще реализовать интерфейсы
public class DoubleLinkedList<T> : IDoubleLinkedList<T>,IEnumerable<T>
Много уже информации перелопатил , есть понимание для чего эти интерфейсы нужны а вот как сделать с этим беда полнейшая. Подскажите люди добрые хотя бы в каком направлении двигаться
Интерфейсы в самом низу находятся, заранее за любую помощь огромная благодарность
public class DoubleLinkedList<T> : IDoubleLinkedList<T>,IEnumerable<T>
{
public int Count { get; set; }
private Node<T> _root;
private Node<T> _tail;
public DoubleLinkedList()
{
Count = 0;
_root = null;
_tail = null;
}
public DoubleLinkedList(T value)
{
Count = 1;
_root = new Node<T>(value);
_tail = _root;
}
public DoubleLinkedList(T[] values)
{
if (values.Length != 0)
{
Count = values.Length;
_root = new Node<T>(values[0]);
_root.Next = null;
_root.Previous = null;
_tail = _root;
for (int i = 1; i < values.Length; i++)
{
var newNode = new Node<T>(values[i]);
_tail.Next = newNode;
newNode.Previous = _tail;
_tail = newNode;
}
}
else
{
_root = null;
_tail = null;
}
}
public void PrintList()
{
Node<T> runner = _root;
while (runner != null)
{
Console.WriteLine(runner.Value);
runner = runner.Next;
}
}
public void PrintReverse()
{
var item = _tail;
while (item != null)
{
Console.WriteLine($"{item.Value}");
item = item.Previous;
}
}
public bool isEmpty { get { return Count == 0; } }
public void AddFirst(T value)
{
var node = new Node<T>(value);
var temp = _root;
node.Next = _root;
_root = node;
if (Count == 0)
{
_tail = _root;
}
else
{
temp.Previous = node;
Count++;
}
}
public void AddLast(T value)
{
var newNode = new Node<T>(value);
_tail.Next = newNode;
newNode.Previous = _tail;
_tail = newNode;
Count++;
}
public void Clear()
{
_root = null;
_tail = null;
Count = 0;
}
public bool Contains(T data)
{
var current = _root;
while (current != null)
{
if (current.Value.Equals(data))
return true;
current = current.Next;
}
return false;
}
public bool Remove(T value)
{
var current = _root;
while (current != null)
{
if (current.Value.Equals(value))
{
break;
}
current = current.Next;
}
if (current != null)
{
if (current.Next != null)
{
current.Next.Previous = current.Previous;
}
else
{
_tail = current.Previous;
}
if (current.Previous != null)
{
current.Previous.Next = current.Next;
}
else
{
_root = current.Next;
}
Count--;
return true;
}
return false;
}
public IEnumerable<T> BackEnumerator()
{
throw new NotImplementedException();
}
public IEnumerator<T> GetEnumerator()
{
throw new NotImplementedException();
}
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
}
Ответы (1 шт):
Не понятно, что такое интерфейс IDoubleLinkedList<T>, почему-то вы его не показали, поэтому ответ без учета этого интерфейса.
private IEnumerable<T> GetEnumerable()
{
Node<T> node = _root;
while (node != null)
{
yield return node.Value;
node = node.Next;
}
}
public IEnumerable<T> GetBackEnumerable()
{
Node<T> node = _tail;
while (node != null)
{
yield return node.Value;
node = node.Previous;
}
}
public IEnumerator<T> GetEnumerator()
{
return GetEnumerable().GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerable().GetEnumerator();
}
Еще несколько ошибок
public int Count { get; set; }
Вы разрешаете кому угодно менять Count? Я бы так не делал
public int Count { get; private set; }
Свойства надо писать с большой буквы
public bool isEmpty { get { return Count == 0; } }
Получится так
public bool IsEmpty { get { return Count == 0; } }
А еще можно так написать
public bool IsEmpty => Count == 0;
Методы добавления элементов могут выглядеть так
public void AddFirst(T value)
{
var node = new Node<T>(value);
if (_root != null)
_root.Previous = node;
else
_tail = node;
_root = node;
Count++;
}
public void AddLast(T value)
{
var node = new Node<T>(value);
if (_tail != null)
_tail.Next = node;
else
_root = node;
_tail = node;
Count++;
}
С учетом того, что реализуется IEnumerable<T>, вот этот метод не нужен вообще:
public bool Contains(T data)
Данный метод есть в Linq.
Методы
public void PrintList()
public void PrintReverse()
Не должны входить в состав коллекции. Что если я буду использовать ваш список в Winforms или Unity, что я как разработчик должен ожидать от этих методов? Зависимости от окружения в реализации коллекции не должно быть. Если мне надо вывести в консоль, этот список, я воспользуюсь IEnumerable<T>.
foreach (var item in list)
{
Console.WriteLine(item);
}
Конструктор из коллекции
public DoubleLinkedList(T[] values)
может выглядеть так
public DoubleLinkedList(IEnumerable<T> values)
{
foreach (T value in values)
{
AddLast(value);
}
}
Кстати, а почему бы не использовать цикл for?
private IEnumerable<T> GetEnumerable()
{
for (Node<T> node = _root; node != null; node = node.Next)
{
yield return node.Value;
}
}
В итоге получилось что-то такое
public class Node<T>
{
public T Value { get; set; }
public Node<T> Next { get; set; }
public Node<T> Previous { get; set; }
public Node(T value)
=> Value = value;
}
public interface IDoubleLinkedList<T>
{
void AddFirst(T item);
void AddLast(T item);
IEnumerable<T> GetBackEnumerable();
}
public class DoubleLinkedList<T> : IDoubleLinkedList<T>, ICollection<T>, IEnumerable<T>
{
private Node<T> _root;
private Node<T> _tail;
private int _count;
public int Count => _count;
public bool IsReadOnly => false;
public DoubleLinkedList() { }
public DoubleLinkedList(T value)
=> AddLast(value);
public DoubleLinkedList(IEnumerable<T> values)
{
foreach (T value in values)
AddLast(value);
}
public void AddFirst(T item)
{
var node = new Node<T>(item);
if (_root != null)
_root.Previous = node;
else
_tail = node;
_root = node;
_count++;
}
public void AddLast(T item)
{
var node = new Node<T>(item);
if (_tail != null)
_tail.Next = node;
else
_root = node;
_tail = node;
_count++;
}
public void CopyTo(T[] array, int arrayIndex)
{
int i = arrayIndex;
foreach (T value in GetEnumerable())
{
if (i >= array.Length)
break;
array[i] = value;
}
}
public bool Contains(T item)
=> GetEnumerable().Contains(item);
public void Clear()
{
_root = null;
_tail = null;
_count = 0;
}
public bool Remove(T value)
{
Node<T> node;
for (node = _root; node != null; node = node.Next)
if (node.Value.Equals(value))
break;
if (node != null)
{
if (node.Previous != null)
node.Previous.Next = node.Next;
if (node.Next != null)
node.Next.Previous = node.Previous;
_count--;
return true;
}
return false;
}
private IEnumerable<T> GetEnumerable()
{
for (Node<T> node = _root; node != null; node = node.Next)
yield return node.Value;
}
public IEnumerable<T> GetBackEnumerable()
{
for (Node<T> node = _tail; node != null; node = node.Previous)
yield return node.Value;
}
public IEnumerator<T> GetEnumerator()
=> GetEnumerable().GetEnumerator();
IEnumerator IEnumerable.GetEnumerator()
=> GetEnumerable().GetEnumerator();
void ICollection<T>.Add(T item)
=> AddLast(item);
}
Но ввобще всё, что вы пытаетесь сделать, уже умеет LinkedList<T> - документация.