双向链表与单向链表
- 双向链表能往前查找,单向链表只能往后查找
- 双向链表删除节点时,可以直接到要删除的节点进行操作
- 而单向链表因为不能往前查找前一个节点。所以只能在要删除的节点的前一个节点进行操作
- 双向链表比单向链表多了一个pre指针指向前一个节点
- 逻辑结构都是线性结构,存储接口都是链式存储
创建节点的类
public class Node2(){
//data存储的数据
int id;//id号
String naem;//名字
String nc;//昵称
Node2 pre;//指向前一个节点
Node2 next;//指向下一个节点
//构造方法
public Node2(int id,String name,String nc){
this.id=id;
this.name=name;
this.nc=nc;
//其余默认为null
}
//重写toString方法
public String toString(){
return id+name+nc;
}
}
创建双向链表的类
public class DoubleLinkedList{
//头节点
Node2 head=new Node2(0,"","");
//增加删除查找修改方法
}
双向链表的方法
- add增加元素(默认从最后添加)
//参数传入要添加的值
public void add(Node2 newNode){
//遍历链表
Node2 temp=head;
//循环结束找到链表,最后一个
while(temp.next!=null){
temp=temp.next;
}
/*
//加入元素(节点)
//加入的新节点指向上一个节点
newNode.pre=temp;
//加入的新节点指向下一个节点
newNode.next=temp.next;
//temp这个节点指向新节点
//建议最后temp指向新节点,因为此语句放到前面运行temp.next内容会被覆盖
//而 newNode.next=temp.next; 就会自己指向自己
temp.next=Node;
*/
//因为是链表尾所以newNode.next,默认为null
//只需要两个节点相互连接即可
temp.next=newNode;
newNode.pre=temp;
}
- 删除元素的方法(Delete)
//参数传入yao删除节点的id编号
public void delete(int id){
Node2 temp=head.next;
//判断是否为空链表,空即无需删除
if(temp==null){
return;
}
//遍历双向链表查找要删除的元素,
//temp=null是即没有查询到要删除的元素,到链表尾部
while(temp!=null){
if(temp.id==id){
//找到要删除的节点跳出循环删除节点操作
//前一个节点指向下下一个节点
temp.pre=temp.next;
//判断是否为null可能是最后的一个节点,造成空指针异常
if(temp.next==null){
//后一个节点指向前前一个节点形成双向链表
temp.next.pre=temp.pre;
}
break;
}
}
/*判断是否为链表尾部
这里会有一个错误 ,万一要删除的元素就在链表尾部,
就直接结束方法而不删除了
if(temp.next==null){
return;
}
}
*/
- 修改数据方法
//参数 传入要修改的节点
public void reData(Node2 newNode){
//遍历链表
Node2 temp=this.head.next;
//标记 找未找到节点 默认为FALSE
boolean flag=false;
//temp=null时表示已查找完链表
while(temp!=null){
//通过id判断是否是要修改的节点
if(temp.id==newNode.id){
//表示找到了
flag=true;
//跳出循环
break;
}
temp=temp.next;
}
//判断是否找到进行修改操作
if(flag){
//修改name和nc数据
temp.naem=newNode.naem;
temp.nc=newNode.nc;
}else{
System.out.prinln("未找到要修改的节点");
}
}
- 查询数据的方法
//找到返回该节点 传入要查询节点的id
public node2 lookFor(int i){
// 遍历链表
Node2 temp=this.hear.next;
while(temp!=null){
if(temp.id==id){
return temp;
}
temp=temp.next;
}
//可能是空链表 ,或查询不到
return null;
}
- 添加第二种方法(根据id的大小进行排序添加数据)
//newNode 要添加的节点
public void add2(Node2 newNode){
// 遍历用
Node2 temp=head.next;
while(temp!=null){
//当前节点比新节点 大 所以添加在当前节点的前一个节点
if(temp.id>newNode.id){
break;
}
temp=temp.next;
}
//temp=null表示添加链表尾部
if(temp==null){
add1(newNode);
}else{
//新节点指向下一个节点temp
newNode.next=temp;
//新节点指向上一个节点
newNode.pre=temp.pre;
//temp的前一个节点 的 next修改成newNode
temp.pre.next=newNode;
//当前节点指向上一个节点,改成新节点
temp.pre=newNode;
}
}
双向链表在删除添加时可以直接查询到当前节点,而不像单向链表需要查询到待删除节点的前一个