• 单链表的模拟实现


    单链表的应用实现

    在这里插入图片描述

    在这里插入图片描述

    顺序添加根据排名 若是排名号有了就显示添加失败
    思路:1.head是头结点不能移动 所以要用一个临时节点 temp
    2.找到要插入位置的前一个节点 用temp遍历
    找到temp.next.no首次大于heroNode.no 的位置此时就在temp位置插入
    让heroNode.next=temp.next ;temp=HeroNode
    在这里插入图片描述删除链表节点
    思路: head不能动 temp 向后遍历找到那个要删除的排名号的下一个节点的位置

    在这里插入图片描述
    删除链表节点
    思路: head不能动 temp 向后遍历找到那个要删除的排名号的下一个节点的位置

    涉及的方法

    1.默认添加节点数据 t
    2.顺序添加节点数据
    3.删除节点
    4.修改节点数据
    5.判断是否为空
    6.获取节点
    7.获取链表长度
    8.显示链表所有数据
    9.插入数据
    10.根据位置返回
    11.退出程序

    代码

    package 链表;
    
    
    import java.util.Scanner;
    
    /**
     * @author 一介草莽子
     * version 1.0
     */
    @SuppressWarnings({"all"})
    public class SingleLinkedListDemo {
        public static void main(String[] args) {
    
            SingleLinkedList singleLinkedList_ = new SingleLinkedList();
            //菜单
            boolean loop = true;
            Scanner scanner = new Scanner(System.in);
            int no = 0;//输入的排名号
            String name = null;//输入的名字
            String nickName = null;//输入的绰号
            //功能号
            int num = 0;
    
            while (loop) {
                System.out.println("============ 1.默认添加节点数据 ===========");
                System.out.println("============ 2.顺序添加节点数据 ===========");
                System.out.println("============ 3.删除节点        ============");
                System.out.println("============ 4.修改节点数据    ============");
                System.out.println("============ 5.判断是否为空    ============");
                System.out.println("============ 6.获取节点       ============");
                System.out.println("============ 7.获取链表长度    ============");
                System.out.println("============ 8.显示链表所有数据 ============");
                System.out.println("============ 9.插入数据 ============");
                System.out.println("============ 10.根据位置返回 ============");
    
                System.out.println("============ 11.退出程序        ============\n");
    
                System.out.print("请输入功能号:");
                num = scanner.nextInt();
                switch (num) {
                    case 1://普通添加
                        System.out.println("【普通添加】 请输入 排名号,名字,绰号 ");
                        no = scanner.nextInt();
                        name = scanner.next();
                        nickName = scanner.next();
                        singleLinkedList_.add(new HeroNode(no, name, nickName));
                        break;
                    case 2://顺序添加
                        System.out.println("【顺序添加】 请输入 排名号,名字,绰号 ");
                        no = scanner.nextInt();//输入的排名号
                        name = scanner.next();//输入的名字
                        nickName = scanner.next();//输入的绰号
                        singleLinkedList_.addIndex(new HeroNode(no, name, nickName));
                        break;
                    case 3://删除
                        System.out.println("请输入要删的排名号~");
                        no = scanner.nextInt();
                        singleLinkedList_.remove(no);
                        break;
                    case 4://修改
                        System.out.println("请输入修改的 排名号,名字,绰号 ");
                        no = scanner.nextInt();//输入的排名号
                        name = scanner.next();//输入的名字
                        nickName = scanner.next();//输入的绰号
                        singleLinkedList_.modify(new HeroNode(no, name, nickName));
                        break;
                    case 5://判断是否为空 若是空会抛出异常
                        singleLinkedList_.IsEmpty(singleLinkedList_.head.next);
                        System.out.println("链表不为空...");
                        break;
                    case 6://获取节点
                        System.out.print("请输入排名号");
                        no = scanner.nextInt();
                        HeroNode heroNode = singleLinkedList_.GetHeroNode(no);
                        System.out.println("获取到的节点是: " + heroNode.toString());
                        break;
                    case 7://.获取链表长度
                        System.out.println("链表长度为: " + singleLinkedList_.GetListLength());
                        break;
                    case 8://显示链表所有数据
                        singleLinkedList_.List();
                        break;
                    case 9:
                        System.out.println("请输入插入的 排名号,名字,绰号 ");
                        no = scanner.nextInt();//输入的排名号
                        name = scanner.next();//输入的名字
                        nickName = scanner.next();//输入的绰号
                       singleLinkedList_.Insert(new HeroNode(no,name,nickName));
                        break;
                    case 10:
                        System.out.print("请输入号:");
                        int n = scanner.nextInt();
                        HeroNode res = singleLinkedList_.GegElem(n);
                        System.out.println(res);
    
                        break;
                    case 11:
                        loop = false;
                        break;
                    default:
                        break;
                }
            }
            System.out.println("程序结束...");
        }
    }
    
    class SingleLinkedList {
        //设置一个头结点 里面不存放值head 不能动
        HeroNode head = new HeroNode(0, "", "");
    
        //链表的长度
        private int length = 0;
    
    
        //插入--先找出要插入的位置的前一个位置
        public void Insert(HeroNode heroNode){
    
            HeroNode temp=head;//遍历去找合适的位置
            while(true){
                if(temp.next==null){
                    break;
                }
                if(temp.next.no> heroNode.no){
                    //找到了第一个大于heroNode.no的
                    break;
                }
                temp=temp.next;
            }
            //heroNode.next指向后一个元素 前面的元素指向heroNode.next
            heroNode.next=temp.next;
            temp.next=heroNode;
            System.out.println("插入成功");
            length++;
        }
        //添加节点到单链表  -- 不考虑添加的顺序 直接添加到最后面
        public void add(HeroNode heroNode) {
            //head是不能动的 让临时变量 tmp来指向head
            HeroNode tmp = head;
    
            //循环遍历到最后找到指向null的那个那个对象
            while (true) {
                if (tmp.next == null) {
                    break;//tmp.next指向null 说明找到最后了
                }
                tmp = tmp.next;
            }
            //把node节点添加到最后
            tmp.next = heroNode;
            length++;
            System.out.println("添加成功...");
        }
    
    
        /**
         * 顺序添加根据排名 若是排名号有了就显示添加失败
         * 思路:1.head是头结点不能移动 所以要用一个临时节点 temp
         * 2.找到要插入位置的前一个节点 用temp遍历
         * 找到temp.next.no首次大于heroNode.no 的位置此时就在temp位置插入
         * 让heroNode.next=temp.next ;temp=HeroNode
         */
        public void addIndex(HeroNode heroNode) {
            HeroNode temp = head;
            boolean flag = false;//标记要是排名号有相同的就true 不能添加
            while (true) {
                if (temp.next == null) {
                    break;//空链表退出
                }
                //temp.no 是不对的 一开始 head是空节点
                if (temp.next.no == heroNode.no) {
                    flag = true;//标记要是排名号有相同的就true 不能添加
                    break;
                } else if (temp.next.no > heroNode.no) {
                    //找到temp.next.no首次大于heroNode.no 的位置
                    //此时就在temp位置插入 让heroNode.next=temp.next ;temp=HeroNode
                    break;
                }
                //遍历
                temp = temp.next;
            }
            if (flag) {
                System.out.println("排名号已存在不能在添加...");
    
            } else {
                heroNode.next = temp.next;
                //temp = heroNode这样是不对的 temp.next 相当于头指针的next域指向下一个节点
                temp.next = heroNode;
                length++;
                System.out.println("添加成功...");
            }
        }
    
        /**
         * 删除链表节点
         * 思路: head不能动   temp 向后遍历找到那个要删除的排名号的下一个节点的位置
         */
        public void remove(int no) {
            //判断链表是否为空
            IsEmpty(head.next);
            HeroNode temp = head;
            //设置标记 找到了就flag=true;可删除
            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是head  temp.next就是代表第一个节点 所以就应该让temp.next 也就是head里的
                //next域指向第二个节点 temp.next.next  temp.next.next等价于 head.next.next
                temp.next = temp.next.next;
                length--;
                System.out.println("删除成功...");
    
            } else {
                System.out.println(no + "排名号不存在");
            }
    
        }
    
    
        /**
         * 修改链表元素内容
         * head是不能动的 让temp动 找到到要修改的节点 改变 name nickname  no不能改变
         */
        public void modify(HeroNode newHeroNode) {
            //判断列表是不是空
            IsEmpty(head.next);
            //临时节点
            HeroNode temp = head;
            //找的了就=true
            boolean flag = false;
            while (true) {
                if (temp.next == null) {
                    break;//遍历到最后也没找到就退出
                }
                if (temp.next.no == newHeroNode.no) {
                    flag = true;
                    break;//找到到了编号 退出
                }
    
                //向后遍历
                temp = temp.next;
            }
            if (flag) {
                temp.next.name = newHeroNode.name;
                temp.next.nickname = newHeroNode.nickname;
                System.out.println("修改成功...");
            } else {
                System.out.println("没有找到" + newHeroNode.no + "号位置的元素");
            }
    
        }
    
        //返回链表的长度
        public int GetListLength() {
            return length;
        }
    
        //判断是否为空链表
        public void IsEmpty(HeroNode heroNode) {
            if (heroNode == null) {
                throw new RuntimeException("空链表....");
            }
        }
    
    
        /**
         * 获取元素 --查 根据排名号
         * head不能动 用temp来遍历查找
         */
        public HeroNode GetHeroNode(int no) {
            //判断是不是空表
            IsEmpty(head.next);
            HeroNode temp = head;
            while (true) {
                if (temp.next == null) {
                    System.out.println("没找到。。。");
                    return null;
                }//找到了返回节点
                if (temp.next.no == no) {
                    return temp.next;
                }
                temp = temp.next;
            }
        }
    
        //按位置查找
        public HeroNode GegElem(int n){
            IsEmpty(head.next);
            HeroNode temp=head;
            boolean flag=true;
            for (int i = 0; i < n; i++) {
                if(temp.next==null){
                    flag=false;
                    break;
                }
                temp=temp.next;
            }
            if(flag){
                //返回找到的数据 不是temp.next 因为在循环的时候指向了下一个
                return temp;
            }
            else{
                return null;
            }
        }
    
        //显示链表
        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.toString());
    
                tmp = tmp.next;
            }
        }
    
    }
    
    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 + '\'' +
                    '}';
        }
    }
    
  • 相关阅读:
    [Linux](16)网络编程:网络概述,网络基本原理,套接字,UDP,TCP,并发服务器编程,守护(精灵)进程
    Nginx之带宽限制解读
    【极客时间-系列教程】Vim 实用技巧必知必会
    ZHOJ_#20952. 最大公约数_数论
    Unity中的两种ScriptingBackend
    超详细的springBoot学习笔记
    【周赛复盘】力扣第 86 场双周赛
    表面清洁工艺对硅片与晶圆键合的影响
    激光雕刻机的雕刻操作
    FPGA杂记
  • 原文地址:https://blog.csdn.net/m0_56398287/article/details/127114285