The move-to-front strategy maintains a linked list with no duplicates. When a previously unseen element is read, it is inserted at the front of the list. When a duplicate element is read, it is deleted from the list and reinserted at the beginning.

The move-to-front strategy is useful for:

  • caching
  • data compression
  • wherever items that have been recently accessed are more likely to be reaccessed
using System;

namespace ConsoleTest
{
    class Program
    {
        static void Main(string[] args)
        {
            MoveToFront m = new MoveToFront();

            Console.Write("A: "); m.Add("A"); m.ShowItems();
            Console.Write("B: "); m.Add("B"); m.ShowItems();
            Console.Write("C: "); m.Add("C"); m.ShowItems();
            Console.Write("C: "); m.Add("C"); m.ShowItems();
            Console.Write("D: "); m.Add("D"); m.ShowItems();
            Console.Write("A: "); m.Add("A"); m.ShowItems();
            Console.Write("B: "); m.Add("B"); m.ShowItems();
            Console.Write("E: "); m.Add("E"); m.ShowItems();
            Console.Write("B: "); m.Add("B"); m.ShowItems();
            Console.Write("A: "); m.Add("A"); m.ShowItems();
            Console.Write("C: "); m.Add("C"); m.ShowItems();
            Console.Write("A: "); m.Add("A"); m.ShowItems();
            Console.Write("A: "); m.Add("A"); m.ShowItems();

            Console.ReadKey();
        }

        class MoveToFront
        {
            private Node first;

            public void Add(T item)
            {
                Node prev;
                bool isFound = Find(item, out prev);

                if (!isFound) // is it a previously unseen item?
                {
                    // Insert a new node at the beginning.
                    Node oldFirst = first;
                    first = new Node();
                    first.Item = item;
                    first.Next = oldFirst;
                }
                else
                {
                    // Remove the node.
                    if (prev == null) // is it the first node?
                        first = first.Next;
                    else
                        prev.Next = prev.Next.Next;

                    // Reinsert the node at the beginning.
                    Node oldFirst = first;
                    first = new Node();
                    first.Item = item;
                    first.Next = oldFirst;
                }
            }

            // Returns the previous node ('prev') of a node that contains 'item'.
            // If the first node contains 'item', prev is null.
            // Returns true if the node found. Otherwise, false.
            private bool Find(T item, out Node prev)
            {
                prev = null;

                // Is the list empty? 
                if (first == null)
                    return false;

                // Are we looking for the first node?
                if (first.Item.Equals(item))
                    return true;

                prev = first;
                Node node;
                while ((node = prev.Next) != null)
                {
                    if (node.Item.Equals(item))
                        return true;

                    prev = node;
                }

                prev = null;
                return false;
            }

            public void ShowItems()
            {
                for (Node node = first; node != null; node = node.Next)
                {
                    Console.Write("{0} ", node.Item.ToString());
                }
                Console.WriteLine();
            }

            private class Node
            {
                public T Item { get; set; }
                public Node Next { get; set; }

                public override string ToString() { return (Item == null ? "null" : Item.ToString()); }
            }
        }
    }
}

Output:

A: A
B: B A
C: C B A
C: C B A
D: D C B A
A: A D C B
B: B A D C
E: E B A D C
B: B E A D C
A: A B E D C
C: C A B E D
A: A C B E D
A: A C B E D