数组列表 (Array List) 进行详细解析,包括中文解释、适用场景、示例代码、测试用例,并特别针对半导体产线或测试机场景提供定制化的代码示例
数组列表 (Array List) 进行详细解析,包括中文解释、适用场景、示例代码、测试用例,并特别针对半导体产线或测试机场景提供定制化的代码示例。
数组列表是项目(https://github.com/aalhour/C-Sharp-Algorithms)中列出的线性数据结构之一,因其简单性和灵活性在多种场景下非常实用。以下内容将基于 C# 类库项目的结构,结合半导体产线应用进行扩展,并确保内容清晰、简洁且全面。
一、数组列表 (Array List) 详解中文解释数组列表是一种动态数组数据结构,基于固定大小的数组实现,但支持动态扩展和收缩。它的核心特点是:
- 随机访问:通过索引直接访问元素,时间复杂度为 O(1)。
- 动态调整:当元素数量超过当前数组容量时,自动扩展数组(通常翻倍)。
- 有序存储:元素按插入顺序存储,支持顺序遍历。
数组列表的常见操作及其时间复杂度:
- 插入(尾部):O(1)(均摊,考虑扩容情况)。
- 插入(任意位置):O(n),需移动后续元素。
- 删除:O(n),需移动后续元素。
- 访问/更新:O(1)。
- 查找(无序):O(n)。
相比固定大小的数组,数组列表提供了动态性;相比链表,它提供了高效的随机访问。适用场景
- 通用场景:
- 存储动态增长的列表数据(如日志记录、任务队列)。
- 需要频繁随机访问的场景(如索引访问元素)。
- 简单的数据集合管理(如临时存储查询结果)。
- 半导体产线场景:
- 测试机:存储晶圆测试结果的序列(如按测试顺序记录缺陷率)。
- 贴片机 (SMT):记录元件贴片位置的列表,支持动态添加和快速访问。
- 优点:
- 高效的随机访问(O(1))。
- 实现简单,内存利用率高。
- 适合尾部插入频繁的场景。
- 缺点:
- 插入/删除非尾部元素效率低(O(n))。
- 扩容可能导致性能抖动。
- 不适合键值对或复杂查询场景。
二、示例代码以下是数组列表的 C# 实现,基于项目的 Data Structures 子项目,简化以突出核心逻辑(类似于 C# 的 List<T>,但自定义实现以展示原理):csharp
using System;
public class ArrayList<T>
{
private T[] items;
private int size;
private int capacity;
private const int DefaultCapacity = 4;
public ArrayList(int initialCapacity = DefaultCapacity)
{
capacity = initialCapacity;
items = new T[capacity];
size = 0;
}
public int Count => size;
public void Add(T item)
{
if (size == capacity)
Resize(capacity * 2); // 容量翻倍
items[size++] = item;
}
public void Insert(int index, T item)
{
if (index < 0 || index > size)
throw new ArgumentOutOfRangeException(nameof(index));
if (size == capacity)
Resize(capacity * 2);
for (int i = size; i > index; i--)
items[i] = items[i - 1];
items[index] = item;
size++;
}
public bool Remove(T item)
{
int index = IndexOf(item);
if (index >= 0)
{
RemoveAt(index);
return true;
}
return false;
}
public void RemoveAt(int index)
{
if (index < 0 || index >= size)
throw new ArgumentOutOfRangeException(nameof(index));
for (int i = index; i < size - 1; i++)
items[i] = items[i + 1];
items[size - 1] = default;
size--;
if (size > 0 && size <= capacity / 4)
Resize(capacity / 2); // 缩容
}
public T this[int index]
{
get
{
if (index < 0 || index >= size)
throw new ArgumentOutOfRangeException(nameof(index));
return items[index];
}
set
{
if (index < 0 || index >= size)
throw new ArgumentOutOfRangeException(nameof(index));
items[index] = value;
}
}
public int IndexOf(T item)
{
for (int i = 0; i < size; i++)
if (Equals(items[i], item))
return i;
return -1;
}
private void Resize(int newCapacity)
{
T[] newItems = new T[newCapacity];
for (int i = 0; i < size; i++)
newItems[i] = items[i];
items = newItems;
capacity = newCapacity;
}
}
代码说明
- 构造:初始化数组,设置默认容量(DefaultCapacity)。
- Add:尾部添加元素,必要时扩容。
- Insert:在指定索引插入元素,需移动后续元素。
- Remove/RemoveAt:删除元素,需移动后续元素并可能缩容。
- this[int index]:提供索引器,支持随机访问。
- Resize:动态调整数组大小,扩容或缩容。
三、测试用例以下是使用 MSTest 框架的单元测试代码:csharp
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public class ArrayListTests
{
[TestMethod]
public void Add_ValidItem_IncreasesCountAndStoresItem()
{
// Arrange
var list = new ArrayList<int>();
list.Add(1);
list.Add(2);
// Act
int count = list.Count;
int firstItem = list[0];
int secondItem = list[1];
// Assert
Assert.AreEqual(2, count);
Assert.AreEqual(1, firstItem);
Assert.AreEqual(2, secondItem);
}
[TestMethod]
public void Insert_ValidIndex_InsertsCorrectly()
{
// Arrange
var list = new ArrayList<int>();
list.Add(1);
list.Add(3);
// Act
list.Insert(1, 2);
// Assert
Assert.AreEqual(3, list.Count);
Assert.AreEqual(1, list[0]);
Assert.AreEqual(2, list[1]);
Assert.AreEqual(3, list[2]);
}
[TestMethod]
public void Remove_ValidItem_RemovesCorrectly()
{
// Arrange
var list = new ArrayList<int>();
list.Add(1);
list.Add(2);
// Act
bool removed = list.Remove(1);
// Assert
Assert.IsTrue(removed);
Assert.AreEqual(1, list.Count);
Assert.AreEqual(2, list[0]);
}
[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void Access_InvalidIndex_ThrowsException()
{
// Arrange
var list = new ArrayList<int>();
// Act
int item = list[0]; // 应抛出异常
}
}
测试说明
- 测试添加功能,确保元素正确存储且计数增加。
- 测试插入功能,验证元素插入正确位置且后续元素移动。
- 测试删除功能,确认元素移除和列表调整。
- 测试边界情况,确保无效索引抛出异常。
四、半导体产线示例在半导体测试机中,数组列表可用于存储晶圆测试结果的序列(如按测试顺序记录缺陷率),支持动态添加和快速访问。以下是一个具体场景:测试机按顺序记录晶圆的测试数据,需要快速访问特定测试结果或追加新数据。示例代码csharp
public class WaferTestRecord
{
public int WaferId { get; set; }
public double DefectRate { get; set; }
public DateTime TestTime { get; set; }
public WaferTestRecord(int waferId, double defectRate, DateTime testTime)
{
WaferId = waferId;
DefectRate = defectRate;
TestTime = testTime;
}
}
public class WaferTestManager
{
private ArrayList<WaferTestRecord> testRecords;
public WaferTestManager()
{
testRecords = new ArrayList<WaferTestRecord>();
}
public void AddTestRecord(int waferId, double defectRate, DateTime testTime)
{
testRecords.Add(new WaferTestRecord(waferId, defectRate, testTime));
}
public WaferTestRecord GetTestRecord(int index)
{
return testRecords[index];
}
public bool RemoveTestRecord(int waferId)
{
for (int i = 0; i < testRecords.Count; i++)
{
if (testRecords[i].WaferId == waferId)
{
testRecords.RemoveAt(i);
return true;
}
}
return false;
}
public int Count => testRecords.Count;
}
测试用例csharp
[TestMethod]
public void WaferTestManager_AddAndGetTestRecord_ReturnsCorrectRecord()
{
// Arrange
var manager = new WaferTestManager();
var testTime1 = new DateTime(2025, 8, 6, 13, 0, 0);
var testTime2 = new DateTime(2025, 8, 6, 13, 1, 0);
manager.AddTestRecord(1001, 0.05, testTime1);
manager.AddTestRecord(1002, 0.03, testTime2);
// Act
var record = manager.GetTestRecord(0);
// Assert
Assert.IsNotNull(record);
Assert.AreEqual(1001, record.WaferId);
Assert.AreEqual(0.05, record.DefectRate);
}
[TestMethod]
public void WaferTestManager_RemoveTestRecord_RemovesCorrectly()
{
// Arrange
var manager = new WaferTestManager();
var testTime = new DateTime(2025, 8, 6, 13, 0, 0);
manager.AddTestRecord(1001, 0.05, testTime);
// Act
bool removed = manager.RemoveTestRecord(1001);
int count = manager.Count;
// Assert
Assert.IsTrue(removed);
Assert.AreEqual(0, count);
}
半导体场景说明
- 场景:测试机按顺序记录晶圆测试结果(如缺陷率),需要快速访问特定测试记录(通过索引)或追加新记录。
- 优势:数组列表的 O(1) 随机访问适合按索引查询测试结果,尾部添加操作高效(O(1) 均摊)。
- 局限性:如果需要频繁插入或删除非尾部记录,性能较差(O(n)),可考虑链表或跳表。
- 优化建议:对于大规模数据,可预分配较大初始容量以减少扩容开销。
五、贴片机场景示例在贴片机 (SMT) 中,数组列表可用于存储元件的贴片位置序列,按贴片顺序记录,支持动态添加和快速访问。示例代码csharp
public class ComponentPlacementRecord
{
public int ComponentId { get; set; }
public double X { get; set; }
public double Y { get; set; }
public DateTime PlacementTime { get; set; }
public ComponentPlacementRecord(int componentId, double x, double y, DateTime placementTime)
{
ComponentId = componentId;
X = x;
Y = y;
PlacementTime = placementTime;
}
}
public class SmtPlacementManager
{
private ArrayList<ComponentPlacementRecord> placements;
public SmtPlacementManager()
{
placements = new ArrayList<ComponentPlacementRecord>();
}
public void AddPlacement(int componentId, double x, double y, DateTime placementTime)
{
placements.Add(new ComponentPlacementRecord(componentId, x, y, placementTime));
}
public ComponentPlacementRecord GetPlacement(int index)
{
return placements[index];
}
public int Count => placements.Count;
}
// 测试用例
[TestMethod]
public void SmtPlacementManager_AddAndGetPlacement_ReturnsCorrectRecord()
{
// Arrange
var manager = new SmtPlacementManager();
var placementTime = new DateTime(2025, 8, 6, 13, 0, 0);
manager.AddPlacement(2001, 10.5, 20.5, placementTime);
// Act
var record = manager.GetPlacement(0);
// Assert
Assert.IsNotNull(record);
Assert.AreEqual(2001, record.ComponentId);
Assert.AreEqual(10.5, record.X);
Assert.AreEqual(20.5, record.Y);
}
贴片机场景说明
- 场景:贴片机按顺序记录元件的贴片位置和时间,支持快速访问特定贴片记录(如检查第 n 个元件的坐标)。
- 优势:数组列表的 O(1) 随机访问适合按索引查询贴片记录,尾部添加高效。
- 局限性:如果需要按元件 ID 查找,需线性搜索(O(n)),可结合哈希表优化。
- 优化建议:可结合快速排序(Quick Sort)对贴片记录按时间或坐标排序,支持后续分析。
六、总结与注意事项
- 数组列表特点:
- 高效的随机访问(O(1))和尾部添加(O(1) 均摊)。
- 适合顺序存储和动态增长的场景。
- 插入/删除非尾部元素效率较低(O(n))。
- 半导体产线应用:
- 测试机:存储晶圆测试结果序列,支持快速访问。
- 贴片机:记录元件贴片位置序列,支持动态添加。
- 优化建议:
- 预分配容量以减少扩容开销。
- 对于频繁插入/删除的场景,可考虑链表或跳表。
- 结合哈希表或跳表支持键值查询或范围查询。
- 与其他数据结构的对比:
- 相比链表,数组列表提供高效随机访问,但插入/删除效率较低。
- 相比跳表,数组列表不支持高效的键值查询,但实现更简单,适合顺序存储。
如果您需要更详细的数组列表实现(如并发支持)、其他算法或数据结构的解析,或针对特定半导体设备(如晶圆切割机)的定制代码,请进一步说明,我将提供更深入的示例!
更多推荐
所有评论(0)