返回

高精度面试必备:Java单链表数据结构与算法

Android

单链表:计算机科学中的基本数据结构

什么是单链表?

单链表是一种线性数据结构,由一系列节点组成。每个节点包含两个字段:一个数据元素和一个指向下一个节点的指针。第一个节点称为头节点,最后一个节点称为尾节点。节点可以通过指针连接起来,形成一个线性序列。

单链表的应用

单链表广泛应用于各种计算机科学领域,包括:

  • 存储和处理列表数据
  • 实现栈和队列数据结构
  • 图形处理
  • 哈希表
  • 链表排序
  • 内存管理

单链表的优点

  • 容易创建和操作
  • 可以动态调整大小,以适应不同大小的数据集
  • 在内存中占用较少空间,因为每个节点仅包含两个字段

单链表的常见面试题

  • 如何创建单链表?
  • 如何在单链表中插入一个节点?
  • 如何在单链表中删除一个节点?
  • 如何反转单链表?
  • 如何判断单链表是否有环?
  • 如何合并两个单链表?
  • 如何查找单链表的中间节点?
  • 如何判断两个单链表是否相交?
  • 如何求单链表的长度?
  • 如何实现单链表的排序?

单链表的代码示例

以下是 Java 中单链表的简单实现:

class Node {
    int data;
    Node next;

    public Node(int data) {
        this.data = data;
        this.next = null;
    }
}

class SingleLinkedList {
    private Node head;

    public void addFirst(int data) {
        Node newNode = new Node(data);
        newNode.next = head;
        head = newNode;
    }

    public void addLast(int data) {
        Node newNode = new Node(data);
        if (head == null) {
            head = newNode;
        } else {
            Node current = head;
            while (current.next != null) {
                current = current.next;
            }
            current.next = newNode;
        }
    }

    public void insertAfter(Node prevNode, int data) {
        if (prevNode == null) {
            throw new IllegalArgumentException("Previous node cannot be null");
        }
        Node newNode = new Node(data);
        newNode.next = prevNode.next;
        prevNode.next = newNode;
    }

    public void deleteNode(Node node) {
        if (node == null) {
            throw new IllegalArgumentException("Node to be deleted cannot be null");
        }
        if (node == head) {
            head = head.next;
        } else {
            Node current = head;
            while (current.next != node) {
                current = current.next;
            }
            current.next = node.next;
        }
    }

    public boolean isEmpty() {
        return head == null;
    }

    public int size() {
        int count = 0;
        Node current = head;
        while (current != null) {
            count++;
            current = current.next;
        }
        return count;
    }

    public void printList() {
        Node current = head;
        while (current != null) {
            System.out.print(current.data + " ");
            current = current.next;
        }
        System.out.println();
    }
}

常见问题解答

  • 为什么单链表比数组更适合存储列表数据?

单链表比数组更适合存储列表数据,因为它可以动态调整大小,而数组的长度是固定的。这意味着单链表可以容纳任何数量的元素,而不会出现内存溢出问题。

  • 如何判断单链表是否有环?

可以使用弗洛伊德判圈算法来判断单链表是否有环。该算法使用两个指针,一个指针每次移动一步,另一个指针每次移动两步。如果这两个指针相遇,则链表中有环。

  • 如何合并两个单链表?

可以使用递归或迭代方法来合并两个单链表。递归方法使用以下步骤:

  1. 如果其中一个链表为空,则返回另一个链表。
  2. 否则,将第一个链表的头节点连接到第二个链表的尾部。
  3. 将第一个链表的头节点的下一个指针指向合并后的链表。

迭代方法使用以下步骤:

  1. 创建一个新的链表作为合并后的链表。
  2. 遍历第一个链表,将每个节点添加到合并后的链表的尾部。
  3. 遍历第二个链表,将每个节点添加到合并后的链表的尾部。
  • 如何查找单链表的中间节点?

可以使用快慢指针法来查找单链表的中间节点。该算法使用两个指针,一个指针每次移动一步,另一个指针每次移动两步。当快指针到达尾节点时,慢指针指向链表的中间节点。

  • 如何反转单链表?

可以使用迭代或递归方法来反转单链表。迭代方法使用以下步骤:

  1. 创建一个新的链表作为反转后的链表。
  2. 遍历原始链表,将每个节点添加到反转后的链表的头节点。

递归方法使用以下步骤:

  1. 如果链表为空或只包含一个节点,则返回链表。
  2. 否则,将链表的尾节点连接到链表的头节点。
  3. 将链表的尾节点的下一个指针指向反转后的链表。