PAT002 Reversing Linked List

题目:

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 (<= 105) 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 Next is 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

分析:主要考查链表逆序。 如果通过数组进行排序,然后每K个逆序输出,对于多余的节点将无法通过测试,所以实现必须使用链表。
代码:
typedef struct reverseNode {
    
    long address;
    int value;
    long nextAdd;
    struct reverseNode *next;
    
} ReverseNode;

ReverseNode *reverseLink(ReverseNode *head, int reverseLen)
{
    ReverseNode *new = head->next;
    ReverseNode *old = new->next;
    int count = 1;
    while (count < reverseLen) {
        ReverseNode *temp = old->next;
        old->next = new;
        old->nextAdd = new->address;
        new = old;
        old = temp;
        count++;
    }
    head->next->next = old;
    if (!old) {
        head->next->nextAdd = -1;
    } else {
        head->next->nextAdd = old->address;
    }
    ReverseNode *temp = head->next;
    head->next = new;
    head->nextAdd = new->address;
    return temp;
}

int main()
{
    // 读取输入
    long beginAddress;
    int number, reverseLen;
    scanf("%ld %d %d", &beginAddress, &number, &reverseLen);
    
    ReverseNode *head = (ReverseNode *)malloc(sizeof(ReverseNode));
    ReverseNode *a[number];

    for (int i = 0; i < number; i++) {
        long address, nextAdd;
        int value;
        scanf("%ld %d %ld",&address, &value, &nextAdd);
        ReverseNode *node = (ReverseNode *)malloc(sizeof(ReverseNode));
        node->address = address;
        node->value = value;
        node->nextAdd = nextAdd;
        node->next = 0;
        a[i] = node;
        if (beginAddress == address) {
            head->next = node;
        }
    }
    
    // 对输入数据通过链表连接起来
    ReverseNode *temp = head->next;
    int actualNumber = 1;
    int recyCount = number;
    while (temp->nextAdd != -1 && recyCount-- > 0) {
        for (int i = 0; i < number; i++) {
            ReverseNode *tempNode = a[i];
            if (tempNode->address == temp->nextAdd) {
                temp->next = tempNode;
                temp->nextAdd = tempNode->address;
                temp = temp->next;
                actualNumber++;
                break;
            }
        }
    }
    
    // 反转
    if (reverseLen > 1) {
        int reverseCount = actualNumber / reverseLen; // 需要进行反转的次数
        ReverseNode *tempHead = head;
        while (reverseCount-- > 0) {
            tempHead = reverseLink(tempHead, reverseLen);
        }
    }
    
    ReverseNode *ptr = head->next;
    while (ptr) {
        if (ptr->nextAdd == -1) {
            printf("%.5ld %d -1\n", ptr->address, ptr->value);
        } else {
            printf("%.5ld %d %.5ld\n", ptr->address, ptr->value, ptr->nextAdd);
        }
        ptr = ptr->next;
    }
}

 

运行结果:

[测试点5,是使用超级大量数据,由于我在将输入数据通过链表连接起来那一步采用的是嵌套循环,复杂度O(N^2),可能是这里导致的,不确定。 但是总体反转思路是这样的,后面找到原因了再进行更新]

posted @ 2015-04-05 11:09  2020_xx  阅读(229)  评论(0编辑  收藏  举报