学到了吗(jdk双向链表)java单向链表和双向链表,java实现双向链表,java双向链表实现,
一 前言
之前知识知识追寻者写了一篇单链表的实现,感觉不是很满意,写的逻辑不够清晰,有些地方实现的不过好,不能连成一个整体,伪单链表;为此研究了一会双向链表的简单实现;本篇的实现方式是以方法的形式展现,读者可以将其整合为一个类;
二 双向链表简介
双向链表的定义是,一个节点有两个方向,分别储存当前节点的前驱节点,和后续节点;双向链表的删除只需要指定前驱节点,或者后续节点就可以进行删除操作;但是缺点也很明显每次添加节点时都需要2个指向,额外增加了内存空间消耗;

三 双向链表的实现
3.1 定义链表节点
定义data存储数据,知识追寻者使用的时int类型,读者可以改为object类型;定义前驱节点previous定义后续节点next/*** @Author lsc* <p> 双向链表节点 </p>*/public class DoubleNode {//数据private Integer data;//后续节点节点private DoubleNode next;//前驱节点private DoubleNode previous;// 省略set get}
3.2 插入头节点
思路如下
将新节点的前驱节点指向nul新节点的后续节点指向表头将表头的前驱节点指向新节点public class DoubleList {private DoubleNode head;/* ** @Author lsc* <p> 表头插入节点* 思路: 1 将新节点的前驱节点指向null,* 2新节点的后续节点指向表头* 3 将表头的前驱节点指向新节点* </p>* @Param [data]* @Return void*/public void addFirst(int data){// 创建新节点DoubleNode newNode = new DoubleNode();// 为新节点添加数据newNode.setData(data);// 如果表头为空直接将新节点作为头if (head==null){head = newNode;}else {// 将新节点的前驱节点指向null(声明的时候本来就是null)//新节点的后续节点指向表头newNode.setNext(head);// 将表头的前驱节点指向新节点head.setPrevious(newNode);// head重新赋值head = newNode;}}/* ** @Author lsc* <p>顺序打印链表思路:从链表的头遍历到链表的尾巴* </p>* @Param []* @Return void*/public void displayNext(){// 将表头作为当前节点DoubleNode currentNode = head;// 遍历链表while (currentNode!=null){// 打印数据System.out.println(currentNode.getData());// 将下一个节点作为当前节点currentNode = currentNode.getNext();}}}
测试代码如下,往前插入数据,打印出来就是倒序
public static void main(String[] args) {DoubleList doubleList = new DoubleList();for (int i = 0; i <5 ; i++) {doubleList.addFirst(i);}doubleList.displayNext();}
结果
43210
3.3 插入尾节点
思路如下
表尾的后续节点指向新节点新节点的前驱节点指向表尾新节点的后续节点指向null/* ** @Author lsc* <p> 表尾插入节点* 思路 : 1 表尾的后续节点指向新节点* 2 新节点的前驱节点指向表尾* 3 新节点的后续节点指向null* </p>* @Param [data]* @Return void*/public void addLast(int data){// 创建新节点DoubleNode newNode = new DoubleNode();// 为新节点添加数据newNode.setData(data);// 如果表头为空直接将新节点作为头if (head==null){head = newNode;}else {DoubleNode currentNode = head;//寻找尾节点while (currentNode.getNext()!=null){currentNode = currentNode.getNext();}//表尾的后续节点指向新节点currentNode.setNext(newNode);//新节点的前驱节点指向表尾newNode.setPrevious(currentNode);}}
测试代码如下,往表为插入数据,也就是顺序打印
public static void main(String[] args) {DoubleList doubleList = new DoubleList();for (int i = 0; i <5 ; i++) {//doubleList.addFirst(i);doubleList.addLast(i);}doubleList.displayNext();}
结果
01234
3.4 获取链表长度
思路 :遍历链表,一个节点代表一个单位的长度
/* ** @Author lsc* <p> 获得链表长度* 思路:遍历链表,一个节点代表一个单位的长度* </p>* @Param []* @Return int*/public int length(){int length = 0;// 当前节点DoubleNode currentNode = head;while (currentNode!=null){// 一个节点 length 长度就加1length++;// 将下一个节点作为当前节点currentNode = currentNode.getNext();}return length;}
3.5 指定位置插入节点
思路: 假设在BC直接插入新节点N
B 节点的后续节点指向 NN 节点 的前驱节点指向 BN 节点的后续节点指向 CC 节点的前驱节点指向 N重要的也就是要找到B节点的位置,转存C节点;

/* ** @Author lsc* <p> 指定位置插入节点* 思路: 假设在AB直接插入新节点N* 1 A 节点的后续节点指向 N* 2 N 节点 的前驱节点指向 A* 3 N 节点的后续节点指向 B* 4 B 节点的前驱节点指向 N* 重点也是找到A节点的位置* </p>* @Param [data]* @Return void*/public void add(int data, int index){// 索引超出,非法if (index<0 || index>length()){System.out.println("非法索引");return;}// 如果索引为0,调用addFirst方法if (index==0){addFirst(data);return;}// 如果索引等于链表的长度,调用addLast方法if (index==length()){addLast(data);return;}// 创建新节点DoubleNode newNode = new DoubleNode();// 为新节点添加数据newNode.setData(data);// 当前节点DoubleNode currentNode = head;// 定义指针int point = 0;// 寻找插入新节点的上一个节点Awhile ((index-1)!= point){currentNode = currentNode.getNext();point++;}// 转存当前节点的后续节点DoubleNode nextNode = currentNode.getNext();// 当前节点的后续节点指向新节点currentNode.setNext(newNode);// 新接的前驱节点指向当前节点newNode.setPrevious(currentNode);// 新节点的后续节点指向转存的节点newNode.setNext(nextNode);// 转存节点的前驱节点指向新节点nextNode.setPrevious(newNode);}
测试代码
public static void main(String[] args) {DoubleList doubleList = new DoubleList();for (int i = 0; i <5 ; i++) {doubleList.addLast(i);}doubleList.add(666,3);doubleList.displayNext();}
结果
01266634
3.6 删除表头
思路如下
创建一个临时节点,存储表头的后续节点将临时节点的前驱节点指向null将临时节点赋值给表头/* ** @Author lsc* <p> 删除表头思路: 1 创建一个临时节点,存储表头的后续节点* 2 将临时节点的前驱节点指向null* 3 将临时节点赋值给表头* </p>* @Param []* @Return void*/public void removeFirst(){if (length()==0){return;}// 只有一个节点直接清空表头if (length()==1){head=null;return;}// 创建一个临时节点,存储表头的后续节点DoubleNode temNode = head.getNext();// 将临时节点的前驱节点指向nulltemNode.setPrevious(null);// 将临时节点赋值给表头head = temNode;}
测试代码
public static void main(String[] args) {DoubleList doubleList = new DoubleList();for (int i = 0; i <5 ; i++) {doubleList.addLast(i);}doubleList.removeFirst();doubleList.displayNext();}
结果
1234
3.7 删除表尾
思路
找到表尾的前驱节点将表尾的前驱节点的后续节点置为null/* ** @Author lsc* <p> 删除表尾思路: 1 找到表尾的前驱节点* 2 将表尾的前驱节点的后续节点置为null* 3* </p>* @Param []* @Return void*/public void removeLast(){if (length()==0){return;}// 只有一个节点直接清空表头if (length()==1){head=null;return;}DoubleNode previousNode = head;// 寻找尾节点的前驱节点while (previousNode.getNext().getNext()!=null){previousNode = previousNode.getNext();}previousNode.setNext(null);}
测试代码
public static void main(String[] args) {DoubleList doubleList = new DoubleList();for (int i = 0; i <5 ; i++) {//doubleList.addFirst(i);doubleList.addLast(i);}doubleList.removeLast();doubleList.displayNext();}
结果
0123
3.8 删除指定节点
思路: 假设有BCD节点要删除B节点
将 B 节点的后续节点指向 D节点将D节点前驱节点指向B节点重要的也就是要找到B节点位置,转存D节点;

/* ** @Author lsc* <p> 指定位置删除节点思路: 假设有ABC节点要删除B节点* 1 将 A 节点的后续节点指向 C节点* 2 将C节点前驱节点指向A节点* </p>* @Param [index]* @Return void*/public void remove(int index){if (index<0 || index>=length()){System.out.println("非法索引");return;}// 头节点if (index==0){removeFirst();return;}// 尾节点if (index==(length()-1)){removeLast();return;}// 欲想删除节点的前驱节点DoubleNode previousNode = head;// 定义指针int point = 0;// 寻找新节while ((index-1)!=point){previousNode = previousNode.getNext();point++;}// 欲想删除节点的后续节点DoubleNode nextNode = previousNode.getNext().getNext();// 将欲想删除节点的前驱节点的后续节点指向欲想删除节点的后续节点previousNode.setNext(nextNode);// 将欲想删除节点的后续节点的前驱节点指向欲想删除节点的前驱节点nextNode.setPrevious(previousNode);}
测试代码
public static void main(String[] args) {DoubleList doubleList = new DoubleList();for (int i = 0; i <5 ; i++) {//doubleList.addFirst(i);doubleList.addLast(i);}doubleList.remove(3);doubleList.displayNext();}
结果
0124
版权申明
本文系作者 @河马 原创发布在河马博客站点。未经许可,禁止转载。
暂无评论数据