数据结构与算法-链表试题(java)

单链表

数据类

class Student{
    int id;
    String name;
    Student next; // 指向下一个节点

    public Student(int id, String name) {
        this.id = id;
        this.name = name;
    }
    @Override
    public String toString() {
        return "Student[ 学号 = " + id + ", 姓名 = " + name + ']';
    }
}

单链表类

class SinglyLinkedList{
    private Student head = new Student(0,""); //头节点

    public Student getHead(){
        return head;
    }

    //遍历
    public void info(){
        if (head.next == null){
            System.out.println("链表为空");
            return;
        }
        Student temp = head.next;
        while (true){
            if(temp == null){
                break;
            }
            System.out.println(temp);
            temp = temp.next;
        }
    }

    //添加
    public void add(Student student){
        Student temp = head; //辅助变量
        boolean isFalse = false;//添加的编号(id)是否存在
        while (true){
            if (temp.next == null){ //链表最后
                break;
            }
            if (temp.next.id > student.id){ //编号比较,位置找到
                break;
            }
            if (temp.next.id == student.id){//要新添加的id值已经存在
                isFalse = true;//表示编号存在
                break;
            }
            //temp 后移
            temp = temp.next;
        }
        //判断id值是否存在
        if (isFalse){
            System.out.println("准备添加的数据已存在,学号为 = " + student.id);
        }else
            student.next = temp.next;
            temp.next = student;
        }
}

1、求单链表中有效节点的个数

通过头结点遍历

代码:

class Unity{
   public static int getLenght(Student head){
        int lenght = 0; //计数
        if (head.next == null){//空链表
            return lenght;
        }
        Student temp = head.next;
        while (temp != null){
            lenght++; //累加
            temp = temp.next; //后移
        }
        return lenght;
    }
 }

测试:

public class Demo1 {
    public static void main(String[] args) {
        SinglyLinkedList list = new SinglyLinkedList();
        Student st1 = new Student(11,"依依");
        Student st2 = new Student(62,"尔尔");
        Student st3 = new Student(393,"三三");
        Student st4 = new Student(991,"斯斯");
        list.add(st1);
        list.add(st2);
        list.add(st4);
        list.add(st3);
        list.info();

        //1、求单链表中有效节点的个数
        int lenght = Unity.getLenght(list.getHead());
        System.out.println("单链表节点个数:" + lenght);
    }
}

2、查找单链表中的倒数第k个结点0

链表长度 - 倒数结点(k) = 查找的节点位置
代码:

  public static Student reciprocal(Student head,int index){
        if (head.next == null){
            System.out.println("链表为空,不存在节点");
            return null;
        }
        int lenght = getLenght(head);//长度
        if (index > lenght || index <= 0){
            System.out.println("怎么说呢,不在这个范围内");
            return null;
        }
        Student temp = head;
        for (int i = 0; i <= lenght - index; i++) {
            temp = temp.next;
        }
        return temp;
    }

测试:

	//2、查找单链表中的倒数第k个结点
	Student reciprocal = Unity.reciprocal(list.getHead(), -1);
    System.out.println(reciprocal);

3、单链表的反转

思路:
定义一个新的头节点,遍历原来的链表,取出每个节点,
放在新头节点的后面,更改链表的头节点指向。

1、创建新的头结点 newHead
两个辅助指针
temp = head.next; next = temp.next

在这里插入图片描述

2、遍历
newHead.next = temp; temp = next; next = temp.next
在这里插入图片描述

3、取出的节点放在最前面
temp.next = newHead.next;
在这里插入图片描述

4、更改指向
head.next = newHead.next;

在这里插入图片描述

代码:

   public static void reversetList(Student head){
        if (head.next == null || head.next.next == null){
            //为空或只有一个节点时不需要反转
            return;
        }
        //创建一个新的头节点
        Student newHead = new Student(0,"");
        Student temp = head.next;
        Student next = null;
        while (temp != null){
            next = temp.next;//保存下一次要是有的节点
            temp.next = newHead.next;//下一个节点指向新链表的最前端
            newHead.next = temp;//连接到新链表上
            temp = next;//temp 后移
        }
        head.next = newHead.next;//更改指向
    }

测试:

	 System.out.println("**********反转**********");
     Unity.reversetList(list.getHead());
     list.info();

4、从尾到头打印单链表

思路:
方式一:进行反转,然后遍历打印
方式二:将数据存入数组,然后从尾打印
方式三:栈结构,先进后出(待补充。。。)

代码:数组

public static void printArray(Student head){
    if (head.next == null || head.next.next == null){
        //为空 或只有一个节点时 不需要
        return;
    }
    int size = getLenght(head);
    Student student[] = new Student[size];
    Student temp = head.next;
    for (int i = 0; i < size; i++) {
        student[i] = temp;
        temp = temp.next;
    }
    for (int i = 1; i <= size; i++) {
        System.out.println(student[size - i]);
    }
}

测试:

	System.out.println("**********倒叙**********");
    Unity.printArray(list.getHead());

5、合并两个有序的单链表,合并之后的链表依然有序

代码:感觉并不是很好,有没有其他办法?

   public static void twoList(Student oneHead,Student twoHead){
        if (oneHead.next == null || twoHead.next == null){
            return;
        }
        Student one = oneHead.next;
        Student two = twoHead.next;
        Student student = new Student(0,"");
        Student temp = student;

       while (one != null){
            while (two != null){
                if (one.id > two.id){
                    temp.next = two;
                    temp = temp.next;
                }else {
                    temp.next = one;
                    temp = temp.next;
                    break;
                }
                two = two.next;
            }
            //one 最后的id值比所有值都大
            if (two == null && one != null){
                temp.next = one;
                temp = temp.next;
            }
           one = one.next;
       }
       //two最后的id值比所有值都大
       while (true){
           if (two != null){
               temp.next = two;
               temp = temp.next;
           }else {
               break;
           }
           two = two.next;
       }
       oneHead.next = student.next;
    }

测试:

   SinglyLinkedList list2 = new SinglyLinkedList();
   Student stu1 = new Student(17,"11");
   Student stu2 = new Student(12,"22");
   Student stu3 = new Student(110,"33");
   list2.add(stu1);
   list2.add(stu2);
   list2.add(stu3);
   list2.info();
   System.out.println("**********合并**********");
   Unity.twoList(list.getHead(),list2.getHead());
   list.info();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值