目录
一、双链表的定义
对于链表中的任意节点,既可以通过该节点向后走,也可以通过该节点向前走
(就是说相较于单链表多存储了该节点前面节点的地址)
双向链表的实际应用中非常广泛
二、双向链表——插
1、双向链表头插
(1)、头插图解思路
(2)、头插代码实现
/**
* 双向链表的头插
* @param val
*/
public void addFirst(int val){
doubleNode node=new doubleNode(val);
//判断链表是否为空
if (head==null){
head=tail=node;
}else{
node.next=head;
head.prev=node;
head=node;
}
size++;
}
2、双向链表的尾插
(1)、尾插图解
(2)、尾插代码实现
/**
* 双向链表的尾插
* @param val
*/
public void addLast(int val){
doubleNode node=new doubleNode(val);
if (head==null){
head=node;
}else{
tail.next=node;
node.prev=tail;
tail=node;
}
size++;
}
3、双向链表在index位置插入
(1)index位置插入图解
(2)index位置插入代码
/**
* 双向链表在索引位置插入值为val的节点
* @param index
* @param val
*/
public void add(int index,int val){
//判断index是否合法
if (index<0||index>size){
System.err.println("index不在范围内");
return;
}
if (index==0){
//相当于头插
addFirst(val);
}else if (index==size){
//相当于尾插
addLast(val);
}else{
//利用方法找到前驱,前驱在index-1的位置
doubleNode prev=findNode(index-1);
doubleNode node=new doubleNode(val);
node.next=prev.next;
prev.next.prev=node;
node.prev=prev;
prev.next=node;
size++;
}
}
/**
* 根据索引值寻找对应的节点
* @param index
* @return
*/
private doubleNode findNode(int index){
doubleNode x=null;
if (index<size){
x=head;
for (int i = 0; i <index; i++) {
x=x.next;
}
}else{
x=tail;
for (int i =index; i <size-1; i--) {
x=x.prev;
}
}return x;
}
二、双向链表——查找
public int get(int index):查找索引为index的节点值,返回节点值
/**
* 查找索引为index的节点值,返回节点值
* @param index
* @return
*/
public int get(int index){
//判断index的合法性
if (judgeIndex(index)){
doubleNode x=findNode(index);
return x.val;
}
return -1;
}
/**
* 判断index是否合法
* @param index
* @return
*/
private boolean judgeIndex(int index){
if (index<0||index>=size){
return false;
}
return true;
}
/**
* 根据索引值寻找对应的节点
* @param index
* @return
*/
private doubleNode findNode(int index){
doubleNode x=null;
if (index<size){
x=head;
for (int i = 0; i <index; i++) {
x=x.next;
}
}else{
x=tail;
for (int i =index; i <size-1; i--) {
x=x.prev;
}
}return x;
}
三、双向链表——修改
public int set(int index,int val):修改索引为index的节点值为val,返回修改前的值
/**
* 修改索引为index位置的节点值为val,返回修改前的值
* @param index
* @param val
* @return
*/
public int set(int index,int val){
//判断index的合法性
if (judgeIndex(index)){
doubleNode x=findNode(index);
int oldVal=x.val;
x.val=val;
return oldVal;
}
return -1;
}
/**
* 判断index是否合法
* @param index
* @return
*/
private boolean judgeIndex(int index){
if (index<0||index>=size){
return false;
}
return true;
}
/**
* 根据索引值寻找对应的节点
* @param index
* @return
*/
private doubleNode findNode(int index){
doubleNode x=null;
if (index<size){
x=head;
for (int i = 0; i <index; i++) {
x=x.next;
}
}else{
x=tail;
for (int i =index; i <size-1; i--) {
x=x.prev;
}
}return x;
}
四、双向链表——删除
·1、删除双向链表中索引为index的节点
(1)删除index节点图解
2、删除index节点的代码
/**
* 删除链表中索引为index的节点
* @param index
*/
public void removeIndex(int index){
//判断index是否合法
if (judgeIndex(index)){
doubleNode node=findNode(index);
removeNode(node);
}else{
System.err.println("index不在范围内");
}
}
/**
* 删除当前链表中的node节点
* @param node
*/
public void removeNode(doubleNode node){
doubleNode prev=node.prev;
doubleNode successor=node.next;
//1.先处理node的前半部分
//判断前驱是否为空,为空则是删除头节点
if (prev==null){
head=successor;
}else{
//此时前驱不为空
prev.next=successor;
node.prev=null;
}
//2.在处理node的后半部分
//判断后继节点是否为空,相当于删除尾节点
if (successor==null){
tail=prev;
}else{
//此时后继节点不为空
successor.prev=prev;
node.next=null;
}
size--;
}
/**
* 根据索引值寻找对应的节点
* @param index
* @return
*/
private doubleNode findNode(int index){
doubleNode x=null;
if (index<size){
x=head;
for (int i = 0; i <index; i++) {
x=x.next;
}
}else{
x=tail;
for (int i =index; i <size-1; i--) {
x=x.prev;
}
}return x;
}
2、双向链表删除第一个值为val的节点
/**
* 删除链表中第一和值为val的节点
*/
public void removeValOnce(int val){
for (doubleNode x=head;x!=null;x=x.next) {
if (x.val==val){
removeNode(x);
break;
}
}
}
3、双向链表删除所有值为val的节点
/**
* 删除链表中所有值为val的节点
*/
public void removeAllVal(int val){
for (doubleNode x=head;x!=null;) {
if (x.val==val){
//此时x是待删除的点,同时保存一下x的后继节点的地址
doubleNode successor=x.next;
removeNode(x);
x=successor;
}else{
//此时x已经不是待删除的点了,这是让for循环继续向下判断
x=x.next;
}
}
}
五、双向链表的全部代码
https://gitee.com/ren-xiaoxiong/rocket_class_ds/blob/master/src/linkedList/DoubleLinkedList.java
https://gitee.com/ren-xiaoxiong/rocket_class_ds/blob/master/src/linkedList/doubleLinkedTest.java