Java单链表深拷贝

在Java中,链表是一种常见且重要的数据结构。它是一种线性结构,由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的引用。在开发中,我们经常需要对链表进行拷贝操作,其中深拷贝是一种常见的需求。本文将介绍如何实现Java单链表的深拷贝,并提供代码示例。

什么是深拷贝

在介绍深拷贝之前,先了解一下浅拷贝。浅拷贝是指创建一个新对象,将原始对象的非静态字段的值复制到新对象中。如果字段是值类型,那么对该字段进行拷贝;如果字段是引用类型,那么拷贝的是引用,也就是说原始对象和新对象共享同一个引用指向的内存空间。这意味着,如果修改了其中一个对象的引用类型字段,另一个对象也会受到影响。

深拷贝解决了浅拷贝的问题。深拷贝是指创建一个新对象,将原始对象的所有字段的值复制到新对象中,包括引用类型字段。这样,原始对象和新对象完全独立,互不影响。

单链表的深拷贝实现

在Java中,链表通常使用节点类表示,节点类包含数据元素和指向下一个节点的引用。要实现单链表的深拷贝,需要对链表中的每个节点进行拷贝,并重新建立节点之间的连接关系。

首先,定义链表节点类Node,包含数据元素data和指向下一个节点的引用next

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

接下来,定义链表类LinkedList,包含头节点head和链表长度size

public class LinkedList {
    public Node head;
    public int size;
    
    public LinkedList() {
        head = null;
        size = 0;
    }
}

链表类中需要实现深拷贝方法deepCopy,该方法将返回一个新的链表对象,该对象包含原始链表中所有节点的深拷贝:

public class LinkedList {
    // ...

    public LinkedList deepCopy() {
        LinkedList newList = new LinkedList();
        Node current = head;
        Node prev = null;
        
        while (current != null) {
            Node newNode = new Node(current.data);
            
            if (prev == null) {
                newList.head = newNode;
            } else {
                prev.next = newNode;
            }
            
            prev = newNode;
            current = current.next;
        }
        
        newList.size = size;
        
        return newList;
    }
}

在深拷贝方法中,遍历原始链表的每个节点,创建一个新的节点,并将原始节点的数值复制给新节点。在建立新节点之间的连接关系时,需要判断是否为头节点,如果是头节点,则将新节点设置为新链表的头节点;否则,将新节点设置为上一个新节点的next引用。

示例

现在,我们来使用一个示例来演示单链表深拷贝的过程。

public class Main {
    public static void main(String[] args) {
        LinkedList list1 = new LinkedList();
        list1.head = new Node(1);
        list1.head.next = new Node(2);
        list1.head.next.next = new Node(3);
        list1.size = 3;
        
        LinkedList list2 = list1.deepCopy();
        
        // 修改原始链表的值
        list1.head.data = 10;
        
        // 修改原始链表的连接关系
        list1.head.next = list1.head.next.next;
        
        // 打印新链表的值
        Node current = list2.head;
        while (current != null) {
            System.out.print(current.data + " ");
            current = current.next;
        }
    }
}

上述代码定义了一个包含三个节点的原始链表list1,并通过调用deepCopy方法得到了一个新链表list2。然后