Java教程

Java 单链表代码实现

本文主要是介绍Java 单链表代码实现,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

前言

用Java实现单链表的增删查改

参考视频

  1. 尚硅谷Java数据结构与java算法(Java数据结构与算法)

1、程序代码

详情介绍的话,可以看看原视频说的思路和代码分步写法。

package Java.nian_linked_list;

public class SingleLinkedListDemo {

    public static void main(String[] args) {

        // 测试
        // 先创建节点
        HeroNode hero1 = new HeroNode(1, "宋江", "及时雨");
        HeroNode hero2 = new HeroNode(2, "卢俊义", "玉麒麟");
        HeroNode hero3 = new HeroNode(3, "吴用", "智多星");
        HeroNode hero4 = new HeroNode(4, "林冲", "豹子头");

        // 创建要给的链表
        SingleLinkedList singleLinkedList = new SingleLinkedList();

        // 添加节点
        // singleLinkedList.add(hero1);
        // singleLinkedList.add(hero2);
        // singleLinkedList.add(hero3);
        // singleLinkedList.add(hero4);

        // 加入按照编号的顺序
        singleLinkedList.addByOrder(hero1);
        singleLinkedList.addByOrder(hero4);
        singleLinkedList.addByOrder(hero3);
        singleLinkedList.addByOrder(hero2);
          // 显示一下
        singleLinkedList.list();


        // 测试修改节点的代码
        HeroNode newHeroNode = new HeroNode(2, "小卢", "玉麒麟~~~");
        singleLinkedList.update(newHeroNode);

        System.out.println("修改后的链表情况~~~");

        // 显示一下
        singleLinkedList.list();

        //  删除一个节点
        singleLinkedList.del(1);
        singleLinkedList.del(4);
        System.out.println("删除后的链表情况~~~");
        // 显示一下
        singleLinkedList.list();
        
    }
    
}

// 定义SingleLinkedList 管理我们的英雄

class SingleLinkedList{
    // 先初始化一个头节点,头节点不要动,不存放任何具体的数据
    private HeroNode head = new HeroNode(0, "", "");

    // 添加节点到单向链表
    // 思路: 当不考虑编号顺序时
    /**
     * 1. 找到当前链表的最后节点
     * 2.将最后这个节点的next 指向新节点
     */
     public void add(HeroNode heroNode){
        //  因为head 节点不能动,所以需要添加一个辅助变量
        HeroNode tmp = head;
        // 遍历链表,找到最后
        while(true){
            // 找到链表最后
            if(tmp.next==null){
                break;
            }
            // 如果没有找到最后,将tmp 后移
            tmp = tmp.next;
        }
        //当退出while 循环时,tmp 就指向了链表的最后
        // 将最后这个节点的next 指向新的节点
        tmp.next = heroNode;
     }

     /**第二种方式在添加英雄时,根据排名将英雄插入到指定位置
      * 如果有这个排名,则添加失败,并给出提示
      */
      public void addByOrder(HeroNode heroNode){
        // 因为头节点不能动,需要通过一个辅助指针(变量)来帮助找到添加的位置
        //  单链表,找的tmp 是位于添加位置的前一个结点,否则插入不了
        HeroNode temp = head;
        boolean flag= false;  // flag 标志添加位置的编号是否存在,默认为false
        while(true){
            if(temp.next ==null ){ // 说明temp 已经在链表最后
                break;
            }
            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.printf("准备插入的英雄的编号%d 已经存在了,不能加入\n",heroNode.no);
        } else{
            // 插入到链表中,temp 后面
            heroNode.next= temp.next;
            temp.next = heroNode;
        }
      }

    // 修改节点信息,根据no编号来修改,即no 编号不能改
    /**
     * 说明
     * 1.根据newHeroNode 的 no 来修改即可
     */
    public void update(HeroNode newHeroNode){
        // 判断是否为空
        if (head.next == null){
            System.out.println("链表为空~");
            return ;
        }
        // 找到需要修改的节点,根据no 编号
        // 定义一个辅助变量
        HeroNode temp = head.next;
        boolean flag = false ; // 表示是否找到该节点
        while(true){
            if (temp == null ){
                break; // 已经遍历完链表
            }
            if(temp.no == newHeroNode.no){
                // 找到
                flag = true;
                break;
            }
            temp = temp.next;
        }

        // 根据flag 判断是否找到要修改的节点
        if(flag){
            temp.name = newHeroNode.name;
            temp.nickname = newHeroNode.nickname;
        } else { // 没有找到
            System.out.printf("没有找到 编号%d 的节点,不能修改\n",newHeroNode.no);
        }

    }

    // 删除节点
    /**
     * 思路:
     * 1、head不能动,需要一个辅助节点temp 找到待删除节点前一个节点
     * 2、说明我们在比较时,是temp.next.no 和需要删除的节点的no 比较
     */

     public void del(int no){
         HeroNode temp = head;
         boolean flag = false; // 标志是否找到待删除的节点
         while(true){
            if(temp.next ==null ){ // 说明temp 已经在链表最后
                break;
            }
           if(temp.next.no == no)
            {
                // 找到的待删除节点的前一个节点temp
                flag = true;
                break;
            }
            temp = temp.next;
         }
         if(flag){
            //   找到,可以删除
            temp.next= temp.next.next;
         }else{
             System.out.printf("要删除的%d 节点不存在\n", no);
         }
     }

     // 显示链表。遍历
     public void list(){
     // 判断链表是否为空
     if(head.next == null ){
         System.out.println("链表为空");
         return ;
     }
     // 因为头节点不能动,需要辅助变量
     HeroNode tmp = head.next;
     while(true){
         // 判断是否到链表最后
         if(tmp == null ){
             break;
         }
         // 输出节点信息
         System.out.println(tmp);
         // 将tmp 后移,小心,,
         tmp = tmp.next;
     }
     }
}



// 定义HeroNode,每个HeroNode 对象就是一个节点
class HeroNode{
    public int no;
    public String name;
    public String nickname;
    public HeroNode next;  // 指向下一个节点

    // 构造器
    public HeroNode(int no,String name, String nickname){
        this.no = no;
        this.name = name;
        this.nickname = nickname;
    }

    // 为了显示方便,我们重新toString
    @Override
    public String toString(){
        return "HeroNode [ no=" + no + ", name="+ name +",nickname="+nickname+"]";
    }
}

2. 结果展示

HeroNode [ no=1, name=宋江,nickname=及时雨]
HeroNode [ no=2, name=卢俊义,nickname=玉麒麟]
HeroNode [ no=3, name=吴用,nickname=智多星]
HeroNode [ no=4, name=林冲,nickname=豹子头]
修改后的链表情况~~~
HeroNode [ no=1, name=宋江,nickname=及时雨]
HeroNode [ no=2, name=小卢,nickname=玉麒麟~~~]
HeroNode [ no=3, name=吴用,nickname=智多星]
HeroNode [ no=4, name=林冲,nickname=豹子头]
删除后的链表情况~~~
HeroNode [ no=2, name=小卢,nickname=玉麒麟~~~]
HeroNode [ no=3, name=吴用,nickname=智多星]

3. 总结

  • 先建立节点类,比如说英雄类(节点)
  • 再建立单链表类
  • 测试类,进行增删改查操作

逻辑思路 容易理解,但实际代码量还是比较大的,理解起来也有点难度,建议多手打几遍,多用几下,慢慢理解就好。

这篇关于Java 单链表代码实现的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!