PAT A1052 Linked List Sorting

题意:
给出N个结点的地址address、数据域data以及指针域next,然后给出链表的首地址,要
求把在这个链表上的结点按data值从小到大输出。
样例解释:
按照输入,这条链表是这样的(结点格式为[address, data, next]):
[00001, 0, 22222]→[22222, 1000, 12345]→[12345, -1, 33333]→[33333, 100000, 11111]→[11111,100, -1]
按key值排序之后得到:
[12345, -1, 00001]→[00001, 0, 11111]→[11111, 100, 22222]→[22222, 1000, 33333]→[33333,100000, -11
此处可以直接套用前面讲解的一般解题步骤。
步骤1:定义静态链表,其中结点性质由bool型变量flag定义,表示为结点在链表中是
否出现。flag为false表示无效结点(不在链表上的结点)。


步骤2:初始化,令flag均为false(即0),表示初始状态下所有结点都是无效结点。


步骤3:由题目给出的链表首地址begin遍历整条链表,并标记有效结点的flag为true(即1),同时计数有效结点的个数count。


步骤4:对结点进行排序,排序函数cmp的排序原则是:如果cmp的两个参数结点中有无效结点的话。则 按flag大到小排序,以把有效结点排到数组左端(因为有效结点的flag为1,大于无效结点的flag),否则按数据域从小到大排序(第二级条件)。


步骤5:由于有效结点已经按照数据域从小到大排序,因此按要求输出有效结点即可.


注意点
1.可以直接使用 % 05d的输出格式,以在不足五位时在高位补0。但是要注意 - 1不能使用 % 05d输出,否则会输出 - 0001(而不是 - 1或者 - 00001),因此必须要留意 - 1的输出。
2.题目可能会有无效结点,即不在题目给出的首地址开始的链表上。
3.数据里面还有均为无效的情况,这时就要根据有效结点的个数特判输出”0 - 1”。

#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 100005;
struct Node {
    int data;
    int next;
    int address;
    bool flag;//判断节点是否在链表上。
}node[maxn];
bool cmp(Node a, Node b) {
    if (a.flag == 0 || b.flag == 0) {
        return a.flag > b.flag;
    }
    else {
        return a.data < b.data;
    }
}
int main() {
    for (int i = 0; i < maxn; i++) {//初始化
        node[i].flag = false;
    }
    int n, s, address;
    scanf("%d%d", &n, &s);
    for (int i = 0; i < n; i++) {
        scanf("%d", &address);
        scanf("%d%d", &node[address].data, &node[address].next);
        node[address].address = address;
    }
    int count = 0,p = s;
    while (p !=-1) {
        node[p].flag = true;//进行标记
        count++;//记录有效节点的个数。
        p = node[p].next;
    }
    if (count == 0) {
        printf("0 -1");
    }
    else {
        sort(node, node + maxn, cmp);
        printf("%d %05d\n", count, node[0].address);//先输出链表元素个数,再输出第一个节点的位置
        for (int i = 0; i < count; i++) {
            if (i != count - 1) {
                printf("%05d %d %05d\n",node[i].address, node[i].data, node[i + 1].address);//第三个位置是下一个元素的地址
            }
            else {//如果是最后一个元素则将其下一个节点的位置输出为“-1”,防止-1被%05d化。
                printf("%05d %d -1\n", node[i].address, node[i].data);
            }
        }
    }
    return 0;
}

 

上一篇:基础算法之插入排序(insetion sorting)


下一篇:CF-911E.Stack Sorting(栈)