A1052 Linked List Sorting (25 分)

A linked list consists of a series of structures, which are not necessarily adjacent in memory. We assume that each structure contains an integer key and a Next pointer to the next structure. Now given a linked list, you are supposed to sort the structures according to their key values in increasing order.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive N (<10​5​​) and an address of the head node, where N is the total number of nodes in memory and the address of a node is a 5-digit positive integer. NULL is represented by −1.

Then N lines follow, each describes a node in the format:

Address Key Next

where Address is the address of the node in memory, Key is an integer in [−10​5​​,10​5​​], and Next is the address of the next node. It is guaranteed that all the keys are distinct and there is no cycle in the linked list starting from the head node.

Output Specification:

For each test case, the output format is the same as that of the input, where N is the total number of nodes in the list and all the nodes must be sorted order.

Sample Input:

5 00001
11111 100 -1
00001 0 22222
33333 100000 11111
12345 -1 33333
22222 1000 12345

Sample Output:

5 12345
12345 -1 00001
00001 0 11111
11111 100 22222
22222 1000 33333
33333 100000 -1

题意:

 给出 N 个节点的地址、数据、指针域,然后给出链表的首地址,要求在这个链表上的节点按数据值从小到大输出

思路:

本题的思路,切忌简单的以为将节点存入结构,对 data 值进行排序即可。其难点在于:链表的地址并不连续,排序的实现仅仅比较 data 值值是不可以的。定义 flag 表示节点在链表中是否出现过(是否有效),定义 cmp 函数时,先查看 flag 是否为 false,若为false 要首先将 flag 按照从大到小来排序。

知识点:

静态链表

  1. 我们知道,动态链表中需要指针来建立节点之间的连接关系,比较麻烦。对于有些问题来说,节点的地址是比较小的整数(比如 5 位数的地址),这样就没有必要去建立动态链表,而应该使用方便很多的静态链表
  2. 实现原理为 hash,通过建立一个机构体数组,令数组的下标直接表示节点的地址,来达到直接访问数组中的元素就能访问节点的效果。其中,next是 int 型,用来存放下一个节点的地址(其实就是数组的下标)

注意:

  1. 使用 %05d 来弥补位数不足 5 位的数字。但要注意 -1 不可使用 %05d 来表示
  2. 如果数组中数据均为无效,这时候根据有效节点的特判输出“0 -1”
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 100005;
struct Node{    //定义静态链表
    int address, data, next;
    bool flag;
}node[maxn];
bool cmp(Node a, Node b){
    if(a.flag == false || b.flag == false){
        return a.flag > b.flag;     //只要 a 和 b 中有一个无效节点,就把他放到后面去
    }
    else{
        return a.data < b.data;
    }
}
int main(){
    for(int i = 0; i < maxn; i++){  //初始化
        node[i].flag = false;
    }
    int n, begin, address;
    scanf("%d%d", &n, &begin);
    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 = begin;
    //枚举链表,对flag进行标记,同时计数有效节点个数
    while(p != -1){
        node[p].flag = true;
        count++;
        p = node[p].next;
    }
    if(count == 0){
        printf("0 -1");
    }
    else{
    //筛选有效节点,并按照data从小到大排序
        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{
                printf("%05d %d -1\n", node[i].address, node[i].data);
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_35093872/article/details/87862542