学习内容来源于:https://labuladong.gitbook.io/algo/
以下是自己的归纳与总结。
示例代码均采用 Java

数据结构的存储方式

数据结构的存储方式只有两种:**数组(顺序存储)和链表**(链式存储)。
散列表、栈、队列、堆、树、图等常见的数据结构,本质上都是数组与链表的实现形式,API不同而已。

数组

优点:连续空间存储,可以随机访问,通过索引快速定位到具体元素。
缺点:

  1. 扩容时需要重新分配一整块空间,再把元素全部复制过去,时间复杂度 O(N);
  2. 在特定位置插入或删除元素时,需要移动特定位置后面的全部元素,时间复杂度 O(N);

链表

优点:不存在扩容的问题,只需知道特定位置的前驱和后驱操作指针即可,时间复杂度 O(1)。
缺点:

  1. 空间不连续,不支持随机访问。
  2. 每个元素需记录前后指针,消耗一定的空间。

数据结构的基本操作

增删改查 其实就是遍历+访问。
散列表、栈、队列、堆、树、图等数据结构的出现,就是要高效的遍历和访问数据。

遍历和访问本质上只有两种,线性和非线性
线性: for/while 迭代为代表
非线性:递归

数组遍历

  1. void traverse(int[] arr) {
  2. for (int i = 0; i < arr.length; i++) {
  3. // 迭代访问 arr[i]
  4. }
  5. }

链表遍历

  1. /* 基本的单链表节点 */
  2. class ListNode {
  3. int val;
  4. ListNode next;
  5. }
  6. void traverse(ListNode head) {
  7. for (ListNode p = head; p != null; p = p.next) {
  8. // 迭代访问 p.val
  9. }
  10. }
  11. void traverse(ListNode head) {
  12. // 递归访问 head.val
  13. traverse(head.next);
  14. }

递归
二叉树

  1. /* 基本的二叉树节点 */
  2. class TreeNode {
  3. int val;
  4. TreeNode left, right;
  5. }
  6. void traverse(TreeNode root) {
  7. traverse(root.left);
  8. traverse(root.right);
  9. }

二叉树遍历与链表遍历相似,节点的数据结构也相似。
同理n叉树可得出:

n叉树

  1. /* 基本的 N 叉树节点 */
  2. class TreeNode {
  3. int val;
  4. TreeNode[] children;
  5. }
  6. void traverse(TreeNode root) {
  7. for (TreeNode child : root.children)
  8. traverse(child);
  9. }

总结

数据结构的存储方式就是链表数组,遍历就是迭代递归