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)

相关推荐
rigidwill6663 分钟前
LeetCode hot 100—子集
数据结构·c++·算法·leetcode·职场和发展
不吃洋葱.2 小时前
力扣448.找到数组中所有消失的元素
数据结构·算法·leetcode
佟格湾3 小时前
聊透多线程编程-线程池-6.C# APM(异步编程模型)
开发语言·后端·c#·多线程
昂子的博客3 小时前
热门面试题第15天|最大二叉树 合并二叉树 验证二叉搜索树 二叉搜索树中的搜索
java·数据结构·算法
我不是程序猿儿4 小时前
【C#】一种优雅的基于winform的串口通信管理
stm32·单片机·c#
扫地僧0096 小时前
【中大厂面试题】腾讯 后端 校招 最新面试题
java·数据结构·后端·算法·面试·排序算法
天天年年天天。6 小时前
在 Linux 或 Unix 系统中使用 pthread_create 创建新线程的步骤
linux·数据结构
大锦终9 小时前
【C++】模板进阶
c语言·开发语言·数据结构·c++
向宇it9 小时前
【unity游戏开发入门到精通——动画篇】Animator反向动力学(IK)
开发语言·unity·c#·编辑器·游戏引擎
Liu_某10 小时前
c# 运用策略模式与模板方法模式实例
c#·策略模式