1.单向链表和双向链表优缺点的分析
1.单向链表查找的方向只能是一个方向,而双向链表可以向前或者向后查找
2.单向链表不能自我删除,需要借助辅助节点,而双向链表,则可以实现自我删除,所以,单链表删除节点时,总是想找到temp节点,temp是待删除节点的前一个节点
2.双向链表的遍历,添加,修改,删除的操作思路分析
2.1遍历:
遍历方法和单链表一样,只是可以向前,也可以向后遍历
2.2添加:
①先找到双向链表的最后这个节点
②temp.next = newHeroNode
③newHeroNode.pre = temp
2.3修改:
修改的思路和原理和单链表一样
2.4删除:
①因为是双向链表,可以实现自我删除
②直接找到要删除的节点
③temp.pre.next = temp.next
④temp.next.pre = temp.pre
代码示例:
package com.wxit.linkedlist;
/**
* @Author wj
**/
public class DoubleLinkedListDemo {
public static void main(String[] args) {
System.out.println("双向链表的测试!");
//创建节点
HeroNode2 hero1 = new HeroNode2(1, "宋江", "及时雨");
HeroNode2 hero2 = new HeroNode2(2, "卢俊义", "玉麒麟");
HeroNode2 hero3 = new HeroNode2(3, "吴用", "智多星");
HeroNode2 hero4 = new HeroNode2(4, "林冲", "豹子头");
//创建双向链表
DoubleLinkedList doubleLinkedList = new DoubleLinkedList();
doubleLinkedList.add(hero1);
doubleLinkedList.add(hero2);
doubleLinkedList.add(hero3);
doubleLinkedList.add(hero4);
doubleLinkedList.list();
//修改
System.out.println("双向链表的修改!");
HeroNode2 newHeroNode = new HeroNode2(4, "公孙胜", "入云龙");
doubleLinkedList.update(newHeroNode);
doubleLinkedList.list();
System.out.println("删除操作");
doubleLinkedList.delete(2);
doubleLinkedList.list();
}
}
//创建一个双向链表的类
class DoubleLinkedList{
private HeroNode2 head = new HeroNode2(0,"","");
public HeroNode2 getHead(){
return head;
}
//遍历双向链表的方法
public void list(){
//判断链表是否为空
if (head.next == null){
System.out.println("链表为空");
return;
}
//因为头节点不能动,所以需要一个辅助变量来遍历
HeroNode2 temp = head.next;
while (true){
//判断是否到链表最后
if (temp == null){
break;
}
//输出节点信息
System.out.println(temp);
//将temp后移
temp = temp.next;
}
}
//添加
public void add(HeroNode2 heroNode){
//因为头节点不能动,因此,需要一个辅助变量来遍历
HeroNode2 temp = head;
//遍历链表,找到最后
while (true){
if (temp.next == null){
break;
}
//没有找到就将temp后移
temp = temp.next;
}
//当退出while循环时,就是遍历到链表最后
temp.next = heroNode;
heroNode.pre = temp;
}
//修改一个节点的内容
public void update(HeroNode2 heroNode){
//判断是否为空
if (head.next == null){
System.out.println("链表为空");
return;
}
//如果不为空,根据id编号来修改
//定义一个辅助变量
HeroNode2 temp = head.next;
boolean flag = false;//表示是否找到该节点
while (true){
if (temp == null){
break;//已经遍历完链表
}
if (temp.id == heroNode.id){
//找到
flag = true;
break;
}
temp = temp.next;
}
//根据flag判断是否找到要修改的节点
if (flag){
temp.name = heroNode.name;
temp.nickName = heroNode.nickName;
} else {
System.out.println("没有知道要删除的节点");
}
}
//从双向链表中删除一个节点
/**
*
* @param id
* 说明:
* 1.对于双向链表,可以直接找到要删除的这个节点
* 2.找到后,自我删除即可
*/
public void delete(int id){
//判断当前链表是否为空
if (head.next == null){
System.out.println("该链表为空,无法删除");
return;
}
HeroNode2 temp = head.next;
boolean flag = false;
while (true){
if (temp == null){
System.out.println("已经到链表最后");
break;
}
if (temp.id == id){
//找到要删除节点的前一个节点temp
flag = true;
break;
}
temp = temp.next;
}
//判断flag
if (flag){
//找到要删除的节点,可以删除
temp.pre.next = temp.next;
if (temp.next != null){
temp.next.pre = temp.pre;
}
} else {
System.out.println("没有找到要删除的节点");
}
}
}
//定义节点
class HeroNode2{
public int id;
public String name;
public String nickName;
public HeroNode2 next;
public HeroNode2 pre;//指向前一个节点
//构造器
public HeroNode2(int id, String name, String nickName) {
this.id = id;
this.name = name;
this.nickName = nickName;
}
@Override
public String toString() {
return "HeroNode{" +
"id=" + id +
", name='" + name + '\'' +
", nickName='" + nickName + '\'' +
'}';
}
}