java实现双向链表的增删改

Java语言中实现双向链表的增删改可以通过以下步骤进行。

一、创建双向链表节点类

首先,需要创建一个双向链表节点类,该类包含节点值以及指向前驱节点和后继节点的指针。以下是该类的代码实现。

public class DoublyListNode {
    public int val;
    public DoublyListNode prev;
    public DoublyListNode next;

    public DoublyListNode(int val) {
        this.val = val;
        this.prev = null;
        this.next = null;
    }
}

二、双向链表的插入操作

1.头部插入

头部插入操作比较简单,只需要将新节点的后继指针指向链表的头节点,而原来的头节点的前驱指针指向新节点即可。以下是头部插入的示例代码实现。

public void insertAtHead(int val) {
    DoublyListNode newNode = new DoublyListNode(val);
    if (head == null) {
        tail = newNode;
    } else {
        head.prev = newNode;
    }
    newNode.next = head;
    head = newNode;
}

2.尾部插入

尾部插入操作也比较简单,只需要将新节点的前驱指针指向链表的尾节点,而原来的尾节点的后继指针指向新节点即可。以下是尾部插入的示例代码实现。

public void insertAtTail(int val) {
    DoublyListNode newNode = new DoublyListNode(val);
    if (tail == null) {
        head = newNode;
    } else {
        tail.next = newNode;
    }
    newNode.prev = tail;
    tail = newNode;
}

3.任意位置插入

任意位置插入操作比较复杂,需要先找到要插入位置的前驱节点和后继节点,然后进行指针的修改。以下是任意位置插入的示例代码实现。

public void insertAtPos(int val, int pos) {
    DoublyListNode newNode = new DoublyListNode(val);
    if (pos <= 0) {
        insertAtHead(val);
    } else {
        DoublyListNode curr = head;
        for (int i = 0; i < pos - 1 && curr != null; i++) {
            curr = curr.next;
        }
        if (curr == null) {
            insertAtTail(val);
        } else {
            newNode.prev = curr;
            newNode.next = curr.next;
            curr.next = newNode;
            newNode.next.prev = newNode;
        }
    }
}

三、双向链表的删除操作

1.头部删除

头部删除操作比较简单,只需要将头节点的后继节点的前驱指针指向空,再将头指针指向后继节点即可。以下是头部删除的示例代码实现。

public void deleteAtHead() {
    if (head == null) {
        return;
    }
    head = head.next;
    if (head == null) {
        tail = null;
    } else {
        head.prev = null;
    }
}

2.尾部删除

尾部删除操作也比较简单,只需要将尾节点的前驱节点的后继指针指向空,再将尾指针指向前驱节点即可。以下是尾部删除的示例代码实现。

public void deleteAtTail() {
    if (tail == null) {
        return;
    }
    tail = tail.prev;
    if (tail == null) {
        head = null;
    } else {
        tail.next = null;
    }
}

3.任意位置删除

任意位置删除操作比较复杂,需要先找到要删除的节点,然后进行指针的修改。以下是任意位置删除的示例代码实现。

public void deleteAtPos(int pos) {
    if (pos <= 0) {
        deleteAtHead();
    } else {
        DoublyListNode curr = head;
        for (int i = 0; i < pos && curr != null; i++) {
            curr = curr.next;
        }
        if (curr == null) {
            return;
        }
        if (curr == head) {
            deleteAtHead();
        } else if (curr == tail) {
            deleteAtTail();
        } else {
            curr.prev.next = curr.next;
            curr.next.prev = curr.prev;
        }
    }
}

四、双向链表的修改操作

双向链表的修改操作比较简单,只需要找到要修改的节点,然后修改节点的值即可。以下是修改节点的示例代码实现。

public void modify(int val, int pos) {
    DoublyListNode curr = head;
    for (int i = 0; i < pos && curr != null; i++) {
        curr = curr.next;
    }
    if (curr != null) {
        curr.val = val;
    }
}

五、完整示例代码

public class DoublyList {

    private DoublyListNode head;
    private DoublyListNode tail;

    public DoublyList() {
        head = null;
        tail = null;
    }

    public void insertAtHead(int val) {
        DoublyListNode newNode = new DoublyListNode(val);
        if (head == null) {
            tail = newNode;
        } else {
            head.prev = newNode;
        }
        newNode.next = head;
        head = newNode;
    }

    public void insertAtTail(int val) {
        DoublyListNode newNode = new DoublyListNode(val);
        if (tail == null) {
            head = newNode;
        } else {
            tail.next = newNode;
        }
        newNode.prev = tail;
        tail = newNode;
    }

    public void insertAtPos(int val, int pos) {
        DoublyListNode newNode = new DoublyListNode(val);
        if (pos <= 0) {
            insertAtHead(val);
        } else {
            DoublyListNode curr = head;
            for (int i = 0; i < pos - 1 && curr != null; i++) {
                curr = curr.next;
            }
            if (curr == null) {
                insertAtTail(val);
            } else {
                newNode.prev = curr;
                newNode.next = curr.next;
                curr.next = newNode;
                newNode.next.prev = newNode;
            }
        }
    }

    public void deleteAtHead() {
        if (head == null) {
            return;
        }
        head = head.next;
        if (head == null) {
            tail = null;
        } else {
            head.prev = null;
        }
    }

    public void deleteAtTail() {
        if (tail == null) {
            return;
        }
        tail = tail.prev;
        if (tail == null) {
            head = null;
        } else {
            tail.next = null;
        }
    }

