【java-数据结构14-双向链表的增删查改2】

   上一篇文章中,我们已经对双向链表进行一些基本操作,本篇文章我们继续通过对链表的增删查改来加深对链表的理解~同时有任何不懂的地方可以在评论区留言讨论,也可以私信小编~觉得小编写的还可以的可以留个关注支持一下~话不多说正片开始~

注意:上篇文章少了一些图,这里做些补充重新发一遍

1.任意位置插入

1.对插入位置进行合法性判断

2.如果等于0即为头插法,等于size即为尾插法

小于0大于saize都是不可以的,代码如下

private void checkIndex(int index) {
        if(index < 0 || index > size()) {
            throw new IndexOutOfException("index 不合法!"+index);
        }
    }

上面我们抛出一个自定义异常 ,也不要忘记定义一个异常类,代码如下

 public class IndexOutOfException extends RuntimeException{
        public IndexOutOfException() {
        }

        public IndexOutOfException(String message) {
            super(message);
        }
    }

3.定义cur,也就是要插入的位置

代码如下

public void addIndex(int index,int data){
        checkIndex(index);
        if(index == 0) {
            addFirst(data);
            return;
        }
        if(index == size()) {
            addLast(data);
            return;
        }
        ListNode cur = searchIndex(index);
        ListNode node = new ListNode(data);
        node.next = cur;
        cur.prev.next = node;
        node.prev = cur.prev;
        cur.prev = node;
    }

调用测试

public class test {
    public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        myLinkedList.addFirst(56);
        myLinkedList.addFirst(45);
        myLinkedList.addFirst(34);
        myLinkedList.addFirst(23);
        myLinkedList.addFirst(12);
        myLinkedList.addLast(67);

        myLinkedList.display();
        myLinkedList.addIndex(0,999);
        myLinkedList.display();
     
    }

运行截图 

2.删除第一次出现的key节点

  如果是单链表,我们是需要找到要删除的前一个节点的,让删除的节点被跳过即可

  双链表则不需要那么麻烦,我们先看中间节点,直接找到要删除的节点cur,让cur.prev.next = cur.next; cur.next.prev = cur.prev;即可 如图

接下来我们讨论如果要删除的是头节点 :先让head = head.next并且head.prev = null

注意:那么如果只有一节点呢head = head.nex代码执行完毕后head就为null,那么head.prev = null就会异常,那么我们要加一个前置条件if:head!=null,如果head等于null,手动把last置为空即可

下面我们讨论要删除的是尾巴节点cur.prev.next = cur.next; last = last.prev

代码如下

 public void remove(int key){
        ListNode cur = head;
        while (cur != null) {
            if(cur.val == key) {
                //删除头节点
                if(cur == head) {
                    head = head.next;
                    if(head != null) {
                        //考虑只有一个节点的情况下
                        head.prev = null;
                    }else {
                        last = null;
                    }
                }else {
                    //删除中间节点 和  尾巴节点
                    if(cur.next != null) {
                        //删除中间节点
                        cur.prev.next = cur.next;
                        cur.next.prev = cur.prev;
                    }else {
                        //尾巴节点
                        cur.prev.next = cur.next;
                        last = last.prev;
                    }
                }
                return;
            }else {
                cur = cur.next;
            }
        }
    }

调用测试

 public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        myLinkedList.addFirst(56);
        myLinkedList.addFirst(45);
        myLinkedList.addFirst(34);
        myLinkedList.addFirst(23);
        myLinkedList.addFirst(12);
        myLinkedList.addLast(67);

        myLinkedList.display();
       myLinkedList.remove(23);
       
        myLinkedList.display();
     


    }

运行截图

 

3.删除所有出现的key节点

    此题逻辑与上题基本相同,只是我们上一个题删除第一个节点后就返回了,我们只要让cur继续往后走即可

代码如下

public void removeAllKey(int key){
        ListNode cur = head;
        while (cur != null) {
            if(cur.val == key) {
                //删除头节点
                if(cur == head) {
                    head = head.next;
                    if(head != null) {
                        //考虑只有一个节点的情况下
                        head.prev = null;
                    }else {
                        last = null;
                    }
                }else {
                    //删除中间节点 和  尾巴节点
                    if(cur.next != null) {
                        //删除中间节点
                        cur.prev.next = cur.next;
                        cur.next.prev = cur.prev;
                    }else {
                        //尾巴节点
                        cur.prev.next = cur.next;
                        last = last.prev;
                    }
                }
                cur = cur.next;
                //return;
            }else {
                cur = cur.next;
            }
        }
    }

调用测试

 public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        myLinkedList.addFirst(56);
        myLinkedList.addFirst(45);
        myLinkedList.addFirst(12);
        myLinkedList.addFirst(12);
        myLinkedList.addFirst(12);
        myLinkedList.addLast(67);

        myLinkedList.display();
        myLinkedList.removeAllKey(12);
     
        myLinkedList.display();
    


    }

运行截图 

4.清空链表

head,last置为null,或者一个一个置null,如图

 

但此时还有head,last两个节点,手动置空即可 

代码如下

 public void clear(){
        ListNode cur = head;
        while (cur != null) {
            ListNode curNext = cur.next;
            cur.prev = null;
            cur.next = null;
            cur = curNext;
        }
        head = null;
        last = null;
    }

调用测试

 public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        myLinkedList.addFirst(56);
        myLinkedList.addFirst(45);
        myLinkedList.addFirst(12);
        myLinkedList.addFirst(12);
        myLinkedList.addFirst(12);
        myLinkedList.addLast(67);

        myLinkedList.display();
        myLinkedList.clear();
     
        myLinkedList.display();
    

    }

运行截图

5.库中的linkedlist方法使用

 到此为止,我们手动创建链表并对链表进行增删查改就结束的,其实我们还可以通过 库当中的linkedlist,直接使用,下面我们做具体演示

1.导入类:import java.util.List

2.创建链表。

  List<Integer> list1 = new LinkedList<>();

下面是一些方法,这里不做演示了

 

6.LinkedList遍历 

1.for循环

这个方法前面有讲过,这里不多赘述

2.for,each循环

代码如下

 public static void main(String[] args) {
        List<Integer> list = new LinkedList<>();
        list.add(1);
        list.add(1);
        list.add(3);
        for (Integer X:list
             ) {
            System.out.println(X);
        }

    }

运行截图

 

3.迭代器· 

使用迭代器要导入类:import java.util.ListIterator;

代码如下

 public static void main(String[] args) {
        List<Integer> list = new LinkedList<>();
        list.add(1);
        list.add(1);
        list.add(3);
     
        ListIterator<Integer> it = list.listIterator();
        while(it.hasNext()){
            System.out.print(it.next()+ " ");
        }

    }

4.迭代器反向遍历

 

public static void main(String[] args) {
        List<Integer> list = new LinkedList<>();
        list.add(1);
        list.add(1);
        list.add(3);
      
        ListIterator<Integer> rit = list.listIterator(list.size());
        while (rit.hasPrevious()){
            System.out.print(rit.previous() +" ");
        }
        System.out.println();
    }

 

到此为止,我们链表的章节就可以跟大家说在再见了,下一篇文章,我们将会进入栈和队列的学习,觉得小编讲的还可以的可以留个关注~我们下期再见~ 谢谢观看~

  • 11
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值