这段代码是一个双向链表的实现。下面逐句解释并画出链表变化图:
public class DoublyList<T> {
public DoubleNode<T> head;
public DoublyList() {
this.head = new DoubleNode<T>();
this.head.prev = null;
this.head.next = null;
}
- 首先定义了一个
DoublyList类,该类表示双向链表。 head是指向链表头部的节点,初始化为一个空节点。
public boolean isEmpty() {
return this.head.next == null;
}
isEmpty()方法用于判断链表是否为空,如果头节点的next指针为空,则表示链表为空。
public String toString()
{
String str = this.getClass().getName() + "(";
DoubleNode<T> p = this.head.next;
while (p != null) {
str += p.data.toString() + ((p.next != null) ? "," : "");
p = p.next;
}
return str + ")";
}
toString()方法用于将双向链表转换成字符串形式输出。- 遍历链表中的每个节点,将节点的数据转换为字符串,并根据节点是否有下一个节点来确定是否添加逗号分隔。
- 最后返回拼接好的字符串形式。
public DoubleNode<T> insert(int i,T x)
{
if(x==null)
return null;
DoubleNode<T> front=this.head;
for(int j=0;front.next!=null&&j<i;j++)
front=front.next;
DoubleNode <T> q=new DoubleNode<T>(x,front,front.next);
front.next.prev=q;
front.next=q;
return q;
}
insert(int i,T x)方法用于在指定位置插入新节点。- 首先判断插入的数据
x是否为null,如果是,则直接返回null。 - 通过循环找到要插入位置的前一个节点,即
front。 - 创建一个新节点
q,将其连接到front和front.next之间。 - 调整相应节点的prev和next指针。
- 返回插入的新节点。
public DoubleNode<T> insert(T x)
{
if (x == null)
return null;
DoubleNode<T> rear = head;
while (rear.next != null)
{
rear = rear.next;
}
DoubleNode<T> q = new DoubleNode<T>(x, rear, null);
rear.next = q;
return q;
}
insert(T x)方法用于在链表末尾插入新节点。- 首先判断插入的数据是否为null,如果是,则直接返回null。
- 通过循环找到链表末尾的节点,即最后一个非空节点。将新节点连接到该节点后面,并调整相应指针。
public DoublyList(DoublyList<T> list)
{
this();
DoubleNode<T> rear = this.head;
for(DoubleNode<T> p = list.head.next; p != null; p = p.next)
{
DoubleNode<T> q = new DoubleNode(p.data, rear, null);
rear.next = q;
q.prev = rear;
rear = rear.next;
}
}
DoublyList(DoublyList<T> list)构造方法用于复制一个双向链表。- 首先创建一个新的空链表,即调用默认构造方法
this()。 - 然后遍历原链表中的每个节点,复制节点的数据并创建新节点,将其连接到新链表末尾,并调整相应指针。
public void concat(DoublyList<T> list)
{
DoubleNode<T> rear = this.head;
while (rear.next != null) {
rear = rear.next;
}
rear.next = list.head.next;
if (list.head.next != null) {
list.head.next.prev = rear;
}
}
concat(DoublyList<T> list)方法用于将另一个链表连接到当前链表末尾。- 首先找到当前链表的末尾节点,即最后一个非空节点。
- 将另一个链表的头部节点连接到当前链表的末尾,并调整相应指针。
public void addAll(DoublyList<T> list)
{
this.concat(new DoublyList<T>(list));
}
addAll(DoublyList<T> list)方法用于将另一个链表全部添加到当前链表末尾。- 首先创建一个新的链表作为参数传入
concat()方法。
public DoublyList<T> union(DoublyList<T> list) {
DoublyList<T> result = new DoublyList<>(this);
result.addAll(list);
return result;
}
union(DoublyList<T> list)方法用于将当前链表与另一个链表合并为一个新链表。- 首先创建一个新的链表
result,将当前链表复制到该链表中。 - 然后使用
addAll()方法将另一个链表全部添加到result链表末尾。 - 最后返回合并后的新链表。
public static void main(String[] args) {
DoublyList<Integer> list1 = new DoublyList<Integer>();
DoublyList<Integer> list2 = new DoublyList<Integer>();
for (int i = 1; i <= 5; i++)
list1.insert(i);
for (int i = 6; i <= 10; i++)
list2.insert(i);
System.out.println(list1.toString());
System.out.println(list2.toString());
list1.addAll(list2);
System.out.println(list1.toString());
}
}
- 在主函数中进行测试:
- 创建两个空的双向链表对象list1和list2。
- 使用循环分别在list1和list2中插入一些整数数据。
- 打印出list1和list2的字符串形式。
- 使用addAll()方法将list2全部添加到list1的末尾。
- 打印出合并后的list1的字符串形式。
链表变化图:
初始状态:
list1: [head] -> null
list2: [head] -> null
插入数据之后:
list1: [head] -> 1 -> 2 -> 3 -> 4 -> 5 -> null
list2: [head] -> 6 -> 7 -> 8 -> 9 -> 10 -> null
合并之后:
list1: [head] -> 1 -> 2 -> 3 -> 4 -> 5 -|-> [head] --> |-->6 -->7 -->8 -->9 -->10-->null
内容由零声教学AI助手提供,问题来源于学员提问




