Luna Tech

Tutorials For Dummies.

数据结构学习笔记(3)——框架

2023-02-12


1. 数组遍历(线性迭代)

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

2. 链表遍历(线性迭代 + 非线性递归)

/* 基本的单链表节点 */
class ListNode {
    int val;
    ListNode next;
}

void traverse(ListNode head) {
    for (ListNode p = head; p != null; p = p.next) {
        // 迭代访问 p.val
    }
}

void traverse(ListNode head) {
    // 递归访问 head.val
    traverse(head.next);
}

3. 二叉树遍历框架(非线性递归)

/* 基本的二叉树节点 */
class TreeNode {
    int val;
    TreeNode left, right;
}

void traverse(TreeNode root) {
    // 前序位置
    traverse(root.left);
    // 中序位置
    traverse(root.right);
    // 后序位置
}

4. N 叉树遍历框架(非线性递归)

单链表就是一个节点只能连一个节点,二叉树可以理解为单链表的扩展(1 对 2),所以 N 叉树也可以理解为单链表的扩展(1 对多)。

/* 基本的 N 叉树节点 */
class TreeNode {
    int val;
    TreeNode[] children;
}

void traverse(TreeNode root) {
    for (TreeNode child : root.children)
        traverse(child);
}

5. 图的遍历框架(非线性递归)

图是好几个 N 叉树的结合体,所以 N 叉树的遍历可以扩展为图的遍历。

假如要检查环,就用 boolean 数组 visited 来做标记。


6. 二分搜索

二分搜索是双指针技巧的运用。


int binarySearch(int[] nums, int target) {
    int left = 0, right = ...;

    while(...) {
        int mid = left + (right - left) / 2;
        if (nums[mid] == target) {
            ...
        } else if (nums[mid] < target) {
            left = ...
        } else if (nums[mid] > target) {
            right = ...
        }
    }
    return ...;
}