C# 使列表中的元素作为第一个元素的最快方法

C# 使列表中的元素作为第一个元素的最快方法,c#,list,C#,List,我有一个列表,我想要一个简短而快速的方法,将其中一个元素作为第一个元素。 我想使用下面的代码来选择第10个元素,并将其放在第一位。但是寻找更好的解决方案 tempList.Insert(0, tempList[10]); tempList.RemoveAt(11); 如果您不介意其余部分的顺序,您实际上可以在位置0和10交换这两个项目,相信这比插入和删除要好: var other = tempList[0]; tempList[0]=tempList[10]; tempList[10] = o

我有一个列表,我想要一个简短而快速的方法,将其中一个元素作为第一个元素。 我想使用下面的代码来选择第10个元素,并将其放在第一位。但是寻找更好的解决方案

tempList.Insert(0, tempList[10]);
tempList.RemoveAt(11);

如果您不介意其余部分的顺序,您实际上可以在位置0和10交换这两个项目,相信这比插入和删除要好:

var other = tempList[0];
tempList[0]=tempList[10];
tempList[10] = other;
为了便于使用,您甚至可以将其作为列表的扩展,例如:

 public static void Swap<T>(this List<T> list, int oldIndex, int newIndex)
 { 
      // place the swap code here
 }
publicstaticvoidswap(此列表、intoldinex、intnewindex)
{ 
//将交换代码放在这里
}

在某些特殊情况下,您可以获得更好的性能(为了简单起见,我假设该值总是插入到它的起始位置之前):

类程序
{
常量int循环=10000;
常数int=10;
const int itemscont=100000;
常数整数乘数=500;
常量int InsertAt=0;
静态void Main(字符串[]参数)
{
var templast=新列表();
var tempDict=新字典();
对于(int i=0;iInsertAt;j--)
{
tempDict[InsertAt+j]=tempDict[InsertAt+j-1];
}
tempDict[InsertAt]=e;
}
s2.停止();
t2+=s2.经过;
如果(s2.appeased>s1.appeased | | limit==0)
限制=从中提取;
}
sG.Start();
for(int k=0;k=限制)
{
for(int i=0;iInsertAt;j--)
{
tempDict[InsertAt+j]=tempDict[InsertAt+j-1];
}
tempDict[InsertAt]=e;
}
}
}
sG.Stop();
WriteLine(“列表:{0}”,t1);
WriteLine(“字典:{0}”,t2);
WriteLine(“优化:{0}”,sG.appeased);
/***************************
列表:00:00:11.9061505
字典:00:00:08.9502043
优化:00:00:08.2504321
****************************/
}
}

在上面的示例中,使用
字典
存储每个元素的索引。如果
insertAt
takeFrom
之间的差距较小,您将获得更好的结果。随着该间隔的增加,性能将下降。我想您可能需要评估此差距,并根据其值选择最佳分支。

您希望获得的速度有多快?。您的解决方案似乎不是很糟糕。如果您为必须查找索引而烦恼,并且始终可以使用LinkedList,则不要认为这会有任何性能提升。圣堂武士。移除(物体);AddFirst(newobject);这感觉像是一个预优化的案例。您确定这是您的应用程序的瓶颈吗?没有更好的方法可以做到这一点-如果使用
列表
,所有以您的编码方式保持顺序的操作都将是
O(n)
。为了使问题合理,请提供“更好”的标准-到目前为止“接近-需要对问题表现出最低限度的理解”。他不想交换。他想把第n个元素移到列表中的第一个位置(前面)。他的问题不是很清楚——他说他想把第n个元素作为第一个元素,但没有说他是否想保持其余元素的顺序。。。我理解对了吗?对不起,如果是错的-英语不是我的母语:)为什么不
vare=tempDict[10]?除此之外:我无法相信这在某种程度上比使用插入/删除更快。在内部,这些方法复制了一个运行时通常支持的数组。测试表明,在某些
[insertAt,takeFrom]
间隔大小时,它的速度更快。
class Program
{
    const int Loops = 10000;
    const int TakeLoops = 10;
    const int ItemsCount = 100000;
    const int Multiplier = 500;
    const int InsertAt = 0;

    static void Main(string[] args)
    {
        var tempList = new List<int>();
        var tempDict = new Dictionary<int, int>();
        for (int i = 0; i < ItemsCount; i++)
        {
            tempList.Add(i);
            tempDict.Add(i, i);
        }

        var limit = 0;
        Stopwatch
            sG = new Stopwatch(),
            s1 = new Stopwatch(),
            s2 = new Stopwatch();
        TimeSpan
            t1 = new TimeSpan(),
            t2 = new TimeSpan();

        for (int k = 0; k < TakeLoops; k++)
        {
            var takeFrom = k * Multiplier + InsertAt;
            s1.Restart();
            for (int i = 0; i < Loops; i++)
            {
                tempList.Insert(InsertAt, tempList[takeFrom]);
                tempList.RemoveAt(takeFrom + 1);
            }
            s1.Stop();
            t1 += s1.Elapsed;
            s2.Restart();
            for (int i = 0; i < Loops; i++)
            {
                var e = tempDict[takeFrom];
                for (int j = takeFrom - InsertAt; j > InsertAt; j--)
                {
                    tempDict[InsertAt + j] = tempDict[InsertAt + j - 1];
                }
                tempDict[InsertAt] = e;
            }
            s2.Stop();
            t2 += s2.Elapsed;
            if (s2.Elapsed > s1.Elapsed || limit == 0)
                limit = takeFrom;
        }

        sG.Start();
        for (int k = 0; k < TakeLoops; k++)
        {
            var takeFrom = k * Multiplier + InsertAt;
            if (takeFrom >= limit)
            {
                for (int i = 0; i < Loops; i++)
                {
                    tempList.Insert(InsertAt, tempList[takeFrom]);
                    tempList.RemoveAt(takeFrom + 1);
                }
            }
            else
            {
                for (int i = 0; i < Loops; i++)
                {
                    var e = tempDict[takeFrom];
                    for (int j = takeFrom - InsertAt; j > InsertAt; j--)
                    {
                        tempDict[InsertAt + j] = tempDict[InsertAt + j - 1];
                    }
                    tempDict[InsertAt] = e;
                }
            }
        }
        sG.Stop();
        Console.WriteLine("List:       {0}", t1);
        Console.WriteLine("Dictionary: {0}", t2);
        Console.WriteLine("Optimized:  {0}", sG.Elapsed);

        /***************************
        List:       00:00:11.9061505
        Dictionary: 00:00:08.9502043
        Optimized:  00:00:08.2504321
        ****************************/
    }
}