好,那我们接下来说一下双向链表和节点创建:
节点的创建:双向链表节点的创建和单链表的节点创建大同小异,只是在声明变量时双向链表多了一个向头指针pre,其余部分组成与单链表相同。
----代码实现----
//创建节点类 class HeroNode2{ //定义各种变量 //编号 public int no; //姓名 public String name; //昵称 public String nickName; //声明下一个节点next public HeroNode2 next; //声明上一个节点pre public HeroNode2 pre; public HeroNode2(int no, String name, String nickName){ this.no = no; this.name = name; this.nickName = nickName; } //重写toString方法 public String toString() { return " HeroNode[no="+no+",name="+name+",nickeName="+nickName+"]"; } }
双向链表的创建:
双向链表的创建和单向链表的创建相同,直接套用代码即可。
----代码实现----
//创建双向链表 class DoubleLinkedList{ //声明头节点 private final HeroNode2 head = new HeroNode2(0,"",""); //---添加元素代码部分--- //显示链表 public void showList() { if (head.next == null) { System.out.println("链表为空,没有元素"); }else { HeroNode2 temp = head.next; while(true) { if (temp == null) { break; }else { System.out.println(temp); //temp后移,进行遍历 temp = temp.next; } } } } }
双向链表元素的添加(尾插法):
还是和单向链表的整体代码不分上下,其中要注意的一部分是双向链表的尾插操作为:
1.
向尾方向--使temp的下一个元素指针指向新元素HeroNode2.
向头方向--将HeroNode的向头指针pre指向temp节点其余部分代码相同:
动画演示一下:
----代码实现----
//向链表中添加元素-不考虑顺序 public void add(HeroNode2 HeroNode) { //声明辅助节点temp用于遍历链表 HeroNode2 temp = head; //遍历链表 while(true) { //到达链表结尾 if ( temp.next == null) { break; } temp = temp.next; } //元素添加操作 /* * 1.使temp的下一个元素指针指向新元素HeroNode--向尾方向 * 2.将HeroNode的向头指针指向temp节点--向头方向 */ temp.next = HeroNode; HeroNode.pre = temp; }
双向链表元素的添加(插入法):我怂了,我要是在说和单链表代码差不多,我估计你们打死我的心都有了,这个不同!这个不同!
(但好像也是差不多相同,不赖我):其实仔细想想吧,既然双向链表是单链表的延伸,核心代码就应该和单链表的相差不了多少,这肯定是事实,就比如生物学上的遗传,真不是我不好好和你们分享,她是真的一样我是真的没辙,哈哈,幸亏我准备了视频,要不然啊,
I will not know how I died~~
插入操作和上面一样:
1.
向尾方向--使temp的下一个元素指针指向新元素HeroNode2.
向头方向--将HeroNode的向头指针pre指向temp节点
视频演示:
----代码实现----
//向链表中添加元素-考虑顺序 public void add1(HeroNode2 HeroNode) { //声明辅助节点temp遍历双向链表 HeroNode2 temp = head; //声明元素存在标志flag,默认不存在false boolean flag = false; //遍历双向链表 while(true) { //已经到达链表结尾 if (temp.next == null) { break; //找到添加的位置 }else if(temp.no>HeroNode.no) { break; //要添加的元素已经存在或冲突 }else if(temp.no == HeroNode.no) { flag = true; break; } //temp后移遍历 temp = temp.next; } if(flag) { System.out.println("要添加的元素已经存在为"+temp.no+"号,添加失败"); }else { //元素添加操作 temp.next= HeroNode; HeroNode.pre = temp; } }
双链表元素的删除操作: 双链表的删除操作,相对于单链表的删除来说简单一些,因为双链表有直接前驱和直接后继,所以说不用找到其他元素, 直接来说就是,你想删除哪个元素,直接定位到这个元素删除就可以了, 我们下面依然用temp遍历的方法找到要删除的元素位置,然后进行删除操作就可以了。 双链表的删除操作如下: 1.temp指针定位到要删除的元素位置; 2.将temp.pre.next=temp.next; 即temp前一个元素的向尾指针指向 temp的下一个元素;--向尾方向 3. temp.next.pre=temp.pre; 将temp后一个元素的向头指针指向temp的上一个元素;--向头方向 特别注意:temp.next.pre = temp.pre语句可能出现空指针异常,即如果被删除的元素是链表的最后一个元素,temp.next会出现空指针异常问题,继而temp.next.pre是空指针现象,所以我们要在代码中解决这个问题,我们采用的解决方法是如果被删除的元素是最后一个元素,就不用再执行词条语句的操作方法。可以参考此章代码!
视频演示:
----代码实现----
//删除链表元素 public void delete(int no) { //声明判断标志flag,判断标志是否存在,默认不存在false boolean flag = false; HeroNode2 temp = head.next; while(true) { //到达链表结尾 if (temp == null) { break; } if(temp.no == no) { //判断标志置true 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.println("编号不存在,删除失败"); }
以下为测试类部分:
public class DoubleLinkedListDemo { public static void main(String[] args) { // TODO Auto-generated method stub //创建元素对象 HeroNode2 hero1 = new HeroNode2(1,"张三","小三"); HeroNode2 hero3 = new HeroNode2(3,"赵五","小五"); HeroNode2 hero2 = new HeroNode2(2,"李四","小四"); //实例化双向链表对象 DoubleLinkedList d = new DoubleLinkedList(); //增加链表元素 d.add1(hero1); d.add1(hero2); d.add1(hero3); //显示双向链表 System.out.println("删除前链表为:"); d.showList(); //删除指定编号的链表元素 d.delete(3); System.out.println("删除后链表为:"); d.showList(); } }
看似挺敷衍的一期,只为能在分享中提高自己,如果上述文章中有错误或者不太详细的地方,可以联系作者,和作者一起学习交流。互利共赢!那废话不多说,感觉文章写的好的话,可以分享、在看或赞赏,感谢大家支持!我们下期再见!