ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

单向链表+双向链表

2021-09-10 15:00:00  阅读:124  来源: 互联网

标签:temp no 单向 next 链表 flag 双向 节点


单项链表

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域data,另一个是存储下一个结点地址的指针域next。
链表可以是带头节点的,也可以不带头节点,具体看具体的需要。头节点一般默认的data不包含任何数据。

单链表的示意图

物理结构

在这里插入图片描述

逻辑结构

在这里插入图片描述

应用场景

在这里插入图片描述

节点的定义

属性定义:

  1. no(编号)
  2. name(名称)
  3. nickName(外号)
  4. next(下一个节点)
class HeroNode{
    public int no;
    public String name;
    public String nickName;
    public HeroNode next; // next域

    public HeroNode(int no,String name,String nickName){
        this.name = name;
        this.nickName = nickName;
        this.no = no;
        this.next = null;
    }

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nickName='" + nickName + '\'' +
                '}';
    }
}

思路

1:实现第一种添加方法

  1. 首先要先定义一个头节点
  2. 将新的节点添加到链表中最后一个节点的next指向中
  3. 如何找到当前链表中的最后一个节点?
  4. 因为链表中的节点,我们是全部都不能随意变动的,所以我们可以使用一个辅助节点temp,使用temp来不断接受链表的节点遍历,在遍历时依次查看temp的next是否为null,如果为null,则表示这是最后一个节点。

具体的代码实现

 public void add(HeroNode heroNode){
        // 添加的时候要想办法找到链表的尾节点,让尾节点的next指向heroNode
        // 因为head节点不能动,因此我们需要一个辅助节点temp
        HeroNode temp = head;
        // 遍历链表,找到最后
        while(true){
            // 找到了最后一个节点
            if(temp.next == null){
                break;
            }
            // 如果不是最后一个节点
            temp = temp.next;
        }
        temp.next = heroNode;
    }

2: 实现第二种添加方法

  1. 首先,添加需要考虑到No的问题,所以我们在temp接受遍历的节点的是时候,需要考虑到temp和temp.next这两个节点的No是否包含了添加节点的No。有以下三种情况,如下表述。
  2. 遍历到最后,temp.next为空的情况下,temp.No小于节点的No,即节点添加到链表的尾部
  3. 节点的No处于temp.No和temp.next.No之间
  4. temp.No等于节点的No
  5. 同时因为需要考虑到No已经存在的问题,我们定义一个布尔变量flag(是否重复),默认为false,当处于4的情况时,修改flag为true。为了方便在后须修改的时候,可以判断flag的值来判断是否存在重复

代码实现

public void addByNo(HeroNode heroNode){
        // 辅助节点
        HeroNode temp = head;
        // 表示添加的编号是否存在, 默认为false
        boolean flag = false;
        while(true){
            // temp已经在链表的最后了
            if(temp.next == null){
                break;
            }
            // 即节点添加到temp和temp.next之间
            if(temp.next.no > heroNode.no){
                break;
            }
            else if(temp.next.no == heroNode.no){ //heroNode的编号已经存在了
                flag = true;
                break;
            }
            temp = temp.next;
        }
        // 判断flag的值
        if(flag){
            // 编号已存在
            System.out.println("待插入的英雄的编号已经存在了,不能加入");
        }else {
            // 插入
            heroNode.next = temp.next;
            temp.next = heroNode;
        }
    }

3:实现遍历链表

  1. 判断链表是否为空,即head.next==null?
  2. 判断是否已经遍历到最后一个节点,temp.next==?

代码实现

public void list(){
        // 先判断链表是否为空
        if(head.next == null){
            System.out.println("链表为空");
            return;
        }
        // 因为头节点不能动,我们需要一个辅助遍历来遍历
        HeroNode temp = head.next;
        //开始遍历
        while(true){
            // 先判断是否到链表的最后
            if(temp == null){
                System.out.println("到末尾了");
                break;
            }
            // 输出节点的信息
            System.out.println(temp);
            temp = temp.next;
        }
    }

4:实现修改节点

  1. 定义一个赋值节点temp
  2. 定义一个布尔变量flag来判断是否找到该节点
  3. 我们在遍历链表的时候,只要判断temp.No == 新节点.No?如果相等,则修改flag=true。
  4. 同时还需要判断temp是否到末尾

代码实现

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.nickName = newHeroNode.nickName;
            temp.name = newHeroNode.name;
        }else {
            System.out.println("没有匹配的节点信息");
        }
    }

5:节点的删除

  1. temp来接受链表遍历的节点信息
  2. 判断temp.next.no == 节点.no? 如果true,temp.next = temp.next.next。在这里必须判断temp.next.no和节点.no是否相同。因为如是等到temp.no和节点.no相同的时候,无法做到删除的效果。在删除时,是需要相同节点的前一个节点.next --> 相同节点的后一个节点

代码实现

 public void delete(int no){
        HeroNode temp = head;
        // 是否找到待删除节点
        boolean flag = false;
        while (true){
            if (temp.next == null){
                break;
            }
            if (temp.next.no == no){
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if (flag){
            temp.next = temp.next.next;
        }else {
            System.out.println("找不到节点信息");
        }
    }

标签:temp,no,单向,next,链表,flag,双向,节点
来源: https://blog.csdn.net/weixin_45690465/article/details/120218732

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有