You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

双向链表添加元素排序交换时出现空指针问题求助

问题分析与修复方案

核心问题1:交换局部变量无法修改链表结构

你当前的节点交换代码只是把first和second这两个局部变量的指向互换了,完全没有修改双向链表中节点的prev和next引用关系,这会导致链表的实际结构混乱,循环遍历的时候自然会出现first.getNext()为null的异常。

核心问题2:交换数据时的空指针

你尝试交换数据时,hold被初始化为null,直接调用hold.setData()必然触发空指针异常——根本不需要用节点来存数据,直接用泛型变量临时存储即可。


修复方案一:正确交换双向链表节点(修改链表结构)

如果要真正交换两个节点的位置,需要处理四个引用关系:

  1. 第一个节点前驱的next
  2. 第一个节点的prev和next
  3. 第二个节点前驱的next
  4. 第二个节点的prev和next
    还要考虑节点是头节点或尾节点的特殊情况。

修改后的排序逻辑代码如下:

if(size() > 1) {
    // 冒泡排序逻辑,每次add后做一次排序
    boolean swapped;
    do {
        swapped = false;
        DoubleLinearNode<T> current = head;
        while (current.getNext() != null) {
            DoubleLinearNode<T> nextNode = current.getNext();
            if (current.getData().compareTo(nextNode.getData()) > 0) {
                // 交换current和nextNode的位置
                DoubleLinearNode<T> prev = current.getPrevious();
                DoubleLinearNode<T> next = nextNode.getNext();

                // 处理current的前驱
                if (prev != null) {
                    prev.setNext(nextNode);
                } else {
                    // current是头节点,更新head
                    head = nextNode;
                }

                // 处理nextNode的后继
                if (next != null) {
                    next.setPrevious(current);
                } else {
                    // nextNode是尾节点,更新tail
                    tail = current;
                }

                // 交换两个节点的prev和next
                nextNode.setPrevious(prev);
                nextNode.setNext(current);
                current.setPrevious(nextNode);
                current.setNext(next);

                swapped = true;
            } else {
                current = current.getNext();
            }
        }
    } while (swapped);
}

修复方案二:仅交换节点数据(更简单)

如果不需要改变节点在链表中的位置,只是排序数据,直接用临时变量存储数据即可,避免复杂的引用修改:

if(size() > 1) {
    boolean swapped;
    do {
        swapped = false;
        DoubleLinearNode<T> current = head;
        while (current.getNext() != null) {
            DoubleLinearNode<T> nextNode = current.getNext();
            if (current.getData().compareTo(nextNode.getData()) > 0) {
                // 直接交换数据,无需修改链表结构
                T temp = current.getData();
                current.setData(nextNode.getData());
                nextNode.setData(temp);
                swapped = true;
            }
            current = current.getNext();
        }
    } while (swapped);
}

完整的add方法修复示例

这里采用方案二(交换数据),代码更简洁且不易出错:

@Override
public void add(T element) throws NullPointerException{
    if(element == null) {
        throw new NullPointerException("Cannot add a null element");
    }
    DoubleLinearNode<T> newNode = new DoubleLinearNode<>(element);

    if(isEmpty()) {
        head = newNode;
        tail = newNode;
    } else {
        tail.setNext(newNode);
        newNode.setPrevious(tail);
        tail = newNode;
    }
    count++;
    modChange++;

    // 排序逻辑:冒泡排序,仅交换数据
    if(size() > 1) {
        boolean swapped;
        do {
            swapped = false;
            DoubleLinearNode<T> current = head;
            while (current.getNext() != null) {
                DoubleLinearNode<T> nextNode = current.getNext();
                if (current.getData().compareTo(nextNode.getData()) > 0) {
                    T temp = current.getData();
                    current.setData(nextNode.getData());
                    nextNode.setData(temp);
                    swapped = true;
                }
                current = current.getNext();
            }
        } while (swapped);
    }
}

内容的提问来源于stack exchange,提问作者Jax

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 02:15:26