c#常用的数据结构

Array数组

内存上连续存储,

数组是引用类型而不是值类型。

优点:

按照索引查询元素速度很快。

按照索引遍历数组很方便。

缺点:

声明数组时大小必须确定,且大小不能改变。

添加和删除元素的速度很慢,因为需要移动其它元素。

数组只能存储一种数据类型。

一维数组的声明和创建形式:

数组类型 [ ] 数组名 = new 数组类型 [数组长度]

int [ ] one = new int [5] { 1, 2, 3, 4, 5 };

相当于MFC 的CArray

二维数组

int [,] one = new int [2,3];

位数组 BitArray

ArrayList

ArrayList类相当于一种高级的动态数组,它是Array类的升级版本.本质是一个object类型的数组.ArrayList类是引用类型。连续的内存。在存和使用值类型的对象时或发生装箱/拆箱的操作。

using System .Collections ;

ArrayList List=new ArrayList();

ArrayList 转Array的函数

Array ToArray(Type type);

ArrayList List = new ArrayList();

for (int i = 0; i < 10; i++)

List.Add(i);

int[] values = (int[])List.ToArray(typeof(int)); //正确

List

List<T> 等效于ArrayList,性能比Arraylist高。 List的内部是用数组实现的,而不是链表,所以也是连续内存。当元素被添加到List中时,List的容量会根据需要自动增加,通过重新分配内部数组。

List<int> primeNumbers = new List<int>();

List 转Array的函数

List<int> primeNumbers = new List<int>();

for (int i = 0; i < 10; i++)

primeNumbers.Add(i);

int[] Numbers = primeNumbers.ToArray();

Array转 List 的函数

int [] array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ,10};

List<int > list = new List<int >(array);

相当于 c++ 的vector

LinkedList(双向链表)

内存非连续的、非顺序的存储结构,无法通过下标查找元素,在查找链表元素时,总是从头结点开始查找;动态调整容量。

查询复杂度为 O(n),操作复杂度为 O(1)。

遍历:

LinkedListNode<int> nowNode=linkedList.First;

while(nowNode!=null)

{

nowNode=nowNode.Next;

}

或者

foreach(int item in linkedList)

{

Console.WriteLine(item);

}

Array转Linked List 的函数

int [] array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ,10};

LinkedList<int > linkedList = new LinkedList<int >(array);

相当于c++的 list

Stack(栈)

栈是有顺序的,是一片连续的内存域,保持着先进后出的原则。

Stack<string> numbers = new Stack<string>();

numbers.Push("one");

string str = numbers.Peek(); //获取不出栈

str = numbers.Pop();//获取并出栈

Queue(队列)

先进先出,存在装箱拆箱,存储任意类型,无法获取指定位置元素,只能取出最先存储的元素。

Queue<string> queue = new Queue<string>();

//向队列中添加元素

ueue.Enqueue ("老一");

queue.Enqueue ("老二");

queue.Dequeue ();获取并移除队列中队首的元素

queue.Peek ();返回顶部的对象而不将其从 队列 中移除

HashSet

是基于哈希表的原理实现的,根据key直接访问存储位置的数据结构

无序、不重复;

插入、查找时间复杂度为O(1);

不使用索引;

容量不足时自动扩容,但扩容成本高;

HashSet<string> hashSet = new HashSet<string>();

hashSet.Add ("123");

hashSet.Add ("456");

//转换成List集合

hashSet.ToList();

相当于STL 的hash_set或者说unordered_set

SortedSet

基于红黑树实现,有序、不重复的集合

SortedSet<string> SortSet = new SortedSet<string>();

SortSet.Add ("123");

hashSet.Add ("456");

foreach (var index in SortSet)

{

}

//转换成List集合

SortSet.ToList();

相当于STL的set

Hashtable

基于哈希表实现,一系列基于键的哈希代码组织起来的 键/值对 。它使用键来访问集合中的元素。

特点:

key(键) 是唯一的,不可重复,

只能通过 key 查询对应 的value

Hashtable hashtable = new Hashtable();

hashtable.Add(0, 1);

hashtable.Add(1, 'a');

foreach (var key in hashtable.Keys)

{

var tablekey = key;

var value = hashtable[key];

}

相当于STL 的unordered_map (hash_map)

Dictionary(字典)

基于哈希表实现,字典中的key值是唯一的。

字典底层将数据储存在数组里面,通过哈希函数建立Key------Value的对应关系,利用拉链法处理哈希冲突。另外,字典是线程不安全的,如果需要线程安全,需要自己加锁

Dictionary<int, string> _testDic = new Dictionary<int, string>();

