zoukankan      html  css  js  c++  java
  • 中国大学MOOC数据结构基础习题集、021、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

    输入:

    第一行:链表的首地址add,结点个数n,每隔k个进行一次反转。
    接下来的n行:结点的地址address,数据data,下一个结点的地址next。
    输出:
    反转之后的结果。

    建议测试如下几个情况
    1. k=1或者k=n:

    00100 6 6
    00000 4 99999
    00100 1 12309
    68237 6 -1
    33218 3 00000
    99999 5 68237
    12309 2 33218

    2. 有其他链表干扰(即有多个-1出现):

    00100 6 2
    00000 4 99999
    00100 1 12309
    68237 6 -1
    33218 3 -1
    99999 5 68237
    12309 2 33218

    先说一下我的解题思路吧:
    1. 首先要处理输入数据。我是用C++中的容器(vector),容器内存储的类型是新建的类Node。
     1 class Node
     2 {
     3 public :
     4     int address;
     5     int data;
     6     int next;
     7     Node* nextNode;
     8     Node(int a = 0, int d = 0, int n = 0):
     9         address(a), data(d), next(n)
    10     {
    11         nextNode = NULL;
    12     }
    13 };
    14 int main()
    15 {
    16     int add, n, k;
    17     cin >> add >> n >> k;
    18     vector<Node> vec;
    19     // input the data
    20     for(int i=0; i<n; i++)
    21     {
    22         int inputa, inputb, inputc;
    23         cin >> inputa >> inputb >> inputc;
    24         Node node(inputa, inputb, inputc);
    25         vec.push_back(node);
    26     }
    27     // ...
    28 }
    2. 这里首先要进行一个预处理,就是按照address对vector内的数据进行升序排序。这么做是为了能增快程序的运行速度,以便通过测试用例5。
    1 // define before main
    2 bool cmp(const Node &a,const Node &b)
    3 {
    4     return a.address < b.address;
    5 }
    6 int main(){
    7     // ...
    8     sort(vec.begin(), vec.end(), cmp);
    9 }
    3. 然后要处理数据,把vecotr内的数据组成单链表。ncount是链表有效结点的数目,p用来遍历myList,q用来遍历myNewList(即反转后的链表)。处理的过程如下:在vector内不断的寻找address为add(即链表头),找到之后放到MyList,然后让it->next成为新的add。不断重复此过程,直到it->next为-1(即链表尾)为止。上面的预处理在这里就起到作用了,如果没有按照address进行升序排序,这个过程会很慢,通不过测试用例。
    用while(1)循环,并且当it走到vector的end再让它回到begin,成一个环状。一定会有it->next为-1走出循环,所以不必担心死循环问题。
     1     Node* myList = new Node();
     2     int ncount = 0;
     3     Node *p = NULL;
     4     Node *q = NULL;
     5     // deal the data from vector to list
     6     vector<Node>::iterator it = vec.begin();
     7     while(1)
     8     {
     9         // find the first node
    10         if(it->address == add)
    11         {
    12             if(myList->nextNode == NULL)
    13             {
    14                 p = myList->nextNode = new Node(it->address, it->data, it->next);
    15             }
    16             else
    17             {
    18                 p = p -> nextNode = new Node(it->address, it->data, it->next);
    19             }
    20             ncount ++;
    21             if(it -> next == -1)
    22                 break;
    23             else
    24                 add = it -> next;
    25         }
    26         it++;
    27         if(it == vec.end())
    28             it = vec.begin();
    29     }// for
    4. 接下来就是反转了,具体的我已经写到注释里了,如果有看不懂的地方可以再评论区里发表评论。
     1     // if the k greater than effective data, then output all
     2     if(k>ncount)
     3     {
     4         p = myList;
     5         while(p->nextNode != NULL)
     6         {
     7             p = p -> nextNode;
     8             if(p->next != -1)
     9                 printf("%.5d %d %.5d\n", p->address, p->data, p->next);
    10             else
    11                 printf("%.5d %d -1\n", p->address, p->data);
    12         }
    13     }// if
    14     else
    15     {
    16         Node *myNewList = new Node();
    17         // 借助栈来完成反转
    18         stack<Node*> sta;
    19         // 需要反转几次
    20         int times = ncount/k;
    21         // p始终指向MyList
    22         p = myList;
    23         // q始终指向MyNewList
    24         q = myNewList;
    25         // 进行times次反转
    26         for(int j=0; j<times; j++)
    27         {
    28             for(int m=0; m<k; m++)
    29             {
    30                 p = p -> nextNode;
    31                 sta.push(p);
    32             }
    33             for(int m=0; m<k; m++)
    34             {
    35                 Node *qt = sta.top();
    36                 sta.pop();
    37                 if(myNewList->nextNode == NULL)
    38                 {
    39                     q = myNewList->nextNode = new Node(qt->address, qt->data, qt->next);
    40                 }
    41                 else
    42                 {
    43                     q = q -> nextNode = new Node(qt->address, qt->data, qt->next);
    44                 }
    45             }
    46         } // for
    47         // 将剩下的节点依次插入到myNewList后面
    48         while(p -> nextNode != NULL)
    49         {
    50             p = p -> nextNode;
    51             if(myNewList->nextNode == NULL)
    52             {
    53                 q = myNewList->nextNode = new Node(p->address, p->data, p->next);
    54             }
    55             else
    56             {
    57                 q = q -> nextNode = new Node(p->address, p->data, p->next);
    58             }
    59         } // while
    60         // 输出
    61         p = myNewList;
    62         while(p->nextNode != NULL)
    63         {
    64             p = p -> nextNode;
    65             if (p->nextNode != NULL)
    66                 p->next = p->nextNode -> address;
    67             else
    68                 p->next = -1;
    69             if(p->next != -1)
    70                 printf("%.5d %d %.5d\n", p->address, p->data, p->next);
    71             else
    72                 printf("%.5d %d -1\n", p->address, p->data);
    73         } // while
    5. 完整的代码如下:
      1 #include <iostream>
      2 #include <vector>
      3 #include <cstdlib>
      4 #include <iomanip>
      5 #include <cstdio>
      6 #include <stack>
      7 #include <algorithm>
      8 using namespace std;
      9 
     10 class Node
     11 {
     12 public :
     13     int address;
     14     int data;
     15     int next;
     16     Node* nextNode;
     17     Node(int a = 0, int d = 0, int n = 0):
     18         address(a), data(d), next(n)
     19     {
     20         nextNode = NULL;
     21     }
     22 };
     23 bool cmp(const Node &a,const Node &b)
     24 {
     25     return a.address < b.address;
     26 }
     27 int main()
     28 {
     29     int add, n, k;
     30     cin >> add >> n >> k;
     31     vector<Node> vec;
     32     // input the data
     33     for(int i=0; i<n; i++)
     34     {
     35         int inputa, inputb, inputc;
     36         cin >> inputa >> inputb >> inputc;
     37         Node node(inputa, inputb, inputc);
     38         vec.push_back(node);
     39     }
     40     sort(vec.begin(), vec.end(), cmp);
     41     Node* myList = new Node();
     42     int ncount = 0;
     43     Node *p = NULL;
     44     Node *q = NULL;
     45     // deal the data from vector to list
     46     vector<Node>::iterator it = vec.begin();
     47     while(1)
     48     {
     49         // find the first node
     50         if(it->address == add)
     51         {
     52             if(myList->nextNode == NULL)
     53             {
     54                 p = myList->nextNode = new Node(it->address, it->data, it->next);
     55             }
     56             else
     57             {
     58                 p = p -> nextNode = new Node(it->address, it->data, it->next);
     59             }
     60             ncount ++;
     61             if(it -> next == -1)
     62                 break;
     63             else
     64                 add = it -> next;
     65         }
     66         it++;
     67         if(it == vec.end())
     68             it = vec.begin();
     69     }// for
     70     // if the k greater than effective data, then output all
     71     if(k>ncount)
     72     {
     73         p = myList;
     74         while(p->nextNode != NULL)
     75         {
     76             p = p -> nextNode;
     77             if(p->next != -1)
     78                 printf("%.5d %d %.5d\n", p->address, p->data, p->next);
     79             else
     80                 printf("%.5d %d -1\n", p->address, p->data);
     81         }
     82     }// if
     83     else
     84     {
     85         Node *myNewList = new Node();
     86         // 借助栈来完成反转
     87         stack<Node*> sta;
     88         // 需要反转几次
     89         int times = ncount/k;
     90         // p始终指向MyList
     91         p = myList;
     92         // q始终指向MyNewList
     93         q = myNewList;
     94         // 进行times次反转
     95         for(int j=0; j<times; j++)
     96         {
     97             for(int m=0; m<k; m++)
     98             {
     99                 p = p -> nextNode;
    100                 sta.push(p);
    101             }
    102             for(int m=0; m<k; m++)
    103             {
    104                 Node *qt = sta.top();
    105                 sta.pop();
    106                 if(myNewList->nextNode == NULL)
    107                 {
    108                     q = myNewList->nextNode = new Node(qt->address, qt->data, qt->next);
    109                 }
    110                 else
    111                 {
    112                     q = q -> nextNode = new Node(qt->address, qt->data, qt->next);
    113                 }
    114             }
    115         } // for
    116         // 将剩下的节点依次插入到myNewList后面
    117         while(p -> nextNode != NULL)
    118         {
    119             p = p -> nextNode;
    120             if(myNewList->nextNode == NULL)
    121             {
    122                 q = myNewList->nextNode = new Node(p->address, p->data, p->next);
    123             }
    124             else
    125             {
    126                 q = q -> nextNode = new Node(p->address, p->data, p->next);
    127             }
    128         } // while
    129         // 输出
    130         p = myNewList;
    131         while(p->nextNode != NULL)
    132         {
    133             p = p -> nextNode;
    134             if (p->nextNode != NULL)
    135                 p->next = p->nextNode -> address;
    136             else
    137                 p->next = -1;
    138             if(p->next != -1)
    139                 printf("%.5d %d %.5d\n", p->address, p->data, p->next);
    140             else
    141                 printf("%.5d %d -1\n", p->address, p->data);
    142         } // while
    143     }// else
    144     return 0;
    145 }
    
    

    困扰我两周的难题终于解决了,试验了20多次将近30次,有图为证:

    最后再粘一下AC的成果:

     










  • 相关阅读:
    std thread
    windows更新包发布地址
    How to set up logging level for Spark application in IntelliJ IDEA?
    spark 错误 How to set heap size in spark within the Eclipse environment?
    hadoop 常用命令
    windows 安装hadoop 3.2.1
    windows JAVA_HOME 路径有空格,执行软连接
    day01MyBatisPlus条件构造器(04)
    day01MyBatisPlus的CRUD 接口(03)
    day01MyBatisPlus入门(02)
  • 原文地址:https://www.cnblogs.com/clevercong/p/4171333.html
Copyright © 2011-2022 走看看