    public void deleteAtPos(int pos) {
        if (pos <= 0) {
            deleteAtHead();
        } else {
            DoublyListNode curr = head;
            for (int i = 0; i < pos && curr != null; i++) {
                curr = curr.next;
            }
            if (curr == null) {
                return;
            }
            if (curr == head) {
                deleteAtHead();
            } else if (curr == tail) {
                deleteAtTail();
            } else {
                curr.prev.next = curr.next;
                curr.next.prev = curr.prev;
            }
        }
    }

    public void modify(int val, int pos) {
        DoublyListNode curr = head;
        for (int i = 0; i < pos && curr != null; i++) {
            curr = curr.next;
        }
        if (curr != null) {
            curr.val = val;
        }
    }

    class DoublyListNode {
        public int val;
        public DoublyListNode prev;
        public DoublyListNode next;

        public DoublyListNode(int val) {
            this.val = val;
            this.prev = null;
            this.next = null;
        }
    }
}

六、示例说明

以下示例代码演示了如何创建一个双向链表实例并进行插入、删除和修改操作。

public static void main(String[] args) {
    DoublyList list = new DoublyList();
    list.insertAtHead(1);
    list.insertAtHead(2);
    list.insertAtTail(3);
    list.insertAtPos(4, 1);
    list.modify(5, 2);
    list.deleteAtHead();
    list.deleteAtTail();
    list.deleteAtPos(1);
}

在这个示例中,首先创建了一个双向链表实例,然后进行了头部插入、尾部插入、任意位置插入、修改、头部删除、尾部删除和任意位置删除操作。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java实现双向链表的增删改 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 使命召唤12卡顿假死弹回桌面等问题的解决方法

    针对使命召唤12出现卡顿、假死、弹回桌面等问题,可以尝试以下几个解决方法: 方法一:修复游戏文件 这是一个常见的解决游戏问题的方法。可能是因为游戏文件缺失或被破坏,导致游戏出现问题。步骤如下: 打开Steam或Battle.net客户端,在游戏列表中找到使命召唤12,点击右键,选择“属性”或“选项”。 选择“局部文件”或“本地文件”,点击“验证游戏文件完整性…

    other 2023年6月27日
    00
  • 怎样安装javadb

    安装 JavaDB 可以分为以下两个步骤:下载与配置。 下载 JavaDB JavaDB 也被称为 Apache Derby,可以从 Apache Derby 的官方网站下载:https://db.apache.org/derby/derby_downloads.html 根据你的操作系统下载对应的二进制压缩包,例如 Windows 系统可以下载 db-de…

    其他 2023年4月16日
    00
  • 讲解Python中for循环下的索引变量的作用域

    讲解Python中for循环下的索引变量的作用域 在Python中,for循环是一种常用的迭代结构,用于遍历可迭代对象(如列表、元组、字符串等)。在for循环中,我们可以使用一个索引变量来追踪当前迭代的位置。然而,需要注意的是,索引变量的作用域在for循环内部。 作用域的概念 作用域是指变量在程序中可访问的范围。在Python中,变量的作用域可以是全局作用域…

    other 2023年8月20日
    00
  • 解析Linux xfs文件系统stat命令Birth字段为空的原因

    当使用Linux xfs文件系统时,在执行”stat”命令时,可能会发现Birth字段为空。这种情况通常是由于一些特殊原因所导致的。本篇攻略将详细讲解这些原因,并提供两个示例说明。 原因1:xfs不支持Birth字段 xfs是一种常用的文件系统却不支持文件的创建时间(Birth字段)记录。因此,如果你使用的是xfs文件系统,无论文件是何时创建的,Birth字…

    other 2023年6月27日
    00
  • window.onload 加载完毕的问题及解决方案(上)

    针对“window.onload 加载完毕的问题及解决方案(上)”这个话题,我们需要分别从以下几个方面进行讲解: 什么是 window.onload? window.onload 是 JavaScript 中一个非常重要的事件,用于在页面中所有的资源(如文件、图片等)都加载完成后触发,也就是在文档的所有内容(包括 DOM、CSS、JS、图片)都已经加载完成后…

    other 2023年6月25日
    00
  • 什么是神经网络?

    神经网络是一种机器学习模型,通过多层神经元构建实现非线性分类和回归预测。接下来的攻略将详细讲解神经网络的构建过程。 准备工作 在进行神经网络构建之前,需要准备好以下工作: 数据集:神经网络需要大量的训练数据来训练模型,因此需要准备好符合实际的数据集。 环境配置:需要安装好合适的深度学习框架以及相应的包和库,如TensorFlow、Keras等。 数据预处理 …

    其他 2023年4月19日
    00
  • Python 多继承中的一个诡异现象 既是 Father又是grandfather

    针对Python多继承中的一个诡异现象,我会给出完整的攻略,包括示例说明。在Python中,多继承是一种同时继承多个父类的方式。然而,在多继承的情况下,可能会出现某个类同时继承了它的父类和祖先类的某个方法或属性的情况,导致代码执行结果不符合预期。 这个诡异现象的根本原因在于Python的MRO算法(multiple inheritance resolutio…

    other 2023年6月26日
    00
  • 浅谈java什么时候需要用序列化

    浅谈Java什么时候需要用序列化 序列化是将对象转换为字节流的过程,可以用于对象的存储、传输和持久化。在Java中,当满足以下情况时,通常需要使用序列化: 对象需要在网络中传输:当需要将对象通过网络传输给其他计算机或进程时,需要将对象序列化为字节流,以便在网络上传输。例如,客户端和服务器之间的通信,可以使用序列化将对象发送给服务器或客户端。 示例说明1:将对…

    other 2023年10月15日
    00
合作推广
合作推广
分享本页
返回顶部