单向链表和双向链表区别_数据结构双向链表的增加删除操作

好久不见大家,由于上周学校教学安排原因,公众号停更了一段时间,让大家久等了,今天我要和大家分享的是数据结构中链表的另一种表现形式—— 双向链表。 十几天前,我和大家分享了数据结构中的单向链表的增删改查知识,今天要介绍的双向链表的知识和单向链表的知识大同小异,双向链表就相当于单向链表的延伸,没有看过单向链表的童鞋可以看一下前几期单向链表的文章,双向链表的知识相对于掌握了单向链表知识的同学更容易掌握哦! 双向链表与单向链表的区别是: 双向链表有两个指针为 向尾指针next 和 向头指针pre ,而单链表只有一个向尾指针next,双向链表的操作更为容易。 听完上面所说,我想大家也应该大致清楚了双向链表的组成了。 双向链表的组成: 元素及属性、向尾指针、向头指针。 如图所示:

97e3c01a7d1d679783e8827498ae9549.png

好,那我们接下来说一下双向链表和节点创建: 节点的创建:双向链表节点的创建和单链表的节点创建大同小异,只是在声明变量时双向链表多了一个向头指针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();      }  }
看似挺敷衍的一期,只为能在分享中提高自己,如果上述文章中有错误或者不太详细的地方,可以联系作者,和作者一起学习交流。互利共赢!那废话不多说,感觉文章写的好的话,可以分享、在看或赞赏,感谢大家支持!我们下期再见!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值