Java实现单向链表的模拟

简介

需求:用单链表存储部分梁山好汉信息

可实现: 1.显示链表全部内容 2.增 3.删 4.改 5.查 6.链表长度 7.逆序输出(原链表无损)

代码

//模拟单链表,并进行增删改查等操作
public class SingleLinkedList {
    //初始化头节点,头节点为空
    heroNode head = new heroNode(0,"","");
​
    //添加,方法一:按添加顺序依次写入数链表
    public void add(heroNode hero) {
        heroNode temp = head;
        //判断是否到末尾
        while(true) {
            if(temp.getNext() == null) {//temp.next即指针的位置
                break;
            } temp = temp.getNext();
        }
        temp.setNext(hero);
    }
    //添加,方法二:按排名写入链表
    public void addByOrder(heroNode hero) {
        heroNode temp = head;
        boolean flag = false;
        //遍历当前链表,并判断
        //1.链表为空2.编号存在3.存在比当前节点编号更大的节点4.前面节点全是比当前小的
        while(true) {
            if(temp.getNext() == null) {//空
                break;
            }
            if(temp.getNext().getNo() == hero.getNo()) {//编号相同
                flag = true;
                break;
            }
            if(temp.getNext().getNo() > hero.getNo()) {//找到位置
                break;
            }
            temp = temp.getNext();
        }
        //1和3都可以直接添加;2报错;4继续迭代
        if(flag) {
            System.out.println("该节点已存在");
        }else {//赋值并首尾连接
            //注意顺序!!!先设置尾指针再设置头指针
            hero.setNext(temp.getNext());
            temp.setNext(hero);
        }
    }
​
    //显示链表
    public void list() {
        if(head.getNext() == null) {
            System.out.println("链表为空");
            return;
        }
        //while遍历,通过之前定义的head对象作为头指针
        heroNode temp = head.getNext();
        while(temp != null) {
            System.out.println(temp);
            temp = temp.getNext();
        }
    }
​
    //修改
    public void update(int no, String name, String nickName) {
        heroNode temp = head;
        boolean flag = false;
        if(temp.getNext() == null) {
            System.out.println("链表为空,请先录入数据");
            return;
        }
        while(true) {
            if(temp.getNext() == null) {//注意顺序!!(空指针异常)
                break;
            }
            if(temp.getNext().getNo() == no) {//注意顺序!!(空指针异常)
                flag = true;
                break;
            }
            temp = temp.getNext();
        }
        if(flag) {
            temp.getNext().setName(name);
            temp.getNext().setNickName(nickName);
        }else {
            System.out.println("该节点不存在,请确认信息");
        }
    }
​
    //删除(即更改节点连接情况)
    public void delete(int no) {
        heroNode temp = head;
        boolean flag = false;
        if(temp.getNext() == null) {
            System.out.println("链表为空,请先录入数据");
            return;
        }
        while(true) {
            if(temp.getNext() == null) {
                break;
            }else if(temp.getNext().getNo() == no) {
                flag = true;
                break;
            }
            temp = temp.getNext();
        }
        if(flag) {
            temp.setNext(temp.getNext().getNext());
            //这里不会空指针!!因为当指针在n处时已经被循环排除,而在n-1处时temp.next.next=null
        }else {
            System.out.println("该节点不存在,请确认信息");
        }
    }
    //查询某个节点内容
    public void Node(int no) {
        heroNode temp = head;
        boolean flag = false;
        if(temp.getNext() == null) {
            System.out.println("链表为空,请先录入数据");
            return;
        }
        while(true) {
            if(temp.getNext() == null) {
                break;
            }else if(temp.getNext().getNo() == no) {
                flag = true;
                break;
            }
            temp = temp.getNext();
        }
        if(flag) {
            System.out.println(temp.getNext());
        }else {
            System.out.println("该节点不存在,请确认信息");
        }
    }
    //链表长度
    public int length() {
        heroNode temp = head;
        int length = 0;
        if(head.getNext() == null) {
            return 0;
        }
        while(temp.getNext() != null) {
            length ++;
            temp = temp.getNext();
        }
        return length;
    }
​
    //逆序输出(原链表无损)
    //用栈来存储链表数据,Stack
    public void reverseOutput() {
        heroNode temp = head;
        if(head.getNext() == null) {
            System.out.println("链表为空,请先录入数据");
            return;
        }
        Stack<heroNode> stack = new Stack<heroNode>();
        while(temp.getNext() != null) {
            stack.push(temp.getNext());
            temp = temp.getNext();
        }
        //输出栈的内容
        while(stack.size() > 0) {
            System.out.println(stack.pop());
        }
    }
}
​
//该类表示节点(存取数据的单位)
class heroNode {
    private int no;//编号
    private String name;
    private String nickName;
    private heroNode next;
    //next用于连接下一个节点
    //每次创建一个新的类对象时都会生成一个heroNode类型的next变量,初始值为null
    //实际上next就相当于链表中当前节点和下一个节点的连接
​
    public heroNode() {
    }
​
    public heroNode(int no, String name, String nickName) {
        this.no = no;
        this.name = name;
        this.nickName = nickName;
    }
​
    public int getNo() {
        return no;
    }
​
    public void setNo(int no) {
        this.no = no;
    }
​
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        this.name = name;
    }
​
    public String getNickName() {
        return nickName;
    }
​
    public void setNickName(String nickName) {
        this.nickName = nickName;
    }
​
    public heroNode getNext() {
        return next;
    }
​
    public void setNext(heroNode next) {
        this.next = next;
    }
​
    @Override
    public String toString() {
        return "排名:" + no +
                "\t姓名:" + name +
                "\t绰号:" + nickName;
    }
}

总结

核心
1.节点类中必须有指向下一个节点的next变量
2.需要一个临时变量temp

需注意
1.代码顺序。顺序颠倒导致了死循环、空指针等问题
2.该单链表的前提是有一个永不赋值的头节点(空的头节点)
3.循环时,节点从前一个节点开始,实际上操作还是temp.next

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值