数据结构-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 (≤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 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

运行结果

CaseHintResultRun TimeMemory
0sample 有尾巴不反转, 地址取上下界Accepted2 ms352 KB
1正好全反转Accepted3 ms352 KB
2K=N全反转Accepted3 ms416 KB
3K=1不用反转Accepted2 ms416 KB
4N=1 最小caseAccepted2 ms384 KB
5最大N,最后剩K-1不反转Accepted153 ms6048 KB
6有多余结点不在链表上Accepted3 ms416 KB

总结:程序占用的内存稍多,还可以继续改进,有看到更好的运行结果:

http://www.pianshen.com/article/2800296730/

程序


#include<iostream>
using namespace std;

typedef struct node *PtrToNode;
struct node
{
    int adress;
    int data;
    int nextAdress;
    PtrToNode next;
};
typedef PtrToNode List;

int MAX_ADRESS = 100000;
//真实链表长度
int TrueN = 0;

List read(int firstAdress, int N, int K);
void printList(List L);
List read_test(int firstAdress, int N, int K);
List reverseKsublist(List L, int N, int K);


int main()
{
    List L, newL;
    int firstAdress, N, K;

    cin >> firstAdress;
    cin >> N;
    cin >> K;
    L = read(firstAdress, N, K);

    /* 测试用例
    firstAdress = 100;
    N = 7;
    K = 7;
    L = read_test(firstAdress, N, K);
    */
    newL = reverseKsublist(L, TrueN, K);
    printList(newL);
    return 0;
}

List reverSubList(List subList, int K)
{
    List FirstToL, SecToL, ThreeToL;

    FirstToL = subList->next;
    SecToL = FirstToL->next;
    ThreeToL = NULL;

    for(int i=0; i<K-1; i++){
        ThreeToL = SecToL->next;
        SecToL->next = FirstToL;
        SecToL->nextAdress = FirstToL->adress;
        //三个指针后移
        FirstToL = SecToL;
        SecToL = ThreeToL;

    }
    //将反转后的最后一个元素接到下一个链表第一个元素
    subList->next->next = SecToL;
    if(ThreeToL){
        subList->next->nextAdress = SecToL->adress;
    }
    else{
        subList->next->nextAdress = -1;
    }

    subList->next = FirstToL;
    subList->nextAdress = FirstToL->adress;

    return subList;
}

List reverseKsublist(List L, int N, int K)
{
    List newSubList, temp;

    if(K == 1){return L;}
    if(K>N){K=N;}

    List subListHead = L;
    for(int i=0; i<N/K; i++){
        newSubList = reverSubList(subListHead, K);

        for(int j=0; j<K; j++)
        {subListHead = subListHead->next;}

    }
    return L;

}

//测试用例
List read_test(int firstAdress, int N, int K)
{
    int data[MAX_ADRESS];
    int next[MAX_ADRESS];
    int tempAdr;
    List L, tempL, temp;

    L = new node;
    L->nextAdress = firstAdress;
    L->next = NULL;
    tempL = L;

    //以数据地址作为数组的索引
    //1
    tempAdr = 0;
    data[tempAdr] = 4;
    next[tempAdr] = 99999;
    //2
    tempAdr = 100;
    data[tempAdr] = 1;
    next[tempAdr] = 12309;
    //3
    tempAdr = 68237;
    data[tempAdr] = 6;
    next[tempAdr] = -1;
    //4
    tempAdr = 33218;
    data[tempAdr] = 3;
    next[tempAdr] = 0;
    //5
    tempAdr = 99999;
    data[tempAdr] = 5;
    next[tempAdr] = 68237;
    //6
    tempAdr = 12309;
    data[tempAdr] = 2;
    next[tempAdr] = 33218;
    //7 ->多余结点,不会出现在链表上的
    tempAdr = 00002;
    data[tempAdr] = 10;
    next[tempAdr] = 25468;

    //构建链表结构
    while(1)
    {
        ++TrueN;
        temp = new node;
        if(next[tempL->nextAdress] == -1){
            temp->adress = tempL->nextAdress;
            temp->data = data[temp->adress];
            temp->nextAdress = next[temp->adress];
            temp->next = NULL;
            tempL->next = temp;

            tempL = tempL->next;
            tempL->next = NULL;
            break;
        }
        temp->adress = tempL->nextAdress;
        temp->data = data[temp->adress];
        temp->nextAdress = next[temp->adress];
        tempL->next = temp;
        tempL = tempL->next;

    }

    //printList(L);

    return L;
}

List read(int firstAdress, int N, int K)
{
    int data[MAX_ADRESS];
    int next[MAX_ADRESS];
    int tempAdr;
    List L, tempL, temp;

    L = new node;
    L->nextAdress = firstAdress;
    L->next = NULL;
    tempL = L;

    //以数据地址作为数组的索引
    for(int i=0; i<N; i++)
    {
        cin >> tempAdr;
        cin >> data[tempAdr];
        cin >> next[tempAdr];
    }

    //构建链表结构
    while(1)
    {
        ++TrueN;
        temp = new node;
        if(next[tempL->nextAdress] == -1){
            temp->adress = tempL->nextAdress;
            temp->data = data[temp->adress];
            temp->nextAdress = next[temp->adress];
            temp->next = NULL;
            tempL->next = temp;

            tempL = tempL->next;
            tempL->next = NULL;
            break;
        }
        temp->adress = tempL->nextAdress;
        temp->data = data[temp->adress];
        temp->nextAdress = next[temp->adress];
        tempL->next = temp;
        tempL = tempL->next;
    }

    //printList(L);

    return L;
}

void printList(List L)
{
    List tempL;

    tempL = L->next;
    while(tempL)
    {
        if(tempL->nextAdress == -1)
            printf("%.5d %d %d\n", tempL->adress, tempL->data, tempL->nextAdress);
        else
            //格式输出,%.5意味着如果一个整数不足5位,输出时前面补0 如:22,输出:00022
            printf("%.5d %d %.5d\n", tempL->adress, tempL->data, tempL->nextAdress);
        tempL = tempL->next;
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值