Java中的LinkedList集合类 , 它的底层就是一个双向链表 !
区分于单向链表,它多一个prev(前驱) 如图 :
接下来我们来模拟一个LinkedList 并去实现一些它的一些常用的方法.
class ListNode {
int val;
ListNode prev;
ListNode next;
ListNode(int x) {
val = x;
next = null;
}
}
public class MyLinkedList {
ListNode head;
ListNode last;
//头插法
public void addFirst(int data){ }
//尾插法
public void addLast(int data){}
//任意位置插入,第一个数据节点为0号下标
public void addIndex(int index,int data){}
//查找是否包含关键字key是否在单链表当中
public boolean contains(int key){}
//删除第一次出现关键字为key的节点
public void remove(int key){}
//删除所有值为key的节点
public void removeAllKey(int key){}
//得到单链表的长度
public int size(){}
public void display(){}
public void clear(){}
}
1. 头插法
//头插法
public void addFirst(int data){
ListNode newNode = new ListNode(data);
if (head == null) {
this.head = newNode;
return;
}
this.head.prev = newNode;
newNode.next = this.head;
this.head = newNode;
}
2. 尾插法
//尾插法
public void addLast(int data){
ListNode newNode = new ListNode(data);
if (head == null) {
this.head = newNode;
this.last = newNode;
return;
}
this.last.next = newNode;
newNode.prev = this.last;
this.last = newNode;
}
3.任意位置插入
//任意位置插入,第一个数据节点为0号下标
public void addIndex(int index,int data){
if (index == 0) {
addFirst(data);
return;
}
if (index == size()) {
addLast(data);
return;
}
ListNode newNode = new ListNode(data);
//通过findIndex方法找到data的那个节点
ListNode cur = findIndex(data);
cur.prev.next = newNode;
newNode.prev = cur.prev;
cur.prev = newNode;
newNode.next = cur;
}
public ListNode findIndex (int index) {
ListNode cur = this.head;
while (index-- > 0) {
cur = cur.next;
}
return cur;
}
4. 在链表中查找是否包含关键字key
//查找是否包含关键字key是否在单链表当中
public boolean contains(int key){
ListNode cur = this.head;
while (cur != null) {
if (cur.val == key) {
return true;
}
cur = cur.next;
}
return false;
}
5. 删除第一次出现关键字为key的节点
在这里需要判断二个情况 :
两个特殊点 : 一是假如要被删除的节点如果是头结点的话,那么赋值的时候就要注意,直接让头结点往后移动一个位置,移动之后让头结点的prev置为null.
二是如果删除的是尾巴节点,那么cur.next.prev就不可以去使用了,会导致空指针异常!所以还要去再加判断确保cur.next != null , 删除完尾巴节点之后,让last往前移动一个位置.
//删除第一次出现关键字为key的节点
public void remove(int key){
ListNode cur = this.head;
while (cur != null) {
if (cur.val == key) {
if (cur != head) {
//中间 尾巴
cur.prev.next = cur.next;
if (cur.next != null) {
cur.next.prev = cur.prev;
} else {
//如果删的是最后一个元素 那么把last往前移动一个.
this.last = this.last.prev;
}
} else {
this.head = this.head.next;
if (this.head != null) {
this.head.prev = null;
}
}
return;
}
cur = cur.next;
}
}
6.删除所有值为key的节点
只需要把上面的return去掉.
//删除所有值为key的节点
public void removeAllKey(int key){
ListNode cur = this.head;
while (cur != null) {
if (cur.val == key) {
if (cur != head) {
//中间 尾巴
cur.prev.next = cur.next;
if (cur.next != null) {
cur.next.prev = cur.prev;
} else {
//如果删的是最后一个元素 那么把last往前移动一个.
this.last = this.last.prev;
}
} else {
this.head = this.head.next;
if (this.head != null) {
this.head.prev = null;
}
}
}
cur = cur.next;
}
}
7.获得长度
//得到双向链表的长度
public int size(){
int count = 0;
ListNode cur = this.head;
while (cur != null) {
cur = cur.next;
count++;
}
return count;
}
8 . 清空链表
public void clear(){
ListNode cur = this.head;
while (this.head != null) {
cur = cur.next;
this.head.prev = null;
this.head.next = null;
this.head = cur;
}
}
9 .打印链表
//打印链表
public void display(){
ListNode cur = this.head;
while (cur != null) {
System.out.print(cur.val + " ");
}
System.out.println();
}
以上就是模拟情况下实现了LinkedList的一些常用的方法.
接下来我们再来看一下Java中提供的LinkedList
这是LinkedList的构造方法 :
public static void main(String[] args) {
// 构造一个空的LinkedList
List<Integer> list1 = new LinkedList<>();
List<String> list2 = new java.util.ArrayList<>();
list2.add("JavaSE");
list2.add("JavaWeb");
list2.add("JavaEE");
// 使用ArrayList构造LinkedList
List<String> list3 = new LinkedList<>(list2);
}
下面是java提供的一些方法 :
迭代器 :
LinkedList<Integer> linkedList = new LinkedList<>();
linkedList.add(12);
linkedList.add(13);
linkedList.add(14);
//利用迭代器正向打印
ListIterator<Integer> it = linkedList.listIterator();
while (it.hasNext()) {
System.out.print(it.next());
}
System.out.println("=============");
//利用迭代器反向打印
ListIterator<Integer> it2 = linkedList.listIterator(linkedList.size());
while (it2.hasPrevious()) {
System.out.print(it2.previous());
}
总结 ArrayList 与 LinkedList 的区别 :
到此就结束了 ~
大家有什么问题可以私信我 . 希望能帮到大家~~~~~~