0
点赞
收藏
分享

微信扫一扫

Java数据结构之双向链表(配图详解,简单易懂)

念川LNSC 2022-01-28 阅读 21

Java数据结构之双向链表

⚡️前言⚡️
本笔记针对无头双向链表的实现来展开,在阅读该笔记时,建议读者结合博主的单链表笔记一起阅读,两者多有相似之处,结合阅读便于理解总结😇


📍内容导读📍

双向链表概述

🍓节点类及链表头尾的建立

class Node {
    public int data;//一个节点存在三个区域
    public Node prev;
    public Node next;
    public Node(int data) {//构造方法用于初始化实例对象
        this.data = data;
    }
}
public class MyLinkedList {
    public Node head;
    public Node tail;
    public void addFirst(int data);
    //1.头插法
    public void addLast(int data);
    //2.尾插法
    public void display();
    //3.打印链表
    public boolean contains(int key);
    //4.查找是否包含关键字key是否在单链表当中 
    public int size();
    //5.求链表长度
    public void addIndex(int index,int data);
    //6.任意位置插入,第一个数据节点为0号下标 
    public void remove(int key);
    //7.删除第一次出现关键字为key的节点 
    public void removeAllKey(int key);
    //8.删除所有值为key的节点 
    public void clear();
    //9.清空链表
}

以下即为双向链表的各接口的实现

🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍐 🍍 🍅 🏀 💡 🔑

🍉1.头插法

    public void addFirst(int data) {
        Node node=new Node(data);//将data的值new为一个节点
        if (this.head == null) {//第一次插入
            this.head=node;//头尾节点都指向该节点
            this.tail=node;
        }else {
            node.next=this.head;//完成连接
            this.head.prev=node;//改变域值
            this.head=node;//头节点前移
        }
    }

🍉2.尾插法

    public void addLast(int data) {
        Node node=new Node(data);
        if(this.head==null) {
            this.head=node;
            this.tail=node;
        }else {
            this.tail.next=node;//续尾
            node.prev=this.tail;//变值
            this.tail=node;//移尾
        }
    }

🍉3.打印链表

    public void display() {
        Node cur=this.head;
        while(cur != null) {
            System.out.print(cur.data+" ");
            cur=cur.next;
        }
        System.out.println();
    }

🍉4.查找是否包含关键字

    public boolean contains(int key) {
        Node cur=this.head;
        while(cur!=null) {
            if(cur.data==key)
                return true;
            cur=cur.next;
        }
        return false;
    }

🍉5.求链表长度

    public int size() {
        int a=0;
        Node cur=this.head;
        while(cur!=null) {
            a++;
            cur=cur.next;
        }
        return a;
    }

🍉6.任意位置(index)插入

    private void checkIndex(int index) {//判断index位置合法性
        if(index<0||index>this.size()) {
            throw new RuntimeException("index位置不合法");
        }
    }
    private Node searchIndex(int index) {//查找插入的位置
        Node cur=this.head;
        int a=0;
        while(a!=index) {
            a++;
            cur=cur.next;
        }
        return cur;
    }
    public void addIndex(int index,int data) {
        checkIndex(index);
        if(index==0) {//头插
            this.addFirst(data);
            return;
        }
        if(index==this.size()) {//尾插
            this.addLast(data);
            return;
        }
        Node node=new Node(data);//实例化node节点
        Node cur=searchIndex(index);//cur存储index位置节点
        node.next=cur;//左边四步完成连接过程,先对node中的值改变对原链表无影响
        node.prev=cur.prev;
        cur.prev.next=node;//然后连接前后
        cur.prev=node;
    }

🍉7.删除第一次出现关键字为key的节点

    public void remove(int key) {
        Node cur=this.head;
        while(cur!=null) {
            if(cur.data==key) {//如果找到关键字key
                if(cur==this.head) {//头节点的data为key
                    this.head=cur.next;//头节点后移完成头节点删除
                    if(this.head!=null)//防止空指针异常
                    this.head.prev=null;
                }else {//中间找到key
                    cur.prev.next=cur.next;
                    if(cur.next!=null)
                    cur.next.prev=cur.prev;
                    else//如果cur.next==null,尾节点即为所需删除节点
                        this.tail=cur.prev;
                }
                break;//完成删除后跳出循环
            }
            cur=cur.next;//如果没有进if语句中,cur继续往后遍历
        }
    }

🍉8.删除所有值为key的节点

    public void remove(int key) {
        Node cur=this.head;
        while(cur!=null) {
            if(cur.data==key) {//如果找到关键字key
                if(cur==this.head) {//头节点的data为key
                    this.head=cur.next;//头节点后移完成头节点删除
                    if(this.head!=null)//防止空指针异常
                    this.head.prev=null;
                }else {//中间找到key
                    cur.prev.next=cur.next;
                    if(cur.next!=null)
                    cur.next.prev=cur.prev;
                    else//如果cur.next==null,尾节点即为所需删除节点
                        this.tail=cur.prev;
                }
            }
            cur=cur.next;//如果没有进if语句中,cur继续往后遍历
        }
    }

🍉9.清空链表

    public void clear() {//完成遍历,所有都置为空,则内存被收回
        while (this.head!=null) {
            Node cur=this.head.next;
            this.head.prev=null;
            this.head.next=null;
            this.head=cur;
        }
        this.tail=null;
    }

⚡️最后的话⚡️

总结不易,希望uu们不要吝啬你们的👍哟(^U^)ノ~YO!!如有问题,欢迎评论区批评指正😁
在这里插入图片描述

举报

相关推荐

0 条评论