数据结构
数据结构的存储方式只有两种:数组(顺序存储)和链表(链式存储)。
对于任何数据结构,其基本操作无非遍历 + 访问,再具体一点就是:增删改查。数据结构种类很多,但它们存在的目的都是在不同的应用场景,尽可能高效地增删改查。
栈
System.Collections.Generic.Stack
队列
System.Collections.Generic.Queue
散列表
- System.Collections.Generic.Dictionary<TKey,TValue>,字典
- System.Collections.Hashtable,哈希表
字典所使用的为顺序存储,它解决冲突的方式为拉链法。即一个地址存储一个链表,链表中存储哈希函数H(key)相等的值。
哈希表通过散列算法,是无序存储的,它解决冲突的方式是二度哈希。即通关不同的哈希函数使每个元素的位置各不相同。
单线程程序中推荐使用 Dictionary, 有泛型优势, 且读取速度较快, 容量利用更充分。
多线程程序中推荐使用 Hashtable, 默认的 Hashtable 允许单线程写入, 多线程读取, 对 Hashtable 进一步调用 Synchronized()方法可以获得完全线程安全的类型. 而Dictionary 非线程安全, 必须人为使用 lock 语句进行保护, 效率大减。
堆
数组形式。基于数组的列表数据结构,可参考微软的ArrayList;泛型实现ArrayList<T>。
树
链表形式。
一般二叉树的实现,可参考树的接口。
二叉搜索树
实现快速搜索。正常的情况下,查找的时间复杂度为 O(logn)。
特点:左子树的结点值比父亲结点小,而右子树的结点值比父亲结点大。
缺点:可能会退化成一条链表。
具体实现可参考二叉查找树(BST)。
AVL 树
平衡二叉树,解决二叉查找树退化成一条线性链表的问题。最坏的查找时间复杂度也为 O(logn)。
特点:
- 具有二叉查找树的全部特性。
- 单个结点的左子树和右子树的高度差至多等于1。
缺点:每次进行插入/删除结点的时候,几乎都会破坏平衡树的第二个规则,频繁的左旋和右旋,会使平衡树的性能大打折扣。
偏重查询时优选。比如 windows进程地址空间管理等。
具体实现可参考高度平衡树(AVL)。
红黑树
一种不大严格的平衡树。在最坏情况下,也能在 O(logn) 的时间复杂度查找到某个结点。
用非严格的平衡换取增删结点时旋转次数的降低。
特点:
- 具有二叉查找树的特点。
- 根结点是黑色的。
- 每个叶子结点都是黑色的空结点(NIL),也就是说,叶子结点不存数据。
- 任何相邻的结点都不能同时为红色,也就是说,红色结点是被黑色结点隔开的。
- 每个结点,从该结点到达其可达的叶子结点,所有路径都包含相同数目的黑色结点。
插入、删除效率更高,适用于 STL、Linux进程调度等操作性能稳定的工业级应用。
具体实现可参考红黑树(RBtree)。
字典树
区间树
B 树
维护数据库。
图
邻接表
邻接矩阵
二分图
并查集
线段树
字典树
树状数组
算法
基本算法
八种排序
DFS
BFS
二分查找
回溯
分治
递归
动态规划
拓扑排序
贪心
Sliding Window
扫描线
蓄水池
flood fill
LeetCode + C#
链表
题目 | 解决方案 | 时间复杂度 | 空间复杂度 |
---|---|---|---|
2. Add Two Numbers | Code | O(n) | O(1) |
19. Remove Nth Node From End of List | Code | O(n) | O(1) |
21. Merge Two Sorted Lists | Code | O(log n) | O(1) |
23. Merge k Sorted Lists | Code | O(log n) | O(1) |
24. Swap Nodes in Pairs | Code | O(n) | O(1) |
25. Reverse Nodes in k-Group | Code | O(log n) | O(1) |
61. Rotate List | Code | O(n) | O(1) |
82. Remove Duplicates from Sorted List II | Code | O(n) | O(1) |
83. Remove Duplicates from Sorted List | Code | O(n) | O(1) |
86. Partition List | Code | O(n) | O(1) |
92. Reverse Linked List II | Code | O(n) | O(1) |
109. Convert Sorted List to Binary Search Tree | Code | O(log n) | O(n) |
141. Linked List Cycle | Code | O(n) | O(1) |
142. Linked List Cycle II | Code | O(n) | O(1) |
143. Reorder List | Code | O(n) | O(1) |
147. Insertion Sort List | Code | O(n) | O(1) |
148. Sort List | Code | O(n log n) | O(1) |
160. Intersection of Two Linked List | Code | O(n) | O(1) |
203. Remove Linked List Element | Code | O(n) | O(1) |
206. Reverse Linked List | Code | O(n) | O(1) |
234. Palindrome Linked List | Code | O(n) | O(1) |
237. Delete Node in a Linked List | Code | O(n) | O(1) |
328. Odd Even Linked List | Code | O(n) | O(1) |
445. Add Two Numbers II | Code | O(n) | O(1) |
707. Design Linked List | Code | O(n) | O(1) |
725. Split Linked List in Parts | Code | O(n) | O(1) |
817. Linked List Components | Code | O(n) | O(1) |
876. Middle of the Linked List | Code | O(n) | O(1) |
1019. Next Greater Node In Linked List | Code | O(n) | O(1) |
Code | O(n) | O(1) |