上一篇文章中,我们已经对双向链表进行一些基本操作,本篇文章我们继续通过对链表的增删查改来加深对链表的理解~同时有任何不懂的地方可以在评论区留言讨论,也可以私信小编~觉得小编写的还可以的可以留个关注支持一下~话不多说正片开始~
注意:上篇文章少了一些图,这里做些补充重新发一遍
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();
}
到此为止,我们链表的章节就可以跟大家说在再见了,下一篇文章,我们将会进入栈和队列的学习,觉得小编讲的还可以的可以留个关注~我们下期再见~ 谢谢观看~