Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- namespace Lists
- {
- /// <summary>
- /// Односвязный список.
- /// </summary>
- /// <typeparam name="T">Тип элемента, хранящегося в списке.</typeparam>
- public class SingleLinkedList<T>
- {
- int length;
- Node<T> head;
- Node<T> end;
- /// <summary>
- /// Возвращает начальный элемент списка.
- /// </summary>
- /// <returns>Значение начального элемента списка.</returns>
- public T Head()
- {
- return head.Elem();
- }
- /// <summary>
- /// Возвращает конечный элемент списка.
- /// </summary>
- /// <returns>Значение конечного элемента списка.</returns>
- public T End()
- {
- return end.Elem();
- }
- /// <summary>
- /// Возвращает длину списка.
- /// </summary>
- /// <returns>Длина списка.</returns>
- public int Length()
- {
- return length;
- }
- /// <summary>
- /// Вставляет элемент в начало списка.
- /// </summary>
- /// <param name="elem">Элемент для вставки.</param>
- public void AddToHead(T elem)
- {
- Node<T> node = new Node<T>(elem, null);
- if (head == null)
- {
- end = node;
- }
- else
- {
- node.SetNext(head);
- }
- head = node;
- length++;
- return;
- }
- /// <summary>
- /// Вставляет элемент в конец списка.
- /// </summary>
- /// <param name="elem">Элемент для вставки.</param>
- public void AddToTail(T elem)
- {
- Node<T> node = new Node<T>(elem, null);
- end.SetNext(node);
- end = node;
- length++;
- }
- /// <summary>
- /// Вставляет элемент на указанную позицию.
- /// </summary>
- /// <param name="index">Позиция для вставки.</param>
- /// <param name="elem">Элемент для вставки.</param>
- public void AddByIndex(int index, T elem)
- {
- if (index < 0 || index > length)
- {
- throw new IndexOutOfRangeException();
- }
- if (index == 0)
- {
- AddToHead(elem);
- return;
- }
- if (index == length)
- {
- AddToTail(elem);
- return;
- }
- // Найти ноду по индексу.
- int i = 0;
- Node<T> indNode = null;
- Node<T> beforeIndNode = null;
- for (Node<T> current = head; current != null; current = current.Next())
- {
- if (i == index)
- {
- indNode = current;
- break;
- }
- beforeIndNode = current;
- i++;
- }
- Node<T> node = new Node<T>(elem, indNode);
- beforeIndNode.SetNext(node);
- length++;
- }
- /// <summary>
- /// Удаляет элемент в начале списка.
- /// </summary>
- /// <returns>Значение удалённого элемента.</returns>
- public T RemoveHead()
- {
- T elem = head.Elem();
- head = head.Next();
- length--;
- return elem;
- }
- /// <summary>
- /// Удаляет элемент в конце списка.
- /// </summary>
- /// <returns>Значение удалённого элемента.</returns>
- public T RemoveEnd()
- {
- if (length == 1)
- {
- T _elem = head.Elem();
- head = null;
- end = null;
- return _elem;
- }
- // Найти ноду перед конечной.
- Node<T> beforeEnd = null;
- for (Node<T> current = head; current.Next() != null; current = current.Next())
- {
- beforeEnd = current;
- }
- T elem = end.Elem();
- beforeEnd.SetNext(null);
- end = beforeEnd;
- length--;
- return elem;
- }
- /// <summary>
- /// Удаляет элемент в указанной позиции списка.
- /// </summary>
- /// <param name="index">Похиция элемента.</param>
- /// <returns>Значение удалённого элемента.</returns>
- public T RemoveByIndex(int index)
- {
- if (index < 0 || index > length - 1)
- {
- throw new IndexOutOfRangeException();
- }
- if (index == 0)
- {
- return RemoveHead();
- }
- if (index == length - 1)
- {
- return RemoveEnd();
- }
- // Найти ноду по индексу.
- int i = 0;
- Node<T> indNode = null;
- Node<T> beforeIndNode = null;
- for (Node<T> current = head; current.Next() != null; current = current.Next())
- {
- if (i == index)
- {
- indNode = current;
- break;
- }
- beforeIndNode = current;
- i++;
- }
- T elem = indNode.Elem();
- beforeIndNode.SetNext(indNode.Next());
- indNode.SetNext(null);
- length--;
- return elem;
- }
- /// <summary>
- /// Возвращает значение элементу, расположенного в указанной позиции.
- /// </summary>
- /// <param name="index">Позиция эелемента.</param>
- /// <returns>Значение элемента.</returns>
- public T GetElemByIndex(int index)
- {
- if (index < 0 || index > length - 1)
- {
- throw new IndexOutOfRangeException();
- }
- // Найти ноду по индексу.
- int i = 0;
- Node<T> indNode = null;
- for (Node<T> current = head; current != null; current = current.Next())
- {
- if (i == index)
- {
- indNode = current;
- break;
- }
- i++;
- }
- return indNode.Elem();
- }
- /// <summary>
- /// Возвращает набор элементов списка.
- /// </summary>
- /// <returns>Набор элементов списка.</returns>
- public T[] GetElems()
- {
- T[] arr = new T[length];
- int i = 0;
- for (Node<T> current = head; current != null; current = current.Next())
- {
- arr[i] = current.Elem();
- i++;
- }
- return arr;
- }
- /// <summary>
- /// Применить указанную процедуру к каждому элементу списка.
- /// </summary>
- /// <param name="visitor">Процедура для применения к элементам списка.</param>
- public void Visit(Action<int, T> visitor)
- {
- int i = 0;
- for (Node<T> current = head; current != null; current = current.Next())
- {
- visitor(i, current.Elem());
- i++;
- }
- }
- }
- /// <summary>
- /// Элемент односвязного списка.
- /// </summary>
- /// <typeparam name="T">Тип элемента списка.</typeparam>
- public class Node<T>
- {
- T elem;
- Node<T> next;
- /// <summary>
- /// Конструктор.
- /// </summary>
- /// <param name="elem">Значение элемента.</param>
- /// <param name="next">Указатель на следующий элемент.</param>
- public Node(T elem, Node<T> next)
- {
- this.elem = elem;
- this.next = next;
- }
- /// <summary>
- /// Возвращает значение элемента списка.
- /// </summary>
- /// <returns>Значение элемента списка.</returns>
- public T Elem()
- {
- return elem;
- }
- /// <summary>
- /// Возвращает следующий за данным элемент списка.
- /// </summary>
- /// <returns>Элемент списка.</returns>
- public Node<T> Next()
- {
- return next;
- }
- /// <summary>
- /// Назначает следующий элемент для данного элемента списка.
- /// </summary>
- /// <param name="node">Следующий элемент списка.</param>
- public void SetNext(Node<T> node)
- {
- next = node;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement