zoukankan      html  css  js  c++  java
  • 天梯赛 L2-022. (数组模拟链表) 重排链表

    题目链接

    题目描述
    给定一个单链表 L1→L2→...→Ln-1→Ln,请编写程序将链表重新排列为 Ln→L1→Ln-1→L2→...。例如:给定L为1→2→3→4→5→6,则输出应该为6→1→5→2→4→3。

    输入格式:

    每个输入包含1个测试用例。每个测试用例第1行给出第1个结点的地址和结点总个数,即正整数N (<= 105)。结点的地址是5位非负整数,NULL地址用-1表示。

    接下来有N行,每行格式为:

    Address Data Next

    其中Address是结点地址;Data是该结点保存的数据,为不超过105的正整数;Next是下一结点的地址。题目保证给出的链表上至少有两个结点。

    输出格式:

    对每个测试用例,顺序输出重排后的结果链表,其上每个结点占一行,格式与输入相同。

    输入样例:
    00100 6
    00000 4 99999
    00100 1 12309
    68237 6 -1
    33218 3 00000
    99999 5 68237
    12309 2 33218

    输出样例:
    68237 6 00100
    00100 1 99999
    99999 5 12309
    12309 2 00000
    00000 4 33218
    33218 3 -1

    分析:
    用数组来模拟链表,如果只是简单的将链表输出来,那么应该没有任何的问题,关键在于如何给链表重新排序。

    我们给每个节点添加一个代表它是链表中的第几个节点的元素index,这样就可以根据index的大小给链表进行排序。

    排序的规则就是原来的链表中的前一半的节点依序成为新的链表中的第2,4,6···个,后一半的节点倒着依序成为新的链表中的第1,3,5···个。

    这样就可以根据该表节点的index属性,来改变节点在链表中的位置。

    代码:

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    struct Node
    {
        int address;//地址
        int data;//数据
        int next;//下地址
        int index=100001;//在链表中的位置
    } node[100009];
    bool cmp(Node a,Node b)//按照在链表中的位置从小到大排序
    {
        return a.index<b.index;
    }
    int main()
    {
        int start,n;
        scanf("%d%d",&start,&n);
        int adr;
        for(int i=0; i<n; i++)
        {
            scanf("%d",&adr);
            node[adr].address=adr;
            scanf("%d%d",&node[adr].data,&node[adr].next);
        }
        int num=0;//表示有效节点的个数,有时候有效节点的个数不一定为n(看别人题解看出来的,我也不知道为啥有这种不合理数据,反正被坑到了)
        //将链表按照最开始的顺序排列出来
        while(start!=-1)
        {
            node[start].index=num;
            num++;
            start=node[start].next;
        }
        sort(node,node+100009,cmp);
        //根据链表的重新排序规则可以发现,前一半分别为第2,4,6--个
        //后一半分别为第1,3,5--个,这样就可以根据这个规律将节点的位置改变
        int index=1;
        for(int i=0; i<num/2; i++)
        {
            node[i].index=index;
            index+=2;
        }
        index=0;
        for(int i=num-1; i>=num/2; i--)
        {
            node[i].index=index;
            index+=2;
        }
        sort(node,node+100009,cmp);
        for(int i = 0; i < num-1; i++)//将下一个节点的地址改变了
            node[i].next = node[i+1].address;
        node[num-1].next = -1;
        for(int i = 0; i < num; i++)
        {
            printf("%05d %d ", node[i].address, node[i].data);
            if(i != num-1) printf("%05d
    ", node[i].next);
            else printf("%d
    ", node[i].next);
        }
        return 0;
    }
    
  • 相关阅读:
    Redis学习笔记(九、Redis总结)
    菜鸟刷面试题(二、RabbitMQ篇)
    RabbitMQ学习笔记(八、RabbitMQ总结)
    MongoDB学习笔记(七、MongoDB总结)
    菜鸟刷面试题(一、Java基础篇)
    朋友圈点赞
    队列变换
    犯二的程度
    猴子选大王
    最大销售增幅
  • 原文地址:https://www.cnblogs.com/cmmdc/p/8596065.html
Copyright © 2011-2022 走看看