JAVA 实现双向链表根据节点大小按顺序新增、修改、删除操作

  • Post author:
  • Post category:java


单向链表查找的方向只能是一个方向,而双向链表可以向前或者向后查找。

结合

JAVA 实现带头结点的链表根据节点大小按顺序新增、修改、删除节点

单向链表的操作。在单向链表的基础上进行双向链表的增删改就比较简单了。

根据上图,分析双向链表的新增,修改、删除操作思路:

1) 遍历 方和 单链表一样,可以向前查找,也可以向后查找。本文使用向后查找的方式遍历 双向链表。

2) 添加 (按照节点的大小顺序插入到双向链表中)

(1) 先通过遍历,找到双向链表中比新节点大的节点。如果找到链表中已存在要添加的新节点,则提示不能添加

(2)反之,则新节点的下个节点即为当前节点的下个节点  newHeroNode.next = temp.next;

(3)当前节点的下个节点为新节点  temp.next = doubleNode;新节点的前一节点为当前节点:doubleNode.previous = temp;

3) 修改 思路和 原单向链表的修改思路一样.找到双向链表中相同编号的节点,并直接修改

4) 删除节点

(1) 首先要设置一个temp节点,使用while循环遍历双向链表,查找到要删除的节点。

(2) 找到要删除的节点后,设置被删除节点的前一个节点的next 为 被删除节点的next。

(3) 如果被删除节点的next不为空,则被删除节点的下个节点的previous为被删除节点的前一个节点temp.next.previous = temp.previous。

代码实现

1、先创建一个DoubleNode对象,即链表中的节点对象

class DoubleNode{
    public int no;
    public String name;
    public String nickName;
    public DoubleNode next;
    public DoubleNode previous;


    public DoubleNode(int no,String name,String nickName){
        this.no = no;
        this.name = name;
        this.nickName = nickName;
    }

    @Override
    public String toString() {
        return "DoubleNode{" + "no=" + no + ", name='" + name  + "', nickName='" + nickName+"'}";
    }
}

2、 创建DoubleLinkedList类,并定义全局头节点对象

 DoubleNode head = new DoubleNode(0,"","");

3、 添加节点,按节点的编号顺序添加到双向链表

 //按节点的编号顺序添加
    public void addByOrder(DoubleNode doubleNode){
        //head节点不能动,所要需要一个临时节点 temp
        DoubleNode temp = head;
        boolean flag = false;
        //遍历链表,找到要添加的节点应插入的位置,如果节点的next为null,就代表找到了最后的节点
        while (true) {
            if(temp.next == null){
                break;
            }
            if(temp.no == doubleNode.no){
                flag = true;
                break;
            }else if(temp.next.no > doubleNode.no){
                break;
            }
            //当遍历的当前节点next不为Null时,则继续遍历,需要将临时节点后移
            temp = temp.next;
        }

        if(flag){
            System.out.printf("链表中已存在该编号%d节点,不能添加\n",doubleNode.no);
        }else{
            doubleNode.next = temp.next;
            if(temp.next !=null){
                temp.next.previous = doubleNode;
            }
            temp.next = doubleNode;
            doubleNode.previous = temp;
        }
    }

4、修改指定节点

public void update(DoubleNode doubleNode){
        if(head.next == null){
            System.out.println("链表为空");
            return;
        }
        DoubleNode temp = head;
        boolean flag = false;
        while (true){
            if(temp.next == null && temp.no == doubleNode.no){
                flag = true;
                break;
            }
            if(temp.next != null && temp.no == doubleNode.no){
                flag = true;
                break;
            }
            if(temp.next == null){
                break;
            }
            temp = temp.next;
        }

        if(flag==true){
            temp.name = doubleNode.name;
            temp.nickName = doubleNode.nickName;
        }else{
            System.out.printf("链表中不存在编号为%d的节点,无法修改\n",doubleNode.no);
        }
    }

5、删除指定节点

 
    //删除指定编号的节点
    public void delete(int no){
        if(head.next == null){
            System.out.println("链表为空");
            return;
        }
        DoubleNode temp = head;
        boolean flag = false;// 标志是否找到待删除节点的
        while (true){
            if((temp.next == null) && (temp.no == no)){
                flag = true;
                break;
            }
            if((temp.next != null) && temp.no == no){
                flag = true;
                break;
            }
            if(temp.next == null){
                break;
            }
            temp = temp.next;
        }

        if(flag){
            //被删除节点的前一个节点的next 为 被删除节点的next
            temp.previous.next = temp.next;
            if(temp.next !=null){
                //如果被删除节点的next不为空,则 被删除节点的下个节点的previous为被删除节点的前一个节点
                temp.next.previous = temp.previous;
            }
        }else{
            System.out.printf("链表中不存在编号为%d的节点,无法删除\n",no);
        }
    }

 

6、遍历双向链表

public void list(){
        //判断链表是否为空,如果为空则返回
        if(head.next == null){
            System.out.println("链表为空");
            return;
        }
        //head节点不能动,所要需要一个临时节点 temp
        DoubleNode temp = head.next;
        while (true){
            //判断当前遍历的节点是否为空,为空则代表到了链表的最后
            if(temp == null){
                break;
            }
            //输出节点信息
            System.out.println(temp);
            //将temp后移,继续遍历
            temp = temp.next;
        }
    }

7、创建测试类

public class DoubleLinkedListDemo {
    public static void main(String[] args) {
        DoubleLinkedList doubleLinkedList = new DoubleLinkedList();
        DoubleNode h1 = new DoubleNode(1,"AAA","A");
        DoubleNode h2 = new DoubleNode(2,"BBB","B");
        DoubleNode h3 = new DoubleNode(3,"CCC","C");
        DoubleNode h4 = new DoubleNode(4,"DDD","D");

        doubleLinkedList.addByOrder(h1);
        doubleLinkedList.addByOrder(h3);
        doubleLinkedList.addByOrder(h4);
        doubleLinkedList.addByOrder(h2);
        System.out.println("修改前的双链表打印--------------------");
        doubleLinkedList.list();

        DoubleNode h5 = new DoubleNode(5,"EEEE","E");
        doubleLinkedList.update(h5);
        System.out.println("修改后的双链表打印--------------------");
        doubleLinkedList.list();

        doubleLinkedList.delete(1);
        System.out.println("删除节点后的双链表打印--------------------");
        doubleLinkedList.list();
    }
}

输出结果:

修改前的双链表打印——————–

DoubleNode{no=1, name=’AAA’, nickName=’A’}

DoubleNode{no=2, name=’BBB’, nickName=’B’}

DoubleNode{no=3, name=’CCC’, nickName=’C’}

DoubleNode{no=4, name=’DDD’, nickName=’D’}

修改后的双链表打印——————–

DoubleNode{no=1, name=’AAA’, nickName=’A’}

DoubleNode{no=2, name=’BBB’, nickName=’B’}

DoubleNode{no=3, name=’CCC’, nickName=’C’}

DoubleNode{no=4, name=’EEEE’, nickName=’E’}

删除节点后的双链表打印——————–

DoubleNode{no=2, name=’BBB’, nickName=’B’}

DoubleNode{no=3, name=’CCC’, nickName=’C’}

DoubleNode{no=4, name=’EEEE’, nickName=’E’}



版权声明:本文为Sundy_sc原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。