题意:链表排序
思路:题目本身并不难,但是这题仔细读题很重要。原题中有一句话,"For each case, the first line contains a positive N and an address of the head node, where N is the total number of nodes in memory",它没有明确表示这个N就是链表的结点个数,而是内存中含有的结点个数(大家可以相比较另外几道链表的题目,看看题目描述的细微差别)。因此,在读入数据后,要从头结点开始遍历一遍链表,把链表上的结点提取出来,因为,输入的链表有可能是不属于这个链表的干扰结点。有几个坑需要注意——
1.输入的结点并不全是链表的结点,因此在正式排序前应先提取出有效结点;
2.有可能在第1步完成后,有效结点为0,故输出 0 -1。
代码:
#include <cstdio> #include <algorithm> using namespace std; const int N=100005; struct Node{ int data; int curr,next; }LinkList[N],node[N]; bool cmp(Node a,Node b){ return a.data<b.data; } int main() { int n,head; scanf("%d%d",&n,&head); int curr,data,next; for(int i=0;i<n;i++){ scanf("%d%d%d",&curr,&data,&next); LinkList[curr].data=data; LinkList[curr].curr=curr; LinkList[curr].next=next; }
//提取有效结点 int cnt=0; while(head!=-1){ node[cnt++]=LinkList[head]; head=LinkList[head].next; } sort(node,node+cnt,cmp); if(cnt==0){//空链表的情况 printf("0 -1\n"); return 0; } printf("%d %05d\n",cnt,node[0].curr); for(int i=0;i<cnt;i++){//注意遍历个数cnt,不是n printf("%05d %d ",node[i].curr,node[i].data); if(i<cnt-1) printf("%05d\n",node[i+1].curr); else printf("-1\n"); } return 0; }
常见的错误写法:
#include <cstdio> #include <algorithm> using namespace std; const int N=100000; struct Node{ int data; int curr,next; }LinkList[N]; bool cmp(Node a,Node b){ return a.data<b.data; } int main() { //freopen("pat.txt","r",stdin); int n,head; scanf("%d%d",&n,&head); int curr,key,next; for(int i=0;i<n;i++){ scanf("%d%d%d",&curr,&key,&next); LinkList[i].data=key; LinkList[i].curr=curr; LinkList[i].next=next; } sort(LinkList,LinkList+n,cmp); printf("%d %05d\n",n,LinkList[0].curr); for(int i=0;i<n;i++){ printf("%05d %d ",LinkList[i].curr,LinkList[i].data); if(i<n-1) printf("%05d\n",LinkList[i+1].curr); else printf("-1\n"); } return 0; }