在学习单向链表的时候,使用带head头的双向链表实现-水浒英雄排行榜管理单项向链表的缺点分析:
[1]单向链表,查找的方向只能是一个方向,而双向链表可以向前或者向后查找。
[2]单向链表不能自我删除,需要靠辅助节点,而双向链表,则可以自我删除,所以前面单链表删除节点时,总是找到temp,temp是代删除节点的前一个节点。
分析 双向链表的遍历,添加,修改,删除的操作思路==》代码实现
[1]遍历方式和单链表一样,只是可以向前,也可以向后
[2]添加(默认添加到双向链表的最后这个节点)
(1)先找到双向链表的最后这个节点
(2)temp.next=newHeroNode(使最后这个节点直接指向新的节点)
(3)newHeroNode.pre=temp(使新添加进来的节点的pre指向上一个节点)
[3]修改思路和原理和单向链表一样
[4]删除
(1)因为是双向链表,因此,可以自我删除某个节点,而不需要想单链表一样找到前一个节点才能删除
(2)直接找到要删除的节点,比如temp
(3)temp.pre.next=temp.next(要删除节点的上一个节点指向的下一个节点为要删除节点的下一个节点)
(4)temp.next.pre=temp.pre(要删除节点的下一个节点指向的上一个节点为要删除节点的上一个节点)
双向链表的代码实现
创建节点类HeroNode
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class HeroNode { public int no; public String nickname; public String name; public HeroNode next; public HeroNode pre; public HeroNode(int no, String name, String nickname) { this.no = no; this.name = name; this.nickname = nickname; } @Override public String toString() { return "HeroNode [no=" + no + ", nickname=" + nickname + ", name=" + name + ", next=" + next + ", pre=" + pre + "]"; } }
|
创建一个双向链表的类DoubleLinkedList
1 2 3 4 5 6 7 8 9
| class DoubleLinkedList { private HeroNode head = new HeroNode(0,"",""); public HeroNode getHead(){ return head; } }
|
双向链表的遍历
双向链表的遍历,和单向链表一样。(在双向链表的类DoubleLinkedList中添加方法list()来显示双向链表)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public void list(){ if(head.next==null){ System.out.println("链表为空"); return; } HeroNode temp = head.next; while(true){ if(temp == null)break; System.out.println(temp); temp = temp.next; } }
|
双向链表添加节点
思路:
(1)先找到双向链表的最后这个节点
(2)temp.next=newHeroNode(使最后这个节点直接指向新的节点)
(3)newHeroNode.pre=temp(使新添加进来的节点的pre指向上一个节点)
代码实现(在双向链表的类DoubleLinkedList中添加方法add()来向双向链表添加节点):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public void add(HeroNode heroNode){ HeroNode temp = head; while(true){ if(temp.next==null) break; temp = temp.next; } temp.next = heroNode; heroNode.pre = temp; }
|
双向链表的修改
双向链表的节点内容修改,可单向链表的节点内容修改一样,在双向链表的类DoubleLinkedList中添加方法update()来修改双向链表节点内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public void update(HeroNode newHeroNode){ if(head.next==null){ System.out.println("链表为空");return; } HeroNode temp = head.next; boolean flag = false; while(true){ if(temp == null)break; if(temp.no == newHeroNode.no){ flag = true; break; } temp = temp.next; } if(flag){ temp.name = newHeroNode.name; temp.nickname = newHeroNode.nickname; }else{ System.out.printf("没有找到编号%d的节点,不能修改",newHeroNode.no); } }
|
双向链表的节点删除
思路:
(1)因为是双向链表,因此,可以自我删除某个节点,而不需要想单链表一样找到前一个节点才能删除
(2)直接找到要删除的节点,比如temp
(3)temp.pre.next=temp.next(要删除节点的上一个节点指向的下一个节点为要删除节点的下一个节点)
(4)temp.next.pre=temp.pre(要删除节点的下一个节点指向的上一个节点为要删除节点的上一个节点)
代码实现(在双向链表的类DoubleLinkedList中添加方法del()来表示删除双向链表中的某个节点):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
public void del(int no){ if(head.next==null) { System.out.println("链表为空~!无法删除");return; } HeroNode temp = head.next; boolean flag = false; while(true){ if(temp == null)break; if(temp.no == no){ 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,不存在",no); } }
|