前奏
双向循环链表特点:一个节点分为3部分,上节点(preNode)、下节点(nextNode) nodeData(当前节点数据)
节点代码
class MyNode{
public Object obj;
public MyNode nextNode;
public MyNode preNode;
public MyNode(Object obj){
this.obj=obj;
}
public MyNode(){}
@Override
public String toString() {
return ("当前节点内容:"+obj+"下一个节点:"+(nextNode==null?"空":""+nextNode.obj)+"上一个节点"+(preNode==null?"空":""+preNode.obj));
}
}
双向链表思路图解:
添加思路:
1:由于是循环链表判断什么时候为链表的最后一个节点,提示当更新完最后一个节点信息进行一个判断currNode.next==headNode.nextNode break; 即可
2:判断链表一开始为空怎么处理新节点
3:判断当前新节点在链表第一个位置怎么处理 提示:要更新尾节点、原第一个节点、头节点指向
4:判断当前新节点在链表最后一个位置怎么处理 提示:要更新链表第一个节点、最后一个节点
5:判断当前新节点在链表中间位置怎么处理
删除思路:
1:删除的节点是链表的第一个节点怎么处理 注意:获取尾节点对节点的nextNode更新及preNode更新(preNode节点如果刚好是链表第一个节点的时候 需要更新 其余无需更新) 要更新头节点的指向位置
2:当删除一个节点的时候该节点刚好是链表唯一节点 这时候怎么处理 提示:将headNode.nextNode=null;即可
3:当删除节点为链表的末尾位置怎么处理
4:当删除节点为链表的中间位置怎么处理
JAVA代码:
package com.king2.dataStructer.linked;
public class BothWayLinkedDemo {
public static void main(String[] args) {
MyBothWayLinked linked=new MyBothWayLinked();
linked.addLoopNodeOrderBy(2);
linked.addLoopNodeOrderBy(1);
linked.addLoopNodeOrderBy(3);
linked.addLoopNodeOrderBy(4);
linked.deleteLoopNode(1);
linked.deleteLoopNode(2);
linked.deleteLoopNode(4);
linked.showNode();
}
}
class MyBothWayLinked{
private MyNode headNode=new MyNode();
public void addNode(Object obj){
MyNode newNode=new MyNode(obj);
MyNode currHeadNode=headNode;
while(currHeadNode.nextNode!=null){
currHeadNode=currHeadNode.nextNode;
}
newNode.preNode=currHeadNode;
currHeadNode.nextNode=newNode;
}
public void addNodeOrderBy(Object obj){
MyNode newNode=new MyNode(obj);
MyNode currHeadNode=headNode;
MyNode currNextNode=null;
while(currHeadNode.nextNode!=null){
currNextNode=currHeadNode.nextNode;
if(Integer.parseInt(currNextNode.obj.toString())>Integer.parseInt(obj.toString())){
break;
}
currHeadNode=currNextNode;
}
newNode.preNode=currHeadNode;
newNode.nextNode=currHeadNode.nextNode;
if(currHeadNode.nextNode!=null) currHeadNode.nextNode.preNode=newNode;
currHeadNode.nextNode=newNode;
}
public void addLoopNode(Object obj){
MyNode newNode=new MyNode(obj);
MyNode currHeadNode=headNode;
while(currHeadNode.nextNode!=null){
currHeadNode=currHeadNode.nextNode;
if(currHeadNode.nextNode==headNode.nextNode){
break;
}
}
if(currHeadNode==headNode){
newNode.preNode=newNode;
newNode.nextNode=newNode;
}else{
newNode.preNode=currHeadNode;
newNode.nextNode=currHeadNode.nextNode;
headNode.nextNode.preNode=newNode;
}
currHeadNode.nextNode=newNode;
}
public void addLoopNodeOrderBy(Object obj){
MyNode newNode=new MyNode(obj);
MyNode currHeadNode=headNode;
MyNode currNextNode=null;
while(currHeadNode.nextNode!=null){
currNextNode=currHeadNode.nextNode;
if(Integer.parseInt(currNextNode.obj.toString())>Integer.parseInt(obj.toString())){
break;
}
currHeadNode=currNextNode;
if(currHeadNode.nextNode==headNode.nextNode){
break;
}
}
if(currHeadNode.nextNode==null){
newNode.preNode=newNode;
newNode.nextNode=newNode;
currHeadNode.nextNode=newNode;
}
else if(currHeadNode==headNode){
MyNode currNode=headNode;
while(currNode.nextNode!=null){
currNode=currNode.nextNode;
if(currNode.nextNode==headNode.nextNode)break;
}
currNode.nextNode=newNode;
newNode.preNode=currNode;
newNode.nextNode=currHeadNode.nextNode;
currHeadNode.nextNode.preNode=newNode;
currHeadNode.nextNode=newNode;
}
else if(currHeadNode.nextNode==headNode.nextNode){
newNode.preNode=currHeadNode;
newNode.nextNode=currHeadNode.nextNode;
currHeadNode.nextNode=newNode;
headNode.nextNode.preNode=newNode;
}
else{
newNode.preNode=currHeadNode;
newNode.nextNode=currHeadNode.nextNode;
currHeadNode.nextNode.preNode=newNode;
currHeadNode.nextNode=newNode;
}
}
public boolean deleteNode(Object obj){
MyNode currHeadNode=headNode;
MyNode currNextNode=null;
while(currHeadNode.nextNode!=null){
currNextNode=currHeadNode.nextNode;
if(currNextNode.obj.equals(obj)){
if(currNextNode.nextNode!=null){
currHeadNode.nextNode.preNode=currHeadNode;
}
currHeadNode.nextNode=null;
return true;
}
}
return false;
}
public boolean deleteLoopNode(Object obj){
MyNode currHeadNode=headNode;
MyNode currNextNode=null;
while(currHeadNode.nextNode!=null){
currNextNode=currHeadNode.nextNode;
if(currNextNode.obj.equals(obj)){
if(currNextNode==headNode.nextNode){
MyNode currNode=headNode;
while(currNode.nextNode!=null){
currNode=currNode.nextNode;
if(currNode.nextNode==headNode.nextNode){
break;
}
}
if(currNextNode.nextNode==currNextNode){
currHeadNode.nextNode=null;
}else{
if(currNode.preNode==currNextNode){
currNode.preNode=currNode;
}
currNode.nextNode=currNextNode.nextNode;
currHeadNode.nextNode= currNextNode.nextNode;
currNextNode.nextNode.preNode=currNode;
}
}
else if(currNextNode.nextNode==headNode.nextNode){
currHeadNode.nextNode=currNextNode.nextNode;
headNode.nextNode.preNode=currHeadNode;
}
else{
currHeadNode.nextNode=currNextNode.nextNode;
currNextNode.nextNode.preNode=currHeadNode;
}
return true;
}
currHeadNode=currNextNode;
if(currHeadNode.nextNode==headNode.nextNode)break;
}
return false;
}
public void showNode(){
MyNode currHeadNode=headNode;
while(currHeadNode.nextNode!=null){
System.out.println(currHeadNode.nextNode);
currHeadNode=currHeadNode.nextNode;
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
结果