返回

链表:极简理解和实现

前端

链表简介

链表是一种线性的数据结构,由一组节点组成,每个节点包含一个数据域和一个指针域,指针域指向下一个节点,形成一个链式结构。

与数组相比,链表具有以下特点:

  • 链表中的元素在内存中不是连续存储的,而是通过指针连接起来的,因此链表可以动态地增长和缩小,而无需移动数据。
  • 链表的插入和删除操作非常简单,只需修改指针即可,而数组则需要移动数据。
  • 链表可以存储任意类型的数据,而数组只能存储相同类型的数据。

链表实现

单向链表

单向链表只允许从一个方向遍历链表,即从头结点开始,沿着指针域指向的下一个节点前进,直到到达尾结点。

class Node {
    int data;
    Node next;

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

class SinglyLinkedList {
    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;
            return;
        }
        Node curr = head;
        while (curr.next != null) {
            curr = curr.next;
        }
        curr.next = newNode;
    }

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

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

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

    public void reverseList() {
        Node prev = null;
        Node curr = head;
        Node next = null;
        while (curr != null) {
            next = curr.next;
            curr.next = prev;
            prev = curr;
            curr = next;
        }
        head = prev;
    }
}

双向链表

双向链表允许从两个方向遍历链表,即从头结点开始沿着指针域指向的下一个节点前进,或者从尾结点开始沿着指针域指向的上一个节点后退。

class Node {
    int data;
    Node next;
    Node prev;

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

class DoublyLinkedList {
    private Node head;
    private Node tail;

    public void addFirst(int data) {
        Node newNode = new Node(data);
        if (head == null) {
            head = newNode;
            tail = newNode;
            return;
        }
        newNode.next = head;
        head.prev = newNode;
        head = newNode;
    }

    public void addLast(int data) {
        Node newNode = new Node(data);
        if (head == null) {
            head = newNode;
            tail = newNode;
            return;
        }
        tail.next = newNode;
        newNode.prev = tail;
        tail = newNode;
    }

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

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

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

    public void reverseList() {
        Node prev = null;
        Node curr = head;
        Node next = null;
        while (curr != null) {
            next = curr.next;
            curr.next = prev;
            curr.prev = next;
            prev = curr;
            curr = next;
        }
        head = prev;
        tail = curr;
    }
}

总结

链表是一种重要的数据结构,具有数组无法比拟的优点。链表的实现并不复杂,但需要对指针的概念有深刻的理解。链表在实际开发中有着广泛的应用,比如:

  • 存储动态变化的数据
  • 实现队列和栈等数据结构
  • 构建哈希表
  • 实现图等数据结构