😽博主优快云主页:小源_😽
🖋️个人专栏:《数据结构》🖋️
😀努力追逐大佬们的步伐~
目录
1. 前言
上一篇文章中我们重点讲解了无头单向非循环链表的模拟实现,现在我们来讲解LinkedList(无头双向链表实现 )的模拟实现。
本章重点:
本文着重讲解了LinkedList(无头双向单链表)的实现和LinkedList的使用。
2. LinkedList(无头双向链表)的模拟实现
从上图可以看出,无头双向链表和无头单向非循环链表结构类似,只是在每个节点中加入了前一个节点的地址(用prev存储),使得每个节点可以访问前一个节点。其中第一个节点的前驱prev为空。
2.1 定义IList接口
无头双向链表的模拟实现要定义的接口和上一篇文章中无头单向非循环链表的模拟实现一样,即:
public interface IList {
//头插法
void addFirst(int data);
//尾插法
void addLast(int data);
//任意位置插入,第一个数据节点为0号下标
void addIndex(int index,int data);
//查找是否包含关键字key是否在单链表当中
boolean contains(int key);
//删除第一次出现关键字为key的节点
void remove(int key);
//删除所有值为key的节点
void removeAllKey(int key);
//得到单链表的长度
int size();
//清空
void clear();
//打印
void display();
}
2.2 重写IList中的方法
定义一个MyLinkedList类来实现IList接口,并且重写IList中的方法
(选中IList,快捷键为Ctrl+O):
首先需要定义一个内部类作为节点的类,用static修饰,代表只能在当前类中使用。
接着定义一个头节点head,尾节点last。
public class MyLinkedList implements IList{
static class ListNode {
public int val;
public ListNode next;
public ListNode prev;
public ListNode(int val) {
this.val = val;
}
}
public ListNode head;
public ListNode last;
@Override
public void addFirst(int data) {
}
@Override
public void addLast(int data) {
}
@Override
public void addIndex(int index, int data) {
}
@Override
public boolean contains(int key) {
return false;
}
@Override
public void remove(int key) {
}
@Override
public void removeAllKey(int key) {
}
@Override
public int size() {
return 0;
}
@Override
public void clear() {
}
@Override
public void display() {
ListNode cur = head;
while (cur != null) {
System.out.println(cur.next + " ");
cur = cur.next;
}
System.out.println();
}
}
2.3 display(打印方法)
遍历双向链表的方法和遍历单链表相同:我们只需关心next域,而不需要关心prev。
@Override
public void display() {
ListNode cur = head;
while (cur != null) {
System.out.print(cur.val + " ");
cur = cur.next;
}
System.out.println();
}
}
2.4 size方法
求链表个数/长度
@Override
public int size() {
ListNode cur = head;
//定义一个计数器
int count = 0;
while (cur != null) {
count++;
cur = cur.next;
}
return count;
}
2.5 contains方法
指的是查找是否包含关键字key是否在单链表当中。这里跟size方法相似,只需遍历链表时判断是否cur.val == key
@Override
public boolean contains(int key) {
ListNode cur = head;
while (cur != null) {
//判断
if (cur.val == key) {
return true;
}
cur = cur.next;
}
return false;
}
2.6 addFirst头插法
指的是将插入的节点存放在链表的第一个位置。
1.实例化一个节点
2.改变插入节点的next和prev
3.改变head
@Override
public void addFirst(int data) {
ListNode node = new ListNode(data);
//如果head为空,则head和last都指向node
if (head == null) {
head = node;
last = node;
} else {
node.next =