【Java数据结构】实现双向链表

目录

1. 🔈引言

2. 😊定义双向链表结点

3. 📰功能列表

5. 💻源代码

MyLinkedList.java

test.java


1. 🔈引言

LinkedList的底层其实就是一个双向链表~

那么什么是双向链表呢?请看下图👇

(从左往右依次为每一个结点)

不难看出:双向链表中每一个结点有三个数据域,分别是data数据、prev前驱、next后继

双向链表的特点:

  1. 引入了前驱域,解决了单链表只能单向访问的痛点
  2. 对于双向链表来说,要注意:第一个结点的前驱是null,最后一个结点的后继是null
  3. 引入一个last,标志尾巴

2. 😊定义双向链表结点

//双向链表结点
class ListNode {
    public int data;
    public ListNode prev;
    public ListNode next;

    public ListNode(int data) {
        this.data = data;
    }
}

public class MyLinkedList {
    public ListNode head;   //头结点
    public ListNode last;   //尾结点
}

3. 📰功能列表

//生成链表
public void createList()
//打印链表内容
public void display()
//打印链表长度
public int length()
//查找是否包含关键字key在链表当中
public boolean contains(int key)
 
//头插法
public void addFirst(int data)
//尾插法
public void addLast(int data)
 
//找到前一个地址
public Node searchPrev(int index)
//任意位置插入,第一个数据节点为0号下标
public void addIndex(int index,int data)
 
//找关键字key的前驱
public Node searchPrevNode(int key)
//删除第一次出现关键字为key的节点
public void remove(int key)
//删除所有值为key的节点
public void removeAllKey(int key)
 
//清空链表
public void clear()

5. 💻源代码

MyLinkedList.java

//双向链表结点
class ListNode {
    public int data;
    public ListNode prev;
    public ListNode next;

    public ListNode(int data) {
        this.data = data;
    }
}

public class MyLinkedList {
    public ListNode head;   //头结点
    public ListNode last;   //尾结点
    //基本功能
    //打印链表内容
    public void display() {
        if (this.head == null) return;
        ListNode cur = this.head;
        while (cur != null) {
            System.out.print(cur.data+" ");
            cur = cur.next;
        }
        System.out.println();
    }
    //打印链表长度
    public int length() {
        ListNode cur = this.head;
        int count = 0;
        while (cur != null) {
            cur = cur.next;
            count++;
        }
        return count;
    }
    //查找是否包含关键字key在链表当中
    public boolean contains(int key) {
        ListNode cur = this.head;
        while (cur != null) {
            if(cur.data == key) return true;
            cur = cur.next;
        }
        return false;
    }
    //插入功能
    //头插法
    public void addFirst(int data) {
        ListNode node = new ListNode(data);
        if (this.head == null) {
            this.head = node;
            this.last = node;
        } else {
            node.next = this.head;
            this.head.prev = node;
            this.head = node;
        }
    }
    //尾插法
    public void addLast(int data) {
        ListNode node = new ListNode(data);
        if (this.head == null) {
            this.head = node;
            this.last = node;
        } else {
            this.last.next = node;
            node.prev = this.last;
            this.last = node;
        }
    }
    //找到第index的链表头
    public ListNode findIndex(int index) {
        ListNode cur = this.head;
        while (index != 0) {
            cur = cur.next;
            index--;
        }
        return cur;
    }
    //任意位置插入,第一个数据节点为0号下标
    public void addIndex(int index,int data) {
        if (index < 0 || index > this.length()) throw new RuntimeException("插入位置异常");
        if (index == 0) {
            this.addFirst(data);
            return;
        }
        if (index == this.length()) {
            this.addLast(data);
            return;
        }
        ListNode cur = this.findIndex(index);
        ListNode node = new ListNode(data);
        node.next = cur;
        node.prev = cur.prev;
        cur.prev.next = node;
        cur.prev = node;
    }

    //删除第一次出现关键字为key的节点
    public void remove(int key) {
        if (this.head == null) return;
        ListNode cur = this.head;

        while (cur != null) {
            if(cur.data == key) {
                //判断是否为头结点
                if (cur == this.head) {
                    this.head = this.head.next;
                    if (this.head == null) {// 防止只有一个结点
                        this.last = null;
                    } else {
                        this.head.prev = null;
                    }
                } else {
                    cur.prev.next = cur.next;
                    // 判断是否为尾结点
                    if (cur.next == null){
                        this.last = cur.prev;
                    } else {
                        cur.next.prev = cur.prev;
                    }
                }
                return;
            }else {
                cur = cur.next;
            }
        }
    }
    //删除所有值为key的节点
    public void removeAllKey(int key) {
        if (this.head == null) return;
        ListNode cur = this.head;

        while (cur != null) {
            if(cur.data == key) {
                //判断是否为头结点
                if (cur == this.head) {
                    this.head = this.head.next;
                    if (this.head == null) {// 防止只有一个结点
                        this.last = null;
                    } else {
                        this.head.prev = null;
                    }
                } else {
                    cur.prev.next = cur.next;
                    // 判断是否为尾结点
                    if (cur.next == null){
                        this.last = cur.prev;
                    } else {
                        cur.next.prev = cur.prev;
                    }
                }
                cur = cur.next;//继续往后走,不要停,直到为null的时候
            }else {
                cur = cur.next;
            }
        }
    }

    //清空链表
    public void clear() {
        ListNode cur = this.head;
        while (cur != null) {
            ListNode curNext = cur.next;
            cur.prev = null;
            cur.next = null;
            cur = curNext;
        }
        this.head = null;
        this.last = null;
    }
}

test.java

测试代码

public class test {
    public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        myLinkedList.addFirst(1);
        myLinkedList.addFirst(2);
        myLinkedList.addFirst(3);
        myLinkedList.addFirst(4);
        myLinkedList.addFirst(5);
        myLinkedList.addFirst(6);
        myLinkedList.display();
        System.out.println(myLinkedList.length());
        System.out.println(myLinkedList.contains(11));
        myLinkedList.addIndex(0,99);
        myLinkedList.addIndex(1,59);
        myLinkedList.display();
        myLinkedList.remove(99);
        myLinkedList.display();
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值