• 双链表的基本操作


    目录

    一、双链表的设计

    二、双链表的实现和基本操作

     1.实现双链表节点以及设置first、last指针

    2.获取当前链表中元素的数量

    3.获取指定位置的节点

    4.在尾部添加结点元素

    5.在指定位置添加元素

    6.删除指定位置的结点


    一、双链表的设计

     针对于查询操作,我们可以从前往后遍历,也可从后往前遍历。

    二、双链表的实现和基本操作

     1.实现双链表节点以及设置first、last指针

    //注意:这里的first和last节点,跟单链表中的头结点不一样,
    //     头结点是专门的一个节点指向链表第一个结点
    //     而这里的first和last节点相当于指针一样,指向第一个和最后一个节点

    1. public class MyDoubleLinkedList {
    2. //节点类设计,设计结点内部类
    3. public class Node{
    4. //存储数据的变量
    5. T item;
    6. //指向上一个节点的引用
    7. Node prev;
    8. //指向下一个结点的引用
    9. Node next;
    10. public Node(Node prev,T item, Node next) {
    11. this.item = item;
    12. this.prev = prev;
    13. this.next = next;
    14. }
    15. }
    16. //注意:这里的first和last节点,跟单链表中的头结点不一样,
    17. // 头结点是专门的一个节点指向链表第一个结点
    18. // 而这里的first和last节点相当于指针一样,指向第一个和最后一个节点
    19. //声明第一个结点
    20. Node first;
    21. //声明最后的结点
    22. Node last;
    23. //定义链表的长度
    24. int size;
    25. //构造方法初始化size
    26. public MyDoubleLinkedList() {
    27. size = 0;
    28. }

    2.获取当前链表中元素的数量

    1. //获取当前存储元素的数量
    2. public int size(){
    3. return this.size;
    4. }

    3.获取指定位置的节点

    1. //根据位置获取元素
    2. public Node getNode(int pos){
    3. int middle = this.size/2;
    4. Node x;
    5. if (pos < middle){//如果目标结点在前半部分,则从前面开始遍历
    6. x = first;
    7. for (int i = 0;i
    8. x = x.next;
    9. }
    10. }else {//如果目标结点在后半部分,则从后面开始遍历
    11. x = last;
    12. for (int i = size-1;i>pos;i--){
    13. x = x.prev;
    14. }
    15. }
    16. return x;
    17. }

    4.在尾部添加结点元素

    思路:将需要插入的结点前指针指向last(链表中最后一个节点),
    //     再将last的next指针指向需要插入的结点,
    //     最后将last游标移动到新插入的结点(即最后一个节点),将最后一个节点赋值给last。
    1. //在尾部添加元素
    2. //思路:将需要插入的结点前指针指向last(链表中最后一个节点),
    3. // 再将last的next指针指向需要插入的结点,
    4. // 最后将last游标移动到新插入的结点(即最后一个节点),将最后一个节点赋值给last。
    5. public void add(T t){
    6. //将last存储在prev结点,last为链表最后一个节点
    7. Node prev = last;
    8. //创建需要插入的结点,同时将节点前指针指向last
    9. Node node = new Node(prev,t,null);
    10. //将prev的next指向新插入的结点
    11. //如果last为空,则链表中没有节点元素,为插入的第一个结点,
    12. // 将first、last游标都指向插入的第一个结点
    13. if (prev == null){
    14. first = node;
    15. }else {
    16. prev.next = node;
    17. }
    18. //将last游标指向新插入的结点
    19. last = node;
    20. //链表长度加一
    21. this.size++;
    22. }

    5.在指定位置添加元素

    思路:一共有四种情况需要考虑,
    //     1.在链表尾部插入节点    2.在链表中正常插入节点
    //     3.链表中没有元素       4.链表中只有一个元素且在第一个元素前插入。

    1. //在指定位置添加元素
    2. //思路:一共有四种情况需要考虑,
    3. // 1.在链表尾部插入节点 2.在链表中正常插入节点
    4. // 3.链表中没有元素 4.链表中只有一个元素且在第一个元素前插入。
    5. public void add(int pos,T t){
    6. if (pos == size){//如果在尾部插入节点,则调用尾部插入节点方法
    7. add(t);
    8. }else {//否则不在尾部插入,在链表中或链表第一个位置插入
    9. //将需要插入的元素创建成节点
    10. Node node = new Node(null,t,null);
    11. //获取当前要插入节点的位置
    12. Node current = this.getNode(pos);
    13. if (current == null){
    14. //链表没有元素的时候
    15. first = node;
    16. }else {
    17. //获取插入节点的前一个位置结点
    18. Node prev = current.prev;
    19. //将node的prev设置成prev节点
    20. node.prev = prev;
    21. //将node的next节点设置成current节点
    22. node.next = current;
    23. //将current的prev设置成node
    24. current.prev = node;
    25. if (prev == null){//如果链表中只有一个节点
    26. //将first指向插入的元素
    27. first = node;
    28. }else {
    29. //将prev的next设置成node
    30. prev.next = node;
    31. }
    32. }
    33. }
    34. //链表长度加一
    35. this.size++;
    36. }

    6.删除指定位置的结点

    思路:分三种情况:
    //     1.在链表中的正常位置删除结点
    //     2.删除链表中第一个结点
    //     3.删除链表中最后一个节点
    1. //指定位置的删除功能
    2. //思路:分三种情况:
    3. // 1.在链表中的正常位置删除结点
    4. // 2.删除链表中第一个结点
    5. // 3.删除链表中最后一个节点
    6. public void remove(int pos){
    7. //获取当前需要删除的结点
    8. Node node = this.getNode(pos);
    9. //获取前一个结点
    10. Node prev = node.prev;
    11. //获取下一个节点
    12. Node next = node.next;
    13. //删除元素,将前一个结点与后一个节点相连
    14. if (prev == null){//如果需要删除的结点是第一个结点
    15. //将first节点指向next
    16. first = next;
    17. }else {
    18. prev.next = next;
    19. }
    20. if (next == null){//如果删除的结点是最后一个节点
    21. //将last节点指向prev
    22. last = prev;
    23. }else {
    24. next.prev = prev;
    25. }
    26. //链表长度减一
    27. this.size--;
    28. }
  • 相关阅读:
    MySQL数据库基础(数据类型与表操作)
    分析可转债的发行公司——公司财务状况、行业分析、公司治理与管理团队
    掌握Pillow:Python图像处理的艺术
    LeetCode 1161.最大层内元素和:层序遍历
    【手把手】教你玩转SpringCloud Alibaba之Sentinel整合GateWay
    【数据集】水文专业常用数据集整理
    Java手写大数乘法算法和大数乘法算法应用拓展案例
    跟艾文学编程《Python基础》(2)Python 容器
    {“Code“:“InvalidParameterValue.TemplateParameterFormatError“
    【CMAKE极简教程】不断更新中......
  • 原文地址:https://blog.csdn.net/m0_51697147/article/details/127849118