数据结构学习-双向链表的实现

数据结构学习-双向链表的实现

双向链表的实现

需求

创建一个带头节点的双向链表,用来存储英雄的信息(排名编号、姓名、昵称),并可以实现增删改查的操作

分析及实现

分析

  1. 与单向链表不同的是,单向蓝标查找的方向只能是一个方向,而双向链表可以向前或向后查找。
  2. 单向链表不能进行自我删除,需要依靠辅助节点,找到待删除节点的下一个节点。而双向链表可以进行自我删除。

实现

  1. 首先创建一个HeroNode类,里面包含两个部分data:no,name,nickName)以及next节点和pre节点
/**
* 定义一个英雄类
* 每个HeroNode就是一个节点
*/
class HeroNode2{
   public int no;// 英雄排名
   public String name;// 英雄名
   public String nickName;// 昵称
   HeroNode2 next;// next节点
   HeroNode2 pre; // 指向前一个节点

   public HeroNode2(int no, String name, String nickName){
       this.no = no;
       this.name = name;
       this.nickName = nickName;
   }

   /**
    * 重写toString方法
    * @return
    */
   @Override
   public String toString() {
       return "HeroNode{" +
               "no=" + no +
               ", name='" + name + '\'' +
               ", nickName='" + nickName + '\'' +
               '}';
   }

}
  1. 添加
    方式一:添加节点到最后
    在这里插入图片描述
    public void addHero(HeroNode2 newHeroNode){
        HeroNode2 temp = head;// 辅助变量
        while(temp.next != null){
            temp = temp.next;
        }
        // 循环结束时,temp已经到达链表最后
        temp.next = newHeroNode;
        newHeroNode.pre = temp;
    }

方式二:按照英雄的排名顺序添加
. 在这里插入图片描述

    /**
     * 按编号添加英雄
     */
    public void addHeroByOrder(HeroNode2 heroNode2){
        HeroNode2 temp = head;// 辅助变量
        boolean flag = false;// 标识是否添加的了相同编号的英雄
        while(true){
            if(temp.next == null){
                break;
            }else if(temp.next.no > heroNode2.no){
              break;
            }else if(temp.next.no == heroNode2.no){
                flag = true;
                break;
            }
            temp = temp.next;
        }

        // 当排名重复时  不允许添加
        if(flag){
            System.out.println("添加的" + heroNode2.no + "号的英雄已经存在,不能重复添加!");
        }

        heroNode2.next = temp.next;
        temp.next = heroNode2;
        temp.next.pre = heroNode2;
        heroNode2.pre = temp;
    }
  1. 修改
	/**
     * 修改双向链表
     * @param heroNode2
     */
    public void updateHero(HeroNode2 heroNode2){
        // 判断链表是否为空
        if(head.next == null){
            System.out.println("链表为空!");
        }
        HeroNode2 temp = head.next;
        boolean flag = false; // 用来标识是否找到了指定编号的英雄
        while(temp != null){
            if(temp.no == heroNode2.no){// 若找到了该编号的英雄直接退出循环
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if(flag){
            temp.name = heroNode2.name;
            temp.nickName = heroNode2.nickName;
        }else{// 为找到节点
            System.out.println("未找到编号为:" + heroNode2.no + "的英雄!");
        }
    }
  1. 删除
    在这里插入图片描述
    /**
     * 删除双向链表的节点
     * @param no
     */
    public void delHero(int no){
        // 判断链表为空
        if(head.next == null){
            System.out.println("链表为空!");
        }
        // 辅助变量
        HeroNode2 temp = head.next;
        boolean flag = false;
        while(temp != null){
            // 因为双向链表可以删除自身  所以直接使用temp.no = no
            // 而单向链表不能删除自身  所以需要找到待删除节点的下一个节点 temp.next.no = no
            if(temp.no == no){
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if(flag){
            // 找到了待删除的节点
            // 将temp的前一个节点指向temp的下一个节点
            temp.pre.next = temp.next;
            // 将temp的下一个节点指向temp的前一个节点
            // 但是这里可能会出现空指针异常
            // 如果删除的是最后一个节点那么 temp.next为空 temp.next.no就会出现空指针异常
            // 所以需要加一个判断
            if(temp.next != null){
                temp.next.pre = temp.pre;
            }
        }else{
            System.out.println("未找到编号为:" + no + "的英雄!");
        }
    }
  1. 遍历
	/**
     * 遍历双向链表和遍历单向链表相同
     */
    public void showList(){
        // 首先判断链表是否为空
        if(head.next == null){
            System.out.println("链表为空!");
            return ;
        }
        // 用一个临时节点来遍历链表
        HeroNode2 temp = head.next;
        while(true){
            if(temp == null){
                break;
            }
            System.out.println(temp.toString());
            temp = temp.next;
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值