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的成果:

     










  • 相关阅读:
    POI 给单元格添加批注
    Linux下Mysql的odbc配置(修改网上博文)
    Linux下mysql实现类似于Sqlser的Profiler的访问记录监听功能
    windows下部署icescrum
    sql server2008查询会话的Ip地址、用户登录名、登录机器名
    error while loading shared libraries的解決方法
    做个标记,指针的指针的应用
    微信架构(转)
    网络监控netstat(转)
    大话MVC模式
  • 原文地址:https://www.cnblogs.com/clevercong/p/4171333.html
Copyright © 2011-2022 走看看