数据结构——单向链表(java)

1.链表是以结点的方式来存储,是链式存储

2.每个结点包含 data(数据) 域, next 域:指向下一个节点. 链表的各个节点不一定是连续存储.

3.链表分带头结点的链表和没有头节点的链表,根据实际的需求来确定

链表结构如图:

以下用一个带头结点的链表来讲解:

案例:用一个带头结点的链表来存储学生的基本信息,实现增删改查功能

带头结点的单链表结构图:

思路图解:

 1.增

尾插法:

 

//尾加法
    public void addLast(Student s) {
        Student temp = head;
        while (true) {
            if (temp.next == null) {
                break;
            }
            temp = temp.next;//一直往下遍历
        }
        temp.next = s;
        s.next = null;
    }

插入指定位置:

//中间插入(按学号从小到大)
    public void addMid(Student s) {
        Student temp = head;
        boolean flag = false;
        while (true) {
            if (temp.next == null) {//到链表最后了
                break;
            }
            if (temp.next.num > s.num) {//找到位置了
                break;
            }else if (temp.next.num==s.num){//说明要添加的学生已经存在
                flag=true;
                break;
            }
            temp=temp.next;//使temp后移,进行遍历
        }
        if (flag){
            System.out.println("学生已经存在不能增加");
        }else{
            //插入(重点)
            s.next=temp.next;
            temp.next=s;
        }
    }

2.删

//删除
    public void del(int num) {
        Student temp = head;
        boolean flag = false;
        while (true) {
            if (temp.next == null) {//已经到链表的最后
                break;
            }
            if (temp.next.num == num) {//找到待删除节点的前一个节点temp
                flag = true;
                break;
            }
            temp = temp.next;//temp后移
        }
        //判断flag
        if (flag) {//找到
            //删除
            temp.next = temp.next.next;
        } else {
            System.out.println("要删除的节点不存在");
        }
    }

3.查

遍历链表:

思路:利用辅助变量temp=head;

加上循环判断temp.next是否为空,不为空则输出。

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

查询指定元素:

思路:在遍历的基础上,加上一个判断语句,判断temp.next.学号,temp.next.姓名是否与我们要找的相等,相等则输出。

4.改

思路:通过辅助变量temp找到我们要修改的结点(对象),将新的结点数据赋值给temp即可

即:假设要插入Student4

temp.学号=Student4.学号;

temp.姓名=Student4.姓名;

//修改
    public void update(Student s) {
        //判断链表是否空
        if (head.next == null) {
            System.out.println("链表为空~");
            return;
        }
        //找到需要修改的节点,根据no编号
        //定义一个辅助遍历
        Student temp = head;
        boolean flag = false;//表示是否找到该节点
        while (true) {
            if (temp.next == null) {
                break;//已经遍历完链表
            }
            if (temp.next.num == s.num) {
                //找到
                flag = true;
                break;
            }
            temp = temp.next;
        }
        //根据flag判断是否找到要修改的节点
        if (flag) {
            temp.next.name = s.name;
        } else {//没有找到
            System.out.printf("没有找到编号%d的节点,不能修改\n", s.num);
        }
    }

完整代码:

public class singleLinkedListDemo {
    public static void main(String[] args) {
        //测试
        singleLinkedList singleLinkedList = new singleLinkedList();
        singleLinkedList.addLast(new Student(1,"小明"));
        singleLinkedList.addLast(new Student(2,"松鸡"));
        singleLinkedList.addLast(new Student(5,"小李"));
        singleLinkedList.addMid(new Student(4,"张三"));
        singleLinkedList.addMid(new Student(2,"李四"));
        singleLinkedList.addMid(new Student(3,"王五"));
        singleLinkedList.del(3);
        singleLinkedList.del(2);
        singleLinkedList.del(6);
        singleLinkedList.update(new Student(1,"老六"));
        singleLinkedList.list();
    }
}

//创建链表
class singleLinkedList {
    //初始化头节点head为空
    Student head = new Student(0, "");


    //尾加法
    public void addLast(Student s) {
        Student temp = head;
        while (true) {
            if (temp.next == null) {
                break;
            }
            temp = temp.next;//一直往下遍历
        }
        temp.next = s;
        s.next = null;
    }

    //中间插入(按学号从小到大)
    public void addMid(Student s) {
        Student temp = head;
        boolean flag = false;
        while (true) {
            if (temp.next == null) {//到链表最后了
                break;
            }
            if (temp.next.num > s.num) {//找到位置了
                break;
            }else if (temp.next.num==s.num){//说明要添加的学生已经存在
                flag=true;
                break;
            }
            temp=temp.next;//使temp后移,进行遍历
        }
        if (flag){
            System.out.println("学生已经存在不能增加");
        }else{
            //插入(重点)
            s.next=temp.next;
            temp.next=s;
        }
    }

    //删除
    public void del(int num) {
        Student temp = head;
        boolean flag = false;
        while (true) {
            if (temp.next == null) {//已经到链表的最后
                break;
            }
            if (temp.next.num == num) {//找到待删除节点的前一个节点temp
                flag = true;
                break;
            }
            temp = temp.next;//temp后移
        }
        //判断flag
        if (flag) {//找到
            //删除
            temp.next = temp.next.next;
        } else {
            System.out.println("要删除的节点不存在");
        }
    }

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

    //修改
    public void update(Student s) {
        //判断链表是否空
        if (head.next == null) {
            System.out.println("链表为空~");
            return;
        }
        //找到需要修改的节点,根据no编号
        //定义一个辅助遍历
        Student temp = head;
        boolean flag = false;//表示是否找到该节点
        while (true) {
            if (temp.next == null) {
                break;//已经遍历完链表
            }
            if (temp.next.num == s.num) {
                //找到
                flag = true;
                break;
            }
            temp = temp.next;
        }
        //根据flag判断是否找到要修改的节点
        if (flag) {
            temp.next.name = s.name;
        } else {//没有找到
            System.out.printf("没有找到编号%d的节点,不能修改\n", s.num);
        }
    }

}

//创建学生对象
class Student {
    //数据域
    int num;//学号
    String name;//姓名
    //指针域
    Student next;

    //构造器
    public Student(int num, String name) {
        this.num = num;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "num=" + num +
                ", name='" + name + '\'' +
                '}';
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明仔爱编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值