PAT1074:Reversing Linked List Java语言实现

一、题目为:

Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elements on L. For example, given L being 1→2→3→4→5→6, if K = 3, then you must output 3→2→1→6→5→4; if K = 4, you must output 4→3→2→1→5→6.

Input Specification:

Each input file contains one test case. For each case, the first line contains the address of the first node, a positive N(<= 10^5​​) which is the total number of nodes, and a positive K(<= N) which is the length of the sublist to be reversed. The address of a node is a 5-digit nonnegative integer, and NULL is represented by -1.

Then N lines follow, each describes a node in the format:

Address Data Next

where Address is the position of the node, Data is an integer, and Nextis the position of the next node.

Output Specification:

For each case, output the resulting ordered linked list. Each node occupies a line, and is printed in the same format as in the input.

Sample Input:

00100 6 4

00000 4 99999

00100 1 12309

68237 6 -1

33218 3 00000

99999 5 68237

12309 2 33218

Sample Output:

00000 4 33218

33218 3 12309

12309 2 00100

00100 1 99999

99999 5 68237

68237 6 -1


二、题目分析
   将链表存入数组中,以输入案例来说,第一行的第一个数为链表头结点所在的位置,第二个数字表示要存入数组中的节点个数,请注意其中可以有多余节点,举例说明:可以看出来11111位置的节点,就是多余节点,不与链表相连。

00100 7 4

00000 4 99999

00100 1 12309

68237 6 -1

11111  8  44444

33218 3 00000

99999 5 68237

12309 2 33218


    其它的行,第一个数字表示存入数组的位置,第二个数字表示存入数组的数值,第三个数字表示链表的下一个节点的位置。第二行:00100 表示第一个节点的位置,即节点: 00100 1 12309 然后根据12309找到第二个节点:12309 2 33218,继续找,直到找到最后一个节点 68237 6 -1。
(以输入案例说明)

 
 
数组下标00000...0010012309332186823799999
节点值41236...5
节点的下一个指针999991230933218...00000...-1...68237


    其中,N表示要存入数组中的节点个数,与有效节点个数是有区别的,所以在程序中需要获取数组中存入的有效节点个数;K表示将链表内的每K个节点进行逆转再相连,
如:1->2->3->4->5->6->7->8,以K=4进行逆转之后,就会变成4->3->2->1->8->7->6->5;
又比如:1->2->3->4->5->6,以K=4进行逆转之后,就会变成4->3->2->1->5->6.


三、程序框架

(1)读取数组,将数据存入数组中,注意数组的容量为10^5;
(2)获取数组中属于链表的有效节点;
(3)当K=1时不需要进行逆转,当K>1时进行逆转;
(4)打印逆转后的链表,输出格式如输出案例所示,因为要显示“00000”,所以需要将整数型数据转化为字符型;最后一行的最后可以有回车符,但是不能有多余的空格;
package cn.eee.www;
import java.util.Scanner;

class ArrayNode {  
    int data;  
    int next;  
  
    public ArrayNode() {  
    }  
}  
  
public class Test12 {  
    public static void main(String[] args) {  
        // 读取数据存入数组  
        ArrayNode[] array = new ArrayNode[100000];  
        Scanner scan = new Scanner(System.in);  
        int head = scan.nextInt();  
        int N = scan.nextInt();  
        int K = scan.nextInt();  
        int current = 0;  
        int a = head;  
        for (int i = 0; i < N; i++) {  
            current = scan.nextInt();  
            array[current] = new ArrayNode();  
            array[current].data = scan.nextInt();  
            array[current].next = scan.nextInt();  
        }  
        // 返回数组中有效的节点个数,为了防止数组中有多余的节点  
        N = number(head, array, N);  
        // 逆转单向链表  
        if (K > 1) {  
            a = reverse(head, array, N, K);  
        }  
        // 打印逆转后的链表  
        display(a, array, N);  
    }  
  
    /* 
     * 改变输出数字格式 在不够五位数的前面补0 
     */  
    public static String change(int val) {  
        if (val == -1) {  
            return val + "";  
        }  
        String s = "00000";  
        String first = val + "";  
        int length = first.length();  
        s = s.substring(length) + first;  
        return s;  
    }  
  
    /* 
     * 打印数组中的静态链表 
     */  
    public static int display(int head, ArrayNode[] arr, int N) {  
        int num = 0;  
        while (head != -1) {  
            String head1 = change(head);  
            String next1 = change(arr[head].next);  
            System.out.println(head1 + " " + arr[head].data + " " + next1);  
            head = arr[head].next;  
            num++;  
        }  
        return num;  
    }  
  
    // 返回数组中有效的节点个数  
    public static int number(int head, ArrayNode[] arr, int N) {  
        int num = 0;  
        while (head != -1) {  
            head = arr[head].next;  
            num++;  
        }  
        return num;  
    }  
  
    //以K为分界线对单向链表进行逆转  
    public static int reverse(int head, ArrayNode[] arr, int N, int K) {  
        int num = 1;  
        int reverse = 1;  
        int remain = head;  
        int old_head = arr[head].next;  
        int new_head = head;  
        int temp;  
        int remain2 = head;  
        while (reverse <= N / K) {  
            while (num < K) {  
                temp = arr[old_head].next;  
                int a = arr[old_head].data;  
                // 注意这里需要给数组该位置创建一个结点,不能直接用“arr[old_head].next= new_head”会影响old_head的值;  
                arr[old_head] = new ArrayNode();  
                arr[old_head].data = a;  
                arr[old_head].next = new_head;// 将链表方向逆转  
                new_head = old_head;  
                old_head = temp;  
                num++;  
            }  
            if (reverse == 1) {// 第一次逆转时,找到头节点,并将逆转之后的节点与还没逆转的节点相连  
                head = new_head;  
                arr[remain].next = old_head;  
            } else {// 第i(i>1)次的逆转,都直接把逆转之后的节点与第i+1次逆转之后的节点连接起来  
                arr[remain].next = new_head;  
                remain = remain2;  
            }  
            if (old_head == -1) {// 当链表逆转结束时,将尾节点的下一个指向-1  
                arr[remain2].next = -1;  
            } else {// 如果一轮逆转之后链表还没结束,则还需要再进行一轮逆转,所以把所有的节点都往后移一位  
                new_head = old_head;  
                old_head = arr[old_head].next;  
                remain2 = new_head;  
            }  
            num = 1;  
            reverse++;  
        }  
        return head;  
    }  
  
}  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值