全网最详细Java 实现单链表(增、删、改、查、遍历等)

以学生管理系统为例:节点是学生,整个链表就是管理系统

节点定义、构造函数

学生类有学号、名字、下标等信息,默认所有的节点都是空的
为了方便。把所有的信息都设为public,这样就不用写get()和set()方法

public class Student {
    public int number=0;
    public int size=0; //下标
    public String name;
    public Student next =null;
    public boolean isEmpty =true;

    public Student(){

    }
    public Student(int number,String name, int size){
        this.name =name;
        this.number =number;
        this.size =size;
        this.isEmpty =false;
        next=null;

    }
    public Student(int number,String name){
        this.name =name;
        this.number =number;
        this.isEmpty =false;
        next=null;
    }

注意:为什么会使用 student.next来作比较?(注意这里有点绕)

1,如果student.next ==null, 那么说明它是链表的最后一个节点

2,关于删除操作

如果是双链表的话,使用student.before =studet.next 就可以删除student这个节点,但是因为单链表没有before这个属性,所以当遍历到student这个节点的时候,是找不到student前一个节点的,无法实现这个操作

但是我们可以通过新的方式实现,可以结合图片理解

原本的:student.before =student.next

新的: student…next= student.next.next

指针遍历链表 java_链表

遍历链表(打印学生信息)

public void print(){
        Student student =this;
        while (true){
            System.out.println("链表下标"+student.size+ "  学号:"+student.number+"  名字"+student.name);
            if (student.next ==null){
                break;
            }//最后一个
            student =student.next;
        }
    }

节点复制:调用方法的节点=新节点

public void copy(Student student){
        this.number = student.number;
        this.name =student.name;
        this.next =student.next;
        this.isEmpty =student.isEmpty;
    }

增:添加学生信息(空节点添加信息、添加新节点)

如果student .next ==null 那么确定student是链表的最后一个节点,需要创建一个新节点来存储新数据

public void addStudent(Student s){
        Student student =this;
        while (true){
            if (student.isEmpty ==true){
                student.name =s.name;
                student.number =s.number;
                student.isEmpty =false;
                break;
            }//已经有一个新的节点了,直接添加信息就好
            if (student.next ==null){
                student.next =s;
                s.size = student.size+1;
                s.next =null;
                /**
                 * 为什么要加这句话?难道next 不是null吗?这里有bug不知道怎么改
                 */
                break;
            }//最后一个
            student =student.next;
        }
    }

删:根据学号删除学生信息(这一段是链表操作最难的部分,如果你理解了,就搞定链表了)

public void remove(int removeNumber){
        Student student =this;
        while (true){
            if (student.number ==removeNumber){
                System.out.println("删除的学号"+student.number+"名字"+student.name);
                Student newhead =student.next;
                if (newhead !=null){
                    this.copy(newhead);
                    //头节点不是唯一的节点
                }else{
                    System.out.println("这个链表被整个删除了");
                    Student student1 =new Student();
                    this.copy(student1);
                }//头节点是唯一的节点,newhead是null
                break;
                }//要删除头节点
            if (student.next ==null){
                if (student.number!=removeNumber){
                    System.err.println("系统里没有这个学生");
                }
                break;
                }//最后一个节点
            if (student.next.number == removeNumber){
                Student student3 =student.next.next;
                System.out.println("删除的学号"+student.next.number+"名字"+student.next.name);
                student.next =student3;
                break;
            }//不是删除头节点
            student=student.next;
        }
    }

删:根据名字删除学生信息

public void remove(String name){
        Student student =this;
        int removeNumber =0;
        while (true){
            if (student.name.equals(name)){
                removeNumber =student.number;
                System.out.println("删除的学号"+student.number+"名字"+student.name);
                break;
            }
            if (student.next ==null){
                break;
            }//最后一个
            student=student.next;
        }
        Student student2 =this;
        if (removeNumber ==0){
            //没有找到
            System.err.println("系统里没有这个学生");
        }else{
            //找到了
            while (true){
                if (student2.number ==removeNumber){
                    Student head =new Student();
                    head.next =student2.next;
                   // this= head;
                    break;
                }//要头节点删除
                if (student2.next ==null){
                    break;
                }//最后一个节点
                if (student2.next.number == removeNumber){
                    Student student3 =student2.next.next;
                    student2.next =student3;
                    break;
                }//不是删除头节点
                student2=student2.next;
            }
        }
    }

改:根据学号修改名字

public void set(int newNumber, String newNme){
        Student student =this;
        while (true){

            if (student.number ==newNumber){
                student.name =newNme;
                System.out.println("新的名字设置成功");
                break;
            }//对应的学生
            if (student.next ==null){
                if (student.number !=number){
                    System.err.println("没有对应的学号");
                }//对应的学生
                break;
            }//最后一个
            student =student.next;
        }
    }

查:根据学号查找名字

public String find(int number){
        Student student =this;
        while (true){
            if (student.number ==number){
                return student.name;
            }//对应的学生
            if (student.next ==null){
                if (student.number !=number){
                    System.err.println("没有对应的学号");
                }//对应的学生
                break;
            }//最后一个节点了
            student =student.next;
        }
        return null;
    }

根据学号,修改学生信息(以修改名字为例)

public void set(int newNumber, String newNme){
        Student student =this;
        while (true){

            if (student.number ==newNumber){
                student.name =newNme;
                System.out.println("新的名字设置成功");
                break;
            }//对应的学生
            if (student.next ==null){
                if (student.number !=number){
                    System.err.println("没有对应的学号");
                }//对应的学生
                break;
            }//最后一个
            student =student.next;
        }
    }

测试代码部分

测试:添加、打印、根据学号修改名字

public void test_Set(){
        Student student1 = new Student(1,"zjh1");
        Student student8 = new Student(8,"zjh8");
        Student student15 = new Student(15,"zjh15");
        student1.addStudent(student8);
        student1.addStudent(student15);
        student1.print();
        String name =student1.find(8);
        System.out.println("名字"+name);
        student1.set(8,"zjhNB");
        String name2 =student1.find(8);
        System.out.println("新名字"+name2);
        student1.print();
    }

测试:根据名字删除学生

public void test_Remove(){
        Student student1 = new Student(1,"zjh1");
        Student student2 = new Student(2,"zjh2");
        Student student3 = new Student(3,"zjh3");
        Student student8 = new Student(8,"zjh8");
        Student student15 = new Student(15,"zjh15");
        student1.addStudent(student2);
        student1.addStudent(student3);
        student1.addStudent(student8);
        student1.addStudent(student15);
        student1.print();

        student1.remove("zjh8");
        student1.remove("zjh15");
        student1.remove("");
        student1.print();
    }

总结:链表本身不难,但是要注意遍历范围、特别是删除这个操作,线性表、哈希表都会用到,打好基础很重要。