Вот другой взгляд на это. Он проходит по списку, берет первый элемент и вставляет его перед маркером в конце. Это работает для элементов N-1, поэтому в конце нужно немного поработать, чтобы обработать самый последний элемент. Я делаю это со списком строк (а не целых чисел) только потому, что это упрощает запись результатов. Я также тестировал его с помощью int.
Вот алгоритм:
private static LinkedList<T> ReverseList<T>(LinkedList<T> theList)
{
var len = theList.Count;
var marker = theList.Last;
//the loop reverses all but the last element
for (var i = 0; i < len - 1; ++i)
{
var currentFirst = theList.First;
theList.RemoveFirst();
theList.AddBefore(marker, currentFirst);
marker = currentFirst;
}
//now take the last element and insert it at the beginning
var last = theList.Last;
theList.RemoveLast();
theList.AddFirst(last);
return theList;
}
Вот мой призыв к нему (используя список string
- вы можете попробовать его с любым типом):
public static void TestReverse()
{
var theList = new LinkedList<string>();
theList.AddLast("1");
theList.AddLast("2");
theList.AddLast("3");
theList.AddLast("4");
theList.AddLast("5");
var results = ReverseList(theList);
Debug.WriteLine(string.Join(", ", theList));
}
и вот результат:
5, 4, 3, 2, 1
Стоит отметить, что все эти операции (Count
, Last
, First
, RemoveFirst
, AddBefore
, RemoveLast
и AddFirst
) должны быть O (1) в правильно реализованном односвязном списке. В результате этот алгоритм O (N).