using System.Collections.Generic; using System.Collections; using UnityEngine; using System.Transactions; namespace MyCollections.Generic { public class LinkedList<T> { private ListNode<T> head; public ListNode<T> Head { get => head; set => head = value; } public int Count { get => CounElements(); } //Constructors public LinkedList() => head = null; public LinkedList(ListNode<T> node) => head = node; //Inserts at the beginning public void InsertAtBegin(T item) { ListNode<T> newNode = new ListNode<T>(item); newNode.Next = head; head = newNode; } public void InsertAfter(T after, T item) { ListNode<T> afterNode = LinearSearch(after); if (afterNode != null) { ListNode<T> newNode = new ListNode<T>(item); ListNode<T> temp = afterNode.Next; afterNode.Next = newNode; newNode.Next = temp; } } //Inserts at the end of the LinkedList public void InsertAtEnd(T item) { ListNode<T> newNode = new ListNode<T>(item); if (head == null) { newNode.Next = head; head = newNode; } else { ListNode<T> current = head; while (current != null) { current = current.Next; } current.Next = newNode; } } public void Remove(T data) { ListNode<T> current = head; ListNode<T> previous = null; //search and keep both current and previous pointers while ((current != null) && (!current.Data.Equals(data))) { previous = current; current = current.Next; } if (current != null) { //remove from the beginning if (previous == null) head = current.Next; //remove from any other place else previous.Next = current.Next; } } public void Remove(ListNode<T> node) { if (IsEmpty()) { Debug.LogWarning($"The list is empty"); return; } if (node == head) { head = head.Next; return; } ListNode<T> current = head; ListNode<T> previous = null; while (current != null && current != node) { previous = current; current = current.Next; } if (current == node) previous.Next = current.Next; } public ListNode<T> LinearSearch(T data) { ListNode<T> current = head; while (current != null) { if (current.Data.Equals(data)) { return current; } current = current.Next; } return null; } //Reverse a LinkedList public void Reverse() => Reverse(this); //Reverse a LinkedList public static void Reverse(LinkedList<T> list) { if (IsEmpty(list)) { Debug.LogWarning($"List is empty!"); return; } else { ListNode<T> previous = null; ListNode<T> current = list.head; ListNode<T> next = null; while (current != null) { //Store the next node next = current.Next; //Reverse the current node's pointer current.Next = previous; //Move pointers one position ahead previous = current; current = next; } //Set the new head of the list list.head = previous; } } //Checks if the LinkedList is empty public bool IsEmpty() => IsEmpty(this); public static bool IsEmpty(LinkedList<T> list) => list.head == null; //Allow iteration with foreach public IEnumerator<T> GetEnumerator() { ListNode<T> current = head; while (current != null) { yield return current.Data; current = current.Next; } } public void AddArray(T[] array) => AddArray(this, array); //Adds an array to LinkedList public static void AddArray(LinkedList<T> list, T[] array) { for (int i = 0; i < array.Length; i++) { list.InsertAtEnd(array[i]); } } //Converts an array to a LinkedList public static LinkedList<T> ArrayToLinkedList(T[] array) { LinkedList<T> list = new LinkedList<T>(null); if (array != null && array.Length > 0) { for (int i = 0; i < array.Length; i++) { list.InsertAtEnd(array[i]); } } return list; } private int CounElements() { ListNode<T> current = head; int count = 0; while (current != null) { count++; current = current.Next; } return count; } } }