Zerox
Zerox

Reputation: 61

In C#, Rotate a List to The Right by the specified numbers of places without using LINQ?

I am trying to rotate a List of items to the right by the specified numbers of places without using LINQ and doing it the manual way, how am I able to do this?

I think I am not understanding how to approach/solve this problem in particular. Here's what I have tried so far.

A clear example of this problem could be something like this: Initial Array(or List): 20,30,40,50,60,70 Rotate to the right by 3 places: 50,60,70,20,30,40

      public void Test(List<int> items, int places)
    {
        items.RemoveAt(places);
        items.Add(places);

    }

Upvotes: 2

Views: 859

Answers (4)

Zein Makki
Zein Makki

Reputation: 30022

Results from the below:

20,30,40,50,60,70 
60,70,20,30,40,50  (Rotate 2) 
50,60,70,20,30,40  (Rotate 3)

If you meant to shift each element n indexes to the left, just replace the line list[i] = copy[index]; with list[index] = copy[i];

Then you get these results:

20,30,40,50,60,70 
40,50,60,70,20,30  (Rotate 2) 
50,60,70,20,30,40  (Rotate 3)

This is a simple working generic method:

static void RotateList<T>(IList<T> list, int places)
{
    // circular.. Do Nothing
    if (places % list.Count == 0)
        return;

    T[] copy = new T[list.Count];
    list.CopyTo(copy, 0);

    for (int i = 0; i < list.Count; i++)
    {
        // % used to handle circular indexes and places > count case
        int index = (i + places) % list.Count;

        list[i] = copy[index];
    }
}

Usage:

List<int> list = new List<int>() { 20, 30, 40, 50, 60, 70 };
RotateList(list, 3);

Or since I'm a big fan of extension Methods, you can create one:

(By using IList, this method works for arrays also)

public static class MyExtensions
{
    public static void RotateList<T>(this IList<T> list, int places)
    {
        // circular.. Do Nothing
        if (places % list.Count == 0)
            return;

        T[] copy = new T[list.Count];
        list.CopyTo(copy, 0);

        for (int i = 0; i < list.Count; i++)
        {
            int index = (i + places) % list.Count;

            list[i] = copy[index];
        }
    }

Usage:

List<int> list = new List<int>() { 20, 30, 40, 50, 60, 70 };
list.RotateList(12); // circular - no changes

int[] arr = new int[] { 20, 30, 40, 50, 60, 70 };

arr.RotateList(3);

Upvotes: 5

nawfal
nawfal

Reputation: 73163

While this may not exactly answer your question it's worth mentioning about queues. For circular operations Queue<T>s could be a better data structure choice. To shift places it could be as simple as:

public static void Rotate<T>(this Queue<T> items, int places)
{
    for (int i = 0; i < places; i++)
        items.Enqueue(items.Dequeue());
}

E.g.

var q = new Queue<int>(new[] { 20, 30, 40, 50, 60, 70 });
q.Rotate(3);

Queues are also a lot more efficient than List<T>s for dequeuing operation since it doesnt have to remove from top and push entire block of array one up (read about it here: Queue<T> vs List<T>) or arrays which involves copying of the entire array.

Upvotes: 0

Cetin Basoz
Cetin Basoz

Reputation: 23797

int[] numbers = {20, 30, 40, 50, 60, 70};
int rotateBy = 3;
int[] rotated = new int[numbers.Length];

Array.Copy(numbers, rotateBy, rotated, 0, numbers.Length-rotateBy);
Array.Copy(numbers, 0, rotated, numbers.Length - rotateBy, rotateBy);

Upvotes: 2

Noctis
Noctis

Reputation: 11763

assuming you have a list 1-2-3-4-5, and you want to shift it 2 right to : 3-4-5-1-2.

for n = 1 to 2 
   remove the head, put it at the tail 

simple loop with no linq.

Even though this sounds more like homework to me to be honest ..

Upvotes: 4

Related Questions