🏆 作者简介,愚公搬代码 🏆《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,阿里云专家博主,腾讯云优秀博主,掘金优秀博主,51CTO博客专家等。 🏆《近期荣誉》:2022年CSDN博客之星TOP2,2022年华为云十佳博主等。
🏆《博客内容》:.NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。
🏆🎉欢迎 👍点赞✍评论⭐收藏
数据结构是计算机科学中的一个重要概念,它描述了数据之间的组织方式和关系,以及对这些数据的访问和操作。常见的数据结构有:数组、链表、栈、队列、哈希表、树、堆和图。
列表是一种线性数据结构,它由一系列元素组成,每个元素可以有一个前驱和一个后继。列表的基本思想是将元素按照一定顺序组织起来,并且支持在列表中插入、删除和遍历元素。
列表可以使用数组或链表实现。在数组实现中,列表的元素在内存中是连续的,而在链表实现中,元素可以在内存中任意位置。列表的一个重要特点是支持快速随机访问,因为元素在数组实现中是连续存储的。
列表的操作包括插入、删除、遍历等。在数组实现中,插入和删除操作需要将后续元素进行移动,所以时间复杂度为O(n)。而在链表实现中,插入和删除操作只需要修改节点的指针,时间复杂度为O(1)。遍历列表需要将每个元素依次访问,时间复杂度为O(n)。
列表具有广泛的应用,例如存储数组、字符串等数据、实现队列、栈、哈希等数据结构,以及其它需要按序访问元素的场合。
1、自定义列表的初始化
C#中的列表可以使用以下语法进行初始化:
List<int> myList = new List<int>() { 1, 2, 3, 4, 5 };
List<int> myList = new List<int>();
myList.Add(1);
myList.Add(2);
myList.Add(3);
int[] myArray = {1,2,3,4,5};
List<int> myList = new List<int>(myArray);
注意,以上初始化方法都需要在列表变量声明时进行。如果需要在后续添加元素,可以使用Add方法进行添加。
2、内置列表的初始化
当然C#中链表的初始化可以使用LinkedList类。以下是示例代码:
LinkedList<int> list = new LinkedList<int>();
这将创建一个空链表,你可以通过使用AddLast()方法将元素添加到末尾,使用AddFirst()方法将元素添加到开头。你可以使用foreach循环遍历链表中的元素。例如:
list.AddLast(1);
list.AddLast(2);
list.AddFirst(3);
foreach (int item in list)
{
Console.WriteLine(item);
}
这将输出:
3
1
2
在C#中,可以通过以下方式来访问列表中的元素:
可以使用方括号和元素的索引值来访问特定位置的元素。例如,myList[0]
将访问列表中的第一个元素。
可以使用循环遍历整个列表中的元素。例如,使用foreach
循环可以遍历列表中的所有元素:
foreach (var item in myList)
{
Console.WriteLine(item);
}
C#中的LINQ操作可用于查询和操作列表。可以使用Where
、Select
、OrderBy
等函数进行筛选、投影和排序等操作。例如,以下代码将从列表中选择所有大于10的元素:
var newList = myList.Where(x => x > 10).ToList();
C#中的列表类(List)提供了许多方法来插入和删除元素。以下是一些常用的方法:
List<int> myList = new List<int>();
myList.Add(1);
List<int> myList = new List<int>();
myList.Insert(0, 1);
List<int> myList = new List<int>{1, 2, 3};
myList.Remove(2); // myList变成了{1, 3}
List<int> myList = new List<int>{1, 2, 3};
myList.RemoveAt(1); // myList变成了{1, 3}
List<int> myList = new List<int>{1, 2, 3};
myList.Clear(); // myList变成了{}
在C#中,有多种方法可以遍历列表元素:
您可以使用 for 循环来迭代列表中的元素。这是最基本的方法,因为您可以通过索引号访问列表元素。例如:
List<int> list = new List<int>() { 1, 2, 3, 4, 5 };
for (int i = 0; i < list.Count; i++)
{
Console.WriteLine(list[i]);
}
使用 foreach 循环可以更加简洁的实现对列表元素的迭代。例如:
List<int> list = new List<int>() { 1, 2, 3, 4, 5 };
foreach (var item in list)
{
Console.WriteLine(item);
}
使用LINQ的查询语句,可以方便地过滤、排序、映射和聚合列表数据。例如:
List<int> list = new List<int>() { 1, 2, 3, 4, 5 };
var filteredList = from i in list
where i > 3
select i;
foreach (var item in filteredList)
{
Console.WriteLine(item);
}
您可以使用 Lambda 表达式来创建委托,以便在遍历列表时执行特定操作。例如:
List<int> list = new List<int>() { 1, 2, 3, 4, 5 };
list.ForEach(item =>
Console.WriteLine(item));
在C#中进行列表拼接的方法有以下几种:
1.使用List.AddRange方法
List.AddRange方法可以将一个列表中的元素全部添加到另外一个列表中。示例如下:
List<int> list1 = new List<int> { 1, 2, 3 };
List<int> list2 = new List<int> { 4, 5, 6 };
list1.AddRange(list2);
2.使用LINQ的Concat方法
使用LINQ的Concat方法可以将两个列表连接起来。示例如下:
List<int> list1 = new List<int> { 1, 2, 3 };
List<int> list2 = new List<int> { 4, 5, 6 };
List<int> result = list1.Concat(list2).ToList();
3.使用List.InsertRange方法
使用List.InsertRange方法可以在指定位置插入一个列表中的元素。示例如下:
List<int> list1 = new List<int> { 1, 2, 3 };
List<int> list2 = new List<int> { 4, 5, 6 };
list1.InsertRange(1, list2);
以上方法都可以实现列表的拼接操作,具体使用哪种方法可以根据实际情况选择。
可以使用List<T>类的Sort()方法来对列表进行排序。该方法接受一个参数,即一个委托,用于比较两个元素的大小关系。
例如,对一个包含整数的List进行升序排序:
List<int> myList = new List<int>{ 4, 2, 8, 1, 5 };
myList.Sort((a, b) => a.CompareTo(b));
也可以使用lambda表达式实现同样的功能:
myList.Sort((a, b) => a - b);
如果要进行降序排序,只需将比较委托中的参数顺序交换即可:
myList.Sort((a, b) => b.CompareTo(a)); //或者 myList.Sort((a, b) => b - a);
在C#中,可以通过自定义一个类来实现列表的功能,以下是一个简单的实现示例:
public class MyList<T>
{
private T[] elements;
private int count;
public MyList(int capacity)
{
elements = new T[capacity];
count = 0;
}
public int Count
{
get { return count; }
}
public void Add(T element)
{
if (count == elements.Length)
{
Array.Resize(ref elements, elements.Length * 2);
}
elements[count++] = element;
}
public T Get(int index)
{
if (index < 0 || index >= count)
{
throw new IndexOutOfRangeException();
}
return elements[index];
}
public void Set(int index, T element)
{
if (index < 0 || index >= count)
{
throw new IndexOutOfRangeException();
}
elements[index] = element;
}
public void RemoveAt(int index)
{
if (index < 0 || index >= count)
{
throw new IndexOutOfRangeException();
}
for (int i = index; i < count - 1; i++)
{
elements[i] = elements[i + 1];
}
count--;
}
}
以上定义了一个类型参数为T的泛型类MyList<T>,其中包含了增加元素、获取元素、设置元素、删除元素等常见的列表操作方法。使用示例:
MyList<string> myList = new MyList<string>(10);
myList.Add("hello");
myList.Add("world");
myList.Add("!");
Console.WriteLine(myList.Get(1)); //输出:world
myList.Set(0, "hi");
myList.RemoveAt(2);
Console.WriteLine(myList.Count); //输出:2
列表(List)是一种基本的数据结构,可以存储一组元素,并按照一定的顺序排列。列表的优点和缺点如下:
优点:
缺点:
列表在数据结构中被广泛应用,并且是一种基本的数据结构类型之一。以下是列表的一些应用场景:
列表是一种非常常用的数据结构类型,它可以用于各种不同的应用场景,帮助我们更方便地管理和处理数据。
数组在C#中最早出现的。在内存中是连续存储的,所以它的索引速度非常快,而且赋值与修改元素也很简单。
<span style="font-family:SimSun;font-size:18px;">//数组
string[] s=new string[2];
//赋值
s[0]="a";
s[1]="b";
//修改
s[1]="a1";
</span>
优点:数组在内存中是连续存储的、所以它的索引速度是非常快的、时间复杂度为O(1)、而且它的赋值/修改/获取元素也是非常简单的。
缺点:
1、定义数组的时候需要指定数组的长度(过长会造成内存浪费、过短会导致程序异常System.IndexOutOfRangeException:"索引超出数组界限")
2、插入和删除元素效率低、也比较麻烦。
在不清楚数组长度的时候、就很尴尬了。 所以C#提供了ArrayList了来处理这些问题...
使用大小会根据需要动态增加的数组。
//初始化
ArrayList list = new ArrayList();
//添加元素
list.Add(1);
list.Add("A");
list.Add(0.1);
//修改元素
list[2] = "B";
//指定索引插入元素
list.Insert(1, "ABC");
//移除元素
list.RemoveAt(1);
优点:
1、ArrayList大小会根据需要动态增加的数组。
2、实现了IList接口、可以方便的对数据进行添加、插入和删除。
缺点:
1、ArrayList会把插入的数据都当做object类型来存储、在操作数据的时候可能会因为类型不匹配而出现异常、它是非类型安全的对象。
2、由于存储的是object类型、在使用的时候进行类型转换、会造成装箱拆箱、从而损耗性能。
装箱:把值类型转换成引用类型;
拆箱:把引用类型转换成值类型。
//装箱
int i = 1;
object obj = (object)i;
//拆箱
int j = (int)obj;
由于ArrayList存在类型不安全、装箱拆箱损耗性能。.NET Framework 2.0 推出了List<T>
表示可通过索引访问的对象的强类型列表。 提供用于对列表进行搜索、排序和操作的方法。
//初始化
List<int> list = new List<int>();
//添加
list.Add(12);
list.Add(34);
//编译器会进行类型验证、下面代码编译失败
//list.Add("ABC");
//修改
list[0] = 1;
//移除
list.RemoveAt(0);
优点:由于泛型List是强类型、编译器会验证类型安全。这样就避免了类型的不安全、以及数据强制转换导致装箱拆箱损耗性能。
备注:哈希表(散列),就是数组的升级版通过hash运算快速查找到值,数组下标就是哈希值。(前512是int,后才是哈希)