单向链表的增删改查

本文详细介绍了单链表的逻辑结构,包括节点属性、添加元素的顺序与排序方法、删除与修改节点操作,以及展示了Java代码实现。通过实例演示了如何使用add(), addByOrder(), delete(), update()和display()方法操作链表。
摘要由CSDN通过智能技术生成

单链表介绍

链表的真实结构

单链表在内存中的结构

结构分析

从结构图中可以分析出

  1. 链表是以节点的方式来存储值
  2. 每一个节点包含了值和next节点
  3. 链表的各个节点不一定是连续存储的
  4. 链表分为带头节点的链表和不带头节点的链表

链表的逻辑结构

单链表的逻辑结构

单链表的代码实现

分析节点属性

  1. 数据属性(如姓名,大招技能等)
  2. 下一节点next(故其属性是一个节点!)
 class Node {
    public int no;
    public String name;
    public String big;
    //注意node节点中next的属性!!!!
    public Node next;

    public Node(int no, String name, String big) {
        this.no = no;
        this.name = name;
        this.big = big;
    }

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

添加元素的方法add()(顺序添加,只能插在链表的尾部)

  1. 通过死循环来遍历,要找一个临时的指针temp,来遍历整个链表,因为要找到最后一个节点,进行插值。
  2. 如果找到最后一个节点位置,则直接进行跳出循环进行插值
  3. 如果没有找到最后一个节点,则在循环中进行指针指向下一个节点的操作
 //添加节点的方法,采用顺序插入法,将新的节点插到最后一个位置,故肯定是要遍历出最后一个节点,来存放这个数据
    public void add(Node node) {
        //由于头节点不能动,故要设置一个临时节点来遍历,从而找到最后一个节点
        Node temp = head;
        //通过死循环找出最后一个节点
        while (true) {
            if (temp.next == null) {
                break;
            }
            //如果不是最后一个节点,就找下一个
            temp = temp.next;
        }
        //找到最后一个节点之后,将新的插入节点赋值到最后一个节点上
        temp.next = node;
    }

添加元素的方法addByOrder()(可以判断no的值来排序)

排序插入的图解
通过以上图,当新的节点值为4时,通过temp指针判断要插入的位置。因为要按照顺序插入,需要两步:

  1. node.next=temp.next
  2. temp.next=node
 //通过顺序加入
    public void addByOrder(Node node) {
        //还是要引入辅助变量
        Node temp = head;
        //此标记用来判断所添加的元素是否已经存在
        boolean flag = false;
        //遍历整个链表
        while (true) {
            if (temp.next == null) {
                break;
            }
            //找到要插入节点的位置
            if (temp.next.no > node.no) {
                break;
            } else if (temp.next.no == node.no) {
                flag = true;
                break;
            }
            temp = temp.next;
        }

        if (flag) {
            System.out.println("准备插入的人编号【" + node.no + "】已存在");
        } else {
            //若可以插入,则将新的节点插入
            node.next = temp.next;
            temp.next = node;
        }
    }

删除节点的方法delete()

删除节点的图解
如图,想要删除一个节点步骤:

  1. 首先确定要删除节点的前一个位置即temp。
  2. 找到位置之后,只需要让temp.next=temp.next.next就可以实现删除节点的操作。
  3. 没有引用的节点,会被垃圾回收机制回收掉。
public void delete(int no){
        Node temp=head;
        boolean flag=false;
        while (true){
            //说明是一个空的链表
            if(temp==null){
                break;
            }
            if(temp.next.no==no){
                //说明找到了
                flag=true;
                break;
            }
            temp=temp.next;
        }
        if(flag){
            temp.next=temp.next.next;
            System.out.println("编号为【"+no+"】的英雄删除成功!");
        }else {
            System.out.println("编号为【"+no+"】的英雄不存在!");
        }
    }

修改节点的方法update()

在这里插入图片描述

public void update(Node newNode){
        Node temp=head;
        //表示链表中是否存在该节点
        boolean flag=false;
        while(true){
            if(temp==null){
                break;
            }
            if(temp.no==newNode.no){
                flag=true;
                break;
            }
            temp=temp.next;
        }
        if(flag){
            temp.name=newNode.name;
            temp.big=newNode.big;
            System.out.println("修改成功!");
        }else {
            System.out.println("没有找到编号为["+newNode.no+"]的节点");
        }
    }

显示元素的方法display()

  1. 首先判断链表是否为空,若为空,可以直接返回
  2. 通过死循环来遍历整个链表进行输出,如果找到最后一个节点,则跳出死循环
    //显示链表中的节点,同是需要找一个;临时指针来遍历链表
    public void display() {
        //首先判断链表是否为空
        if (head.next == null) {
            return;
        }
        Node temp = head.next;
        //遍历每一个链表
        while (true) {
            //如果下一个节点为空,说明已经找到了最后一个节点,可以退出
            if (temp == null) {
                break;
            }
            System.out.println(temp);
            temp = temp.next;
        }
    }

代码测试

package com.njupt.List;

/**
 * Creat with IntelliJ IDEA
 *
 * @Auther:倔强的加瓦
 * @Date:2021/07/13/11:32
 * @Description:
 */
public class LinkedListDemo {
    public static void main(String[] args) {
        Node node1 = new Node(1, "花木兰", "推推");
        Node node2 = new Node(2, "张飞", "变大");
        Node node3 = new Node(3, "牛魔", "起飞");
        Node node4 = new Node(4, "鲁班", "等死");
        SingList singList = new SingList();
        System.out.println("使用有序插入:");
        singList.add(node1);
        singList.add(node2);
        singList.add(node4);
        singList.add(node3);
        singList.display();
        //测试修改英雄
        Node node5 = new Node(4, "鲁班", "起飞升天");
        singList.update(node5);
        singList.display();

        System.out.println("------删除-------");
        singList.delete(1);
        singList.display();
        System.out.println("------删除-------");

        SingList singList1 = new SingList();
        System.out.println("使用无序插入:");
        singList1.addByOrder(node1);
        singList1.addByOrder(node2);
        singList1.addByOrder(node4);
        singList1.addByOrder(node3);
        singList1.display();

    }
}

//2创建链表来管理对象
class SingList {
    //头节点不存放数据,并且不能动
    private Node head = new Node(0, "", "");

    //添加节点的方法,采用顺序插入法,将新的节点插到最后一个位置,故肯定是要遍历出最后一个节点,来存放这个数据
    public void add(Node node) {
        //由于头节点不能动,故要设置一个临时节点来遍历,从而找到最后一个节点
        Node temp = head;
        //通过死循环找出最后一个节点
        while (true) {
            if (temp.next == null) {
                break;
            }
            //如果不是最后一个节点,就找下一个
            temp = temp.next;
        }
        //找到最后一个节点之后,将新的插入节点赋值到最后一个节点上
        temp.next = node;
    }

    //通过顺序加入
    public void addByOrder(Node node) {
        //还是要引入辅助变量
        Node temp = head;
        //此标记用来判断所添加的元素是否已经存在
        boolean flag = false;
        //遍历整个链表
        while (true) {
            if (temp.next == null) {
                break;
            }
            if (temp.next.no > node.no) {
                break;
            } else if (temp.next.no == node.no) {
                flag = true;
                break;
            }
            temp = temp.next;
        }

        if (flag) {
            System.out.println("准备插入的人编号【" + node.no + "】已存在");
        } else {
            //若可以插入,则将新的节点插入
            node.next = temp.next;
            temp.next = node;
        }
    }
    //修改节点信息的方法
    public void update(Node newNode){
        Node temp=head;
        //表示链表中是否存在该节点
        boolean flag=false;
        while(true){
            if(temp==null){
                break;
            }
            if(temp.no==newNode.no){
                flag=true;
                break;
            }
            temp=temp.next;
        }
        if(flag){
            temp.name=newNode.name;
            temp.big=newNode.big;
            System.out.println("修改成功!");
        }else {
            System.out.println("没有找到编号为["+newNode.no+"]的节点");
        }
    }

    public void delete(int no){
        Node temp=head;
        boolean flag=false;
        while (true){
            //说明是一个空的链表
            if(temp==null){
                break;
            }
            if(temp.next.no==no){
                //说明找到了
                flag=true;
                break;
            }
            temp=temp.next;
        }
        if(flag){
            temp.next=temp.next.next;
            System.out.println("编号为【"+no+"】的英雄删除成功!");
        }else {
            System.out.println("编号为【"+no+"】的英雄不存在!");
        }
    }

    //显示链表中的节点,同是需要找一个;临时指针来遍历链表
    public void display() {
        //首先判断链表是否为空
        if (head.next == null) {
            return;
        }
        Node temp = head.next;
        //遍历每一个链表
        while (true) {
            //如果下一个节点为空,说明已经找到了最后一个节点,可以退出
            if (temp == null) {
                break;
            }
            System.out.println(temp);
            temp = temp.next;
        }
    }
}

//1创建节点对象
class Node {
    public int no;
    public String name;
    public String big;
    public Node next;

    public Node(int no, String name, String big) {
        this.no = no;
        this.name = name;
        this.big = big;
    }

    @Override
    public String toString() {
        return "Node{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", big='" + big + '\'' +
                '}';
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值