双向链表
思路分析
代码:
public class Test4 {
public static void main(String[] args) {
//先创建节点
HeroNode2 heroNode1 = new HeroNode2(1, "宋江", "及时雨");
HeroNode2 heroNode2 = new HeroNode2(2, "林冲", "豹子头");
HeroNode2 heroNode3 = new HeroNode2(3, "卢俊义", "玉麒麟");
HeroNode2 heroNode4 = new HeroNode2(4, "吴用", "智多星");
//创建要给链表
DoubleLinkedList doubleLinkedList = new DoubleLinkedList();
doubleLinkedList.add(heroNode1);
doubleLinkedList.add(heroNode2);
doubleLinkedList.add(heroNode3);
doubleLinkedList.add(heroNode4);
//显示一下链表
doubleLinkedList.list();
//修改链表
HeroNode2 newHeroNode = new HeroNode2(4,"公孙胜","入云龙");
doubleLinkedList.update(newHeroNode);
System.out.println("----------------------");
doubleLinkedList.list();
//删除后的情况
System.out.println("----------------");
doubleLinkedList.del(2);
doubleLinkedList.list();
//测试第二种添加方法
doubleLinkedList.addByOrder(heroNode2);
System.out.println("-------------");
doubleLinkedList.list();
}
}
//创建一个双向链表的类
class DoubleLinkedList{
//先初始化一个头节点,头节点不要动,不存放具体的数据
private HeroNode2 heroNode2 = new HeroNode2(0,"","");
//返回头节点
public HeroNode2 getHead(){
return heroNode2;
}
//遍历链表的方法
public void list(){
//判断链表是否为空
if(heroNode2.next==null){
System.out.println("链表为空");
return;
}
//因为头节点,不能动,因此需要一个辅助变量来遍历
HeroNode2 temp = heroNode2.next;
while (true){
//判断链表是否到最后
if (temp==null){
break;
}
//输出节点信息
System.out.println(temp);
//将next后移
temp=temp.next;
}
}
//添加 (按序号添加)
public void addByOrder(HeroNode2 heroNode){
HeroNode2 temp = heroNode2.next;
while (true){
//按着这个找
if (heroNode.no>temp.no&&heroNode.no<temp.next.no)
break;
else {
if (temp.next==null){
break;
}
temp=temp.next;
}
}
//找到这个节点的前一个节点了
//执行添加
heroNode.next=temp.next;
temp.next.pre=heroNode;
heroNode.pre=temp;
temp.next=heroNode;
}
//添加 (默认添加到结尾)
public void add(HeroNode2 heroNode){
//思路:1.当不考虑编号顺序时
//2.将最后这个节点的next,指向新的结点
//因为head结点不能动,所以需要一个辅助遍历 temp
HeroNode2 temp = heroNode2;
//遍历链表,找到最后
while (true){
//找到链表的最后
if (temp.next==null){
break;
}
//没有找到链表的最后
temp=temp.next;
}
//当退出while循环时,temp就指向了链表的最后
//将最后这个节点的next 指向新的节点
temp.next =heroNode;
heroNode.pre = temp;
}
//修改一个双向链表一个节点的内容。
public void update(HeroNode2 newHeroNode){
if (heroNode2.next==null){
System.out.println("链表为空");
return;
}
//找到需要修改的节点
//先定义一个辅助变量
HeroNode2 temp = heroNode2.next;
boolean flag = false;
while (true){
if (temp==null){
break;//到了链表的最后
}
if (temp.no==newHeroNode.no) {//找到了
flag =true;
break;
}
temp=temp.next;
}
//根据flag 判断是否找到要修改的节点
if (flag){
temp.name= newHeroNode.name;
temp.nickname= newHeroNode.nickname;
}
else {
//没有找到
System.out.printf("没有找到编号%d的节点,不能修改\n",newHeroNode.no);
}
}
//从双向链表中删除一个节点
public void del(int no){
if(heroNode2.next ==null){
System.out.println("链表为空,无法删除");
return;
}
HeroNode2 temp =heroNode2.next;
boolean flag = false;//标志是否找到删除节点
while (true){
if (temp==null){//没有找到
break;
}
if (temp.no==no){
//找到了
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.printf("要删除的%d节点,不存在",temp.no);
}
}
}
class HeroNode2{
public int no;
public String name;
public String nickname;
public HeroNode2 next;
public HeroNode2 pre;
@Override
public String toString() {
return "HeroNode2{" +
"no=" + no +
", name='" + name + '\'' +
", nickname='" + nickname + '\'' +
'}';
}
public HeroNode2(int no, String name, String nickname) {
this.no = no;
this.name = name;
this.nickname = nickname;
}
}