_testDic.Add (24, "Canon");

// 注意相同相同Key值只能Add一次

_testDic.Add (34, "Jason"); // foreach遍历

foreach (var kvp in _testDic)

{

Console .WriteLine ("Key = {0}, Value = {1}", kvp.Key , kvp.Value );

}

相当于STL 的unordered_map (hash_map)

Dictionary和Hashtable对比

Dictionary<K,V>是泛型的,当K或V是值类型时,其速度远远超过Hashtable。

由于 Hashtable 和 Dictionary 同时存在, 在使用场景上必然存在选择性, 并不任何时刻都能相互替代.

1\] 单线程程序中推荐使用 Dictionary, 有泛型优势, 且读取速度较快, 容量利用更充分. \[2\] 多线程程序中推荐使用 Hashtable, 默认的 Hashtable 允许单线程写入, 多线程读取, 对 Hashtable 进一步调用 Synchronized() 方法可以获得完全线程安全的类型. 而 Dictionary 非线程安全, 必须人为使用 lock 语句进行保护, 效率大减. \[3\] Dictionary 有按插入顺序排列数据的特性 (注: 但当调用 Remove() 删除过节点后顺序被打乱), 因此在需要体现顺序的情境中使用 Dictionary 能获得一定方便. ###### ******SortedDictionary****** 基于使用红黑树实现的键值对集合。 特点: 有序,键唯一 只能通过 key(键) 查询对应 的 value(值) SortedDictionary 可对未排序的数据执行更快的插入和移除操作:它的时间复杂度为 O(log n) SortedDictionary\ My_sdict = new SortedDictionary\(); My_sdict.*Add* (004, "Ask.com"); My_sdict.*Add* (003, "Yahoo"); foreach (var kvp in My_sdict) { *Console* .*WriteLine* ("Key = {0}, Value = {1}", kvp.*Key* , kvp.*Value* ); } 相当于STL的map ###### ******SortedList****** 排序列表是数组和哈希表的组合,使用索引访问各项,则它是一个动态数组,如果您使用键访问各项,则它是一个哈希表。集合中的各项总是按键值排序。 ###### 总结 数据结构 类型及备注 插入和删除 查找 Array 顺序存储的线性表、定长 不支持(这里的插入与删除指会更改表长的行为) O(N) LinkedList\ 链式存储的线性表、不定长 O(1) O(N) List\ 顺序存储的线性表、不定长、动态扩容 O(N),结尾则是O(1) O(N) Stack\ 栈、不定长、动态扩容 O(1) 只能访问栈顶 Queue\ 队列、不定长、动态扩容 O(1) 只能访问队列头部 Dictionary\ 保存键值对、使用开散列法、不定长、动态扩容、长度总为质数 O(1) O(1) SortedList\ 保存键值对、内部使用数组实现、保持有序、不定长 O(logN) O(logN) SortedDictionary\ 保存键值对、内部使用红黑树实现、保持有序、不定长 O(logN) O(logN) HashSet\ 使用开散列法、不定长、动态扩容、长度总为质数、是不含值的字典,故复杂度和它完全相同 O(1) O(1) SortedSet\ 内部使用红黑树实现、保持有序、不定长、是不含值的SortedDictionary\,故复杂度和它完全相同 O(logN) O(logN)

相关推荐
江沉晚呤时4 小时前
在 C# 中调用 Python 脚本:实现跨语言功能集成
python·microsoft·c#·.net·.netcore·.net core
Oberon4 小时前
Avalonia硬配.NET Framework 4.8
c#·.net·avalonia·.net framework
没书读了5 小时前
考研复习-数据结构-第六章-图
数据结构
future14127 小时前
C#进阶学习日记
数据结构·学习
喵叔哟7 小时前
3. 【Blazor全栈开发实战指南】--Blazor是什么?为什么选择Blazor?
c#·.netcore
钢铁男儿9 小时前
C# 接口(接口可以继承接口)
java·算法·c#
ChoSeitaku10 小时前
NO.4数据结构数组和矩阵|一维数组|二维数组|对称矩阵|三角矩阵|三对角矩阵|稀疏矩阵
数据结构·人工智能·矩阵
Paper Clouds11 小时前
代码随想录|图论|15并查集理论基础
数据结构·算法·leetcode·深度优先·图论
Paper Clouds11 小时前
代码随想录|图论|14有向图的完全可达性
数据结构·算法·深度优先·图论·宽度优先
闻缺陷则喜何志丹13 小时前
【并集查找 虚拟节点】P1783 海滩防御|省选-
数据结构·c++·洛谷·并集查找·虚拟节点