Java实现双向链表的基本操作

}

3.尾插法

思考:

思考过程与头插法一样,参考头插法

  • 过程图解:
  • 在这里插入图片描述

代码实现:

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;

}

}

4.任意位置插入

思考:

  • 判断Index的合法性
  • 首先判断是否是第一次插入—头插
  • 若不是,再判断是否插入到最后位置—尾插
  • 中间位置插入,需要考虑四个位置,如下图:
  • 图解:
  • 在这里插入图片描述

代码实现:

private void checkIndex(int index){

if(index < 0 || index > len()){

throw new RuntimeException(“index不合法!!”);

}

}

private Node searchIndex(int index){

Node cur = this.head;

while(index != 0) {

cur = cur.next;

index–;

}

return cur;

}

public void addIndex(int index,int data){

checkIndex(index);

if(index == 0){

addFirst(data);

return;

}

if(index == len()){

addLast(data);

return;

}

Node node = new Node(data);

Node cur = searchIndex(index);

node.next = cur;

node.prev = cur.prev;

cur.prev.next = node;

cur.prev = node;

}

5.查找链表中是否包含关键字 key

比较简单,直接贴代码:

public boolean containKey(int key){

Node cur = this.head;

while(cur != null){

if(cur.data == key){

return true;

}

cur = cur.next;

}

return false;

}

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

思考

  • 直接上图解:
  • 在这里插入图片描述

代码实现:

public void deleteKey(int key){

Node cur = this.head;

while(cur != null){

if(cur.data == key){

//头节点

if(cur == this.head){

this.head = this.head.next;

this.head.prev = null;

}

//中间节点

else{

cur.prev.next = cur.next;

if(cur.next != null){

cur.next.prev = cur.prev;

}

//删除的是尾节点,只需要移动tail

else{

this.tail = cur.prev;

}

}

}

cur = cur.next;

}

}

7.删除所有出现关键字为 key 的节点

思考:

根据删除第一次出现关键字为 key 的节点,修改代码即可,考虑特殊情况

代码实现:

public void deleteAllKey(int key){

Node cur = this.head;

while(cur != null){

if(cur.data == key){

//头节点

if(cur == this.head){

this.head = this.head.next;

if(this.head != null){

this.head.prev = null;

}

}

//中间节点

else{

cur.prev.next = cur.next;

if(cur.next != null){

cur.next.prev = cur.prev;

}

//删除的是尾节点,只需要移动tail

else{

this.tail = cur.prev;

}

}

}

cur = cur.next;

}

}

8.链表长度

比较简单,直接贴代码:

public int len(){

int count = 0;

Node cur = this.head;

while(cur != null){

count++;

cur = cur.next;

}

return count;

}

9.链表清空

首先会想到以下代码:

public void clear(){

this.head = null;

}

测试打断点调试:

System.out.println(“===============”);

DoubleLinkedList doubleLinkedList3 = new DoubleLinkedList();

doubleLinkedList3.addLast(1);

doubleLinkedList3.addLast(2);

doubleLinkedList3.addLast(3);

doubleLinkedList3.addLast(4);

doubleLinkedList3.print();

doubleLinkedList3.clear();

System.out.println(“!!!”);

在这里插入图片描述

在这里插入图片描述

然后打开 cmd:

  1. 输入jps
![在这里插入图片描述](https://img-blog.csdnimg.cn/b468df18206741a2b307333f8afdc37c.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5LiA5py16Iqx6Iqx,size_20,color_FFFFFF,t_70,g_se,x_16)
  1. 重定义到一个文本文件
![在这里插入图片描述](https://img-blog.csdnimg.cn/6040423881a440b39401d8c6ae11dbf5.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5LiA5py16Iqx6Iqx,size_20,color_FFFFFF,t_70,g_se,x_16)
  1. 找到 log.txt 所在目录,打开 log.txt
![在这里插入图片描述](https://img-blog.csdnimg.cn/3a6d84ffdd124d439766d74bda707d56.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5LiA5py16Iqx6Iqx,size_20,color_FFFFFF,t_70,g_se,x_16)
  1. 双击打开后,ctrl + f,搜索Node
![在这里插入图片描述](https://img-blog.csdnimg.cn/f19e55eb9c4a497aa126246237eab089.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5LiA5py16Iqx6Iqx,size_19,color_FFFFFF,t_70,g_se,x_16)  
![在这里插入图片描述](https://img-blog.csdnimg.cn/f3b6d1d8f651457ebbc2d70a085c8ad2.jpg)  
仍然有4个,说明插入的4个数据没有被回收掉!  
**故:仅仅将 head 置为null,不能实现链表清空**

解决方法:

大家可以按照上述调试检测,数据是否被回收~

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;

}

附全部代码:

class Node{

public int data;//数据

public Node next;//后继信息

public Node prev;//前驱信息

//提供构造方法

public Node(int data){

this.data = data;

}

}

public class DoubleLinkedList {

public Node head; //表示双向链表的头

public Node tail; //表示当前双向链表的尾

//1.打印链表

public void print(){

Node cur = this.head;

while(cur != null){

System.out.print(cur.data+" ");

cur = cur.next;

}

System.out.println();

}

//2.头插法

public void addFirst(int data){

Node node = new Node(data);

//第一次插入

if(this.head == null){

this.head = node;

this.tail = node;

}

//不是第一次插入

else{

node.next = this.head;

this.head.prev = node;

this.head = node;

}

}

//3.尾插法

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;

}

难道这样就够了吗?不,远远不够!

提前多熟悉阿里往年的面试题肯定是对面试有很大的帮助的,但是作为技术性职业,手里有实打实的技术才是你面对面试官最有用的利器,这是从内在散发出来的自信。

备战阿里时我花的最多的时间就是在学习技术上,占了我所有学习计划中的百分之70,这是一些我学习期间觉得还是很不错的一些学习笔记

我为什么要写这篇文章呢,其实我觉得学习是不能停下脚步的,在网络上和大家一起分享,一起讨论,不单单可以遇到更多一样的人,还可以扩大自己的眼界,学习到更多的技术,我还会在csdn、博客、掘金等网站上分享技术,这也是一种学习的方法。

今天就分享到这里了,谢谢大家的关注,以后会分享更多的干货给大家!

阿里一面就落马,恶补完这份“阿里面试宝典”后,上岸蚂蚁金服

阿里一面就落马,恶补完这份“阿里面试宝典”后,上岸蚂蚁金服

image.png

if(this.head == null){

this.head = node;

this.tail = node;

}

//不是第一次插入

else{

this.tail.next = node;

node.prev = this.tail;

this.tail = node;

}

难道这样就够了吗?不,远远不够!

提前多熟悉阿里往年的面试题肯定是对面试有很大的帮助的,但是作为技术性职业,手里有实打实的技术才是你面对面试官最有用的利器,这是从内在散发出来的自信。

备战阿里时我花的最多的时间就是在学习技术上,占了我所有学习计划中的百分之70,这是一些我学习期间觉得还是很不错的一些学习笔记

我为什么要写这篇文章呢,其实我觉得学习是不能停下脚步的,在网络上和大家一起分享,一起讨论,不单单可以遇到更多一样的人,还可以扩大自己的眼界,学习到更多的技术,我还会在csdn、博客、掘金等网站上分享技术,这也是一种学习的方法。

今天就分享到这里了,谢谢大家的关注,以后会分享更多的干货给大家!

[外链图片转存中…(img-oNEVVpQE-1719161206536)]

[外链图片转存中…(img-16JnJqbk-1719161206537)]

[外链图片转存中…(img-wKJPVd8h-1719161206537)]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值