1052 Linked List Sorting (25分)
题意
给出N个结点的地址address、数据域data以及指针域next,然后给出链表的首地址,要求把在这个链表.上的结点按data值从小到大输出。
样例解释
按照输入,这条链表是这样的(结点格式为[address, data,next]):
[00001, 0, 22222]→[22222, 1000, 12345]→[12345, -1, 33333]→[3333, 100000, 11111]→[1111, 100, -1]
按key值排序之后得到:
[12345, -1, 00001]→[00001, 0, 11111]→[1111, 100, 22222]→[2222, 1000, 33333]→[33333, 100000, -1]
错解
天真的我一开始写了个无比沙雕的代码:
const int N=1e5+10;
struct Node {
int addr;
int value;
int nxt;
bool operator<(const Node &W) const
{
return value < W.value;
}
}a[N];
int n,head;
int main()
{
cin>>n>>head;
for(int i=0;i<n;i++) cin>>a[i].addr>>a[i].value>>a[i].nxt;
sort(a,a+n);
printf("%d %05d\n",n,a[0].addr);
for(int i=0;i<n;i++)
{
if(i == n-1)
printf("%05d %d -1",a[i].addr,a[i].value);
else
printf("%05d %d %05d\n",a[i].addr,a[i].value,a[i+1].addr);
}
//system("pause");
return 0;
}
完全没有考虑不在链表上的结点,直接对所有结点一窝蜂排序,就这还能骗\(21\)分,?_?。
正解
- 定义静态链表,其中结点性质由bool型变量flag定义,表示为结点在链表中是否出现。flag 为false表示无效结点(不在链表上的结点)。
- 初始化,令flag均为false(即0),表示初始状态下所有结点都是无效结点。
- 由题目给出的链表首地址begin遍历整条链表,并标记有效结点的flag为true(即1),同时计数有效结点的个数count。
- 对结点进行排序,排序函数cmp的排序原则是;如果cmp的两个参数结点中有无效结点的话,则按flag从大到小排序,以把有效结点排到数组左端( 因为有效结点的flag为1,大于无效结点的flag);否则按数据域从小到大排序。
- 由于有效结点已经按照数据域从小到大排序,因此按要求输出有效结点即可。
const int N=1e5+10;
struct Node {
int addr,val,nxt;
bool exist;
bool operator<(const Node &W) const
{
if(exist == false || W.exist == false)
return exist > W.exist;
else
return val < W.val;
}
}a[N];
int n,head;
int main()
{
cin>>n>>head;
for(int i=0;i<n;i++)
{
int addr,val,nxt;
cin>>addr>>val>>nxt;
a[addr]={addr,val,nxt};
}
int p=head;
int cnt=0;
while(p != -1)
{
cnt++;
a[p].exist = true;
p = a[p].nxt;
}
if(cnt == 0)
{
printf("%d %d\n",cnt,head);
}
else
{
sort(a,a+N);
printf("%d %05d\n",cnt,a[0].addr);
for(int i=0;i<cnt;i++)
if(i == cnt-1)
printf("%05d %d -1",a[i].addr,a[i].val);
else
printf("%05d %d %05d\n",a[i].addr,a[i].val,a[i+1].addr);
}
//system("pause");
return 0;
}
用vector记录所有在链表上的结点也可,效率更高(相比对所有元素排序而言,这里只对有效的结点进行排序),注意对\(0\)的特判。
const int N=1e5+10;
struct Node {
int addr,val,nxt;
bool operator<(const Node &W) const
{
return val < W.val;
}
}a[N];
int n,head;
int main()
{
cin>>n>>head;
for(int i=0;i<n;i++)
{
int addr,val,nxt;
cin>>addr>>val>>nxt;
a[addr]={addr,val,nxt};
}
int p=head;
vector<Node> v;
while(p != -1)
{
v.pb(a[p]);
p = a[p].nxt;
}
sort(v.begin(),v.end());
if(v.size() == 0)
{
printf("%d %d\n",v.size(),head);
}
else
{
printf("%d %05d\n",v.size(),v[0].addr);
for(int i=0;i<v.size();i++)
if(i == v.size()-1)
printf("%05d %d -1",v[i].addr,v[i].val);
else
printf("%05d %d %05d\n",v[i].addr,v[i].val,v[i+1].addr);
}
//system("pause");
return 0;
}