The Algorithms logo
The Algorithms
Acerca deDonar

Unrolled linked list

P
using System.Collections.Generic;

namespace DataStructures.UnrolledList;

/// <summary>
/// Unrolled linked list is a linked list of small arrays,
/// all of the same size where each is so small that the insertion
/// or deletion is fast and quick, but large enough to fill the cache line.
/// </summary>
public class UnrolledLinkedList
{
    private readonly int sizeNode;

    private UnrolledLinkedListNode start = null!;
    private UnrolledLinkedListNode end = null!;

    /// <summary>
    /// Initializes a new instance of the <see cref="UnrolledLinkedList"/> class.
    /// Create a unrolled list with start chunk size.
    /// </summary>
    /// <param name="chunkSize">The size of signe chunk.</param>
    public UnrolledLinkedList(int chunkSize)
    {
        sizeNode = chunkSize + 1;
    }

    /// <summary>
    /// Add value to list [O(n)].
    /// </summary>
    /// <param name="value">The entered value.</param>
    public void Insert(int value)
    {
        if (start == null)
        {
            start = new UnrolledLinkedListNode(sizeNode);
            start.Set(0, value);

            end = start;
            return;
        }

        if (end.Count + 1 < sizeNode)
        {
            end.Set(end.Count, value);
        }
        else
        {
            var pointer = new UnrolledLinkedListNode(sizeNode);
            var j = 0;
            for (var pos = end.Count / 2 + 1; pos < end.Count; pos++)
            {
                pointer.Set(j++, end.Get(pos));
            }

            pointer.Set(j++, value);
            pointer.Count = j;

            end.Count = end.Count / 2 + 1;
            end.Next = pointer;
            end = pointer;
        }
    }

    /// <summary>
    /// Help method. Get all list inside to check the state.
    /// </summary>
    /// <returns>Items from all nodes.</returns>
    public IEnumerable<int> GetRolledItems()
    {
        UnrolledLinkedListNode pointer = start;
        List<int> result = new();

        while (pointer != null)
        {
            for (var i = 0; i < pointer.Count; i++)
            {
                result.Add(pointer.Get(i));
            }

            pointer = pointer.Next;
        }

        return result;
    }
}