C# 在列表/数组中查找元素的更快方法

C# 在列表/数组中查找元素的更快方法,c#,arrays,list,C#,Arrays,List,我正在开发一个有限元程序,其中我的输入是一个节点列表(ListNodes double[node_index,x,y,z]其中(x,y,z)是笛卡尔坐标系中节点的坐标),一个元素列表(ListElements double[element_index,node1_index,node2_index,等等)]和每个元素的一些数据(双[元素索引]) 我必须不断搜索有限元模型中某个给定区域的数据,区域是由某个边界定义的[xmin,xmax,ymin,ymax,zmin,zmax]。为了检索该区域的数据

我正在开发一个有限元程序,其中我的输入是一个节点列表
(ListNodes double[node_index,x,y,z]
其中
(x,y,z)
是笛卡尔坐标系中节点的坐标),一个元素列表
(ListElements double[element_index,node1_index,node2_index,等等)]
和每个元素的一些数据
(双[元素索引])

我必须不断搜索有限元模型中某个给定区域的数据,区域是由某个边界定义的
[xmin,xmax,ymin,ymax,zmin,zmax]
。为了检索该区域的数据,我首先查找其节点(搜索节点时,
(x,y,z)
位于边界内)然后查找它的元素,最后检索这些元素的数据

功能1:检查节点是否在区域内

private static bool有界(双[]节点,双xmin,双ymin,双zmin,双xmax,双ymax,双zmax)
{
return((node[1]>=xmin)&&&(node[1]=ymin)&&(node[2]=zmin)&(node[3]是有界的(node,xmin,ymin,zmin,xmax,ymax,zmax)).ToList().ForEach(node=>zoneNodes.Add(Convert.ToInt32(node[0]);
功能3:查找区域内的元素

//在所有元素上循环
for(int j=0;j
功能4:对于区域内的每个元素,我们可以检索数据

但是,此过程非常缓慢。是否有任何方法可以改进此过程以提高性能


谢谢,

我不确定这段代码是否是您想要的

请退房

减少计算时间的主要方法是使用字典

字典的时间复杂度通常为O(1)

公共类示例
{
//向该变量添加数据。
System.Collections.Generic.Dictionary pointPerElement=新的System.Collections.Generic.Dictionary();
System.Collections.Generic.Dictionary cubePerElement=新的System.Collections.Generic.Dictionary();
System.Collections.Generic.List elements=新的System.Collections.Generic.List();
私有无效计算()
{
foreach(元素中的var元素)
{
if(pointPerElement.ContainsKey(元素)==false | | cubePerElement.ContainsKey(元素)==false)
{
继续;
}
变量点=点元素[元素];
var cube=立方相关元素[元素];
if(立方体(点))
{
//向列表中添加点、立方体或元素。
}
}
}
}
私有结构点
{
公共双x;
公共双y;
公共双z;
公共点(双x、双y、双z)
{
这个.x=x;
这个。y=y;
这个。z=z;
}
公共静态点GetVector(点从、点到)
{
返回新点(to.x-from.x,to.y-from.y,to.z-from.z);
}
}
私有结构范围
{
公共双敏;
公共双最大值;
公共双倍长度;
公共双中心;
公共范围(双最小值、双最大值)
{
系统诊断调试断言(最小值<最大值);
this.min=min;
this.max=max;
这个长度=最大-最小;
该中心=长度*0.5;
}
}
私有结构多维数据集
{
公共范围;
公共射程;
公共范围zRange;
私人点中心;
公共多维数据集(范围xRange、范围yRange、范围zRange)
{
这个.xRange=xRange;
this.yRange=yRange;
this.zRange=zRange;
this.center=新点(xRange.center、yRange.center、zRange.center);
}
公共边界(点-点)
{
var v=点.GetVector(点,此.center);
var doubledV=新点(v.x*2,v.y*2,v.z*2);

return doubledV.x请看一看R-tree嗨,谢谢你的建议,但是为什么要使用Rtree?如果我使用Rtree,我必须重新索引我的所有元素编号?R-tree是我们用于空间数据的典型数据结构。从你提供的代码中可以看出,从技术上讲,不要使用元素编号:相反,你正在解决“如果元素在区域中”问题-任务R树正是为此而设计的
public class Sample
{
    // add data to that variables.
    System.Collections.Generic.Dictionary<double, Point> pointPerElement = new System.Collections.Generic.Dictionary<double, Point>();
    System.Collections.Generic.Dictionary<double, Cube> cubePerElement = new System.Collections.Generic.Dictionary<double, Cube>();
    System.Collections.Generic.List<double> elements = new System.Collections.Generic.List<double>();

    private void Calculate()
    {
        foreach (var element in elements)
        {
            if (pointPerElement.ContainsKey(element) == false || cubePerElement.ContainsKey(element) == false)
            {
                continue;
            }
            var point = pointPerElement[element];
            var cube = cubePerElement[element];
            if (cube.IsBouded(point))
            {
                // add point or cube or element to list.
            }
        }
    }
}

private struct Point
{
    public double x;
    public double y;
    public double z;

    public Point(double x, double y, double z)
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public static Point GetVector(Point from, Point to)
    {
        return new Point(to.x - from.x, to.y - from.y, to.z - from.z);
    }
}

private struct Range
{
    public double min;
    public double max;

    public double length;
    public double center;

    public Range(double min, double max)
    {
        System.Diagnostics.Debug.Assert(min < max);
        this.min = min;
        this.max = max;
        this.length = max - min;
        this.center = length * 0.5;
    }
}

private struct Cube
{
    public Range xRange;
    public Range yRange;
    public Range zRange;

    private Point center;

    public Cube(Range xRange, Range yRange, Range zRange)
    {
        this.xRange = xRange;
        this.yRange = yRange;
        this.zRange = zRange;

        this.center = new Point(xRange.center, yRange.center, zRange.center);
    }

    public bool IsBouded(Point point)
    {
        var v = Point.GetVector(point, this.center);
        var doubledV = new Point(v.x * 2, v.y * 2, v.z * 2);
        return doubledV.x <= this.xRange.length
            && doubledV.y <= this.yRange.length
            && doubledV.z <= this.yRange.length;
    }
}