单链表和双链表的区别
单向链表:只有一个指向下一个节点的next指针。查找的方向只能是一个。
优点:单向链表增加删除节点简单。遍历时候不会死循环;
缺点:只能从头到尾遍历。只能找到后继,比较单一。不能自我删除需要辅助节点。
双向链表:有两个指针,一个指向前一个节点prev,一个后一个节点next。可以双向查找。
优点:可以找到前驱和后继,相对单链表灵活一些;可以自我删除。
缺点:增加删除节点复杂,需要多分配一个指针存储空间。
内存示意图
逻辑结构示意图
crud实践
遍历和单链表相差不大,就是可以选择向前或者是向后遍历。
/**
* 遍历双向链表的方法
*/
public void list(){
if (head.next == null){
System.out.println("此链表为空~~");
return;
}
CharacterNode temp = head.next;
while (true){
if (temp == null){
break;
}
System.out.println(temp);
//将temp后移
temp = temp.next;
}
}
class CharacterNode{
public int id;
public String name;
public String nickname;
public CharacterNode next;
public CharacterNode pre;
public CharacterNode(int id,String name,String nickname){
this.id = id;
this.name = name;
this.nickname = nickname;
}
@Override
public String toString() {
return "CharacterNode{" +
"id=" + id +
", name='" + name + '\'' +
", nickname='" + nickname + '\'' +
'}';
}
}
添加 以添加到最后为例
temp.next = newNode
newNode.pre = temp;
/**
* 添加
* @param characterNode
*/
public void add(CharacterNode characterNode){
CharacterNode temp = head;
while (true){
if (temp.next == null){
break;
}
temp=temp.next;
}
temp.next = characterNode;
characterNode.pre = temp;
}
修改和单链表一致
/**
* 修改
* @param characterNode
*/
public void update(CharacterNode characterNode){
if (head.next == null){
System.out.println("链表为空~~");
return;
}
CharacterNode temp = head.next;
boolean flag = false;
while (true){
if (temp == null){
break;
}
if (temp.id == characterNode.id){
flag = true;
break;
}
temp= temp.next;
}
if (flag){
temp.name = characterNode.name;
temp.nickname = characterNode.nickname;
}else {
System.out.printf("没有找到编号%d的节点,不能修改\n",characterNode.id);
}
}
删除
temp.pre.next = temp.next;
temp.next.pre = temp.pre;
public void del(int id){
if (head.next == null){
System.out.println("链表为空~~");
return;
}
CharacterNode temp = head.next;
boolean flag = false;
while (true){
if (temp == null){
break;
}
if (temp.id == id){
flag= true;
break;
}
temp = temp.next;
}
if (flag){
temp.pre.next = temp.next;
/**
* 注意 最后一个节点不能执行下面的语句 ,负责出现空指针
*/
if (temp.next != null){
temp.next.pre = temp.pre;
}
}else {
System.out.printf("要删除的 %d 节点不存在\n", id);
}
}