C# 使列表中的元素作为第一个元素的最快方法
我有一个列表,我想要一个简短而快速的方法,将其中一个元素作为第一个元素。 我想使用下面的代码来选择第10个元素,并将其放在第一位。但是寻找更好的解决方案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
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
****************************/
}
}