题目大意:
给定一个单链表,节点数目N和阈值K,从新将链表按照如下规则进行排序,节点值小于0的在最左边,[0,K]的在中间,大于K的在最右边,同时同一类别的节点其相对顺序不能改变.
算法思路:
算法思路1:
由于题目给出的是静态链表,那么数据和地址实际上是绑定在一起的,next指针基本可以先不考虑,我们给链表上每一个节点设置一个flag和id,分别表示当前节点的类别(0对应小于0的节点,1对应[0,K]的节点,2对应大于K的节点),节点在链表中的位置(用来记录相对位置),那么使用nodes数组接受所有的输入节点,然后将不在链表中的节点过滤后添加到list中,然后对list的节点进行排序,排序规则如下:flag小的在前,flag相同的,id小的在前。然后直接输出list数组即可,只需要注意当前节点不是最后一个节点的话,当前节点的next就是就是下一个节点的地址。
算法思路2:
开辟第二个链表,第一遍遍历将所有的负数节点添加进新链表,第二次遍历将所有在[0,K]范围的节点添加进新链表,第三次遍历将剩余所有的节点添加进新链表。
注意点:
- 1、需要过滤输入的数据,防止出现无效节点(PAT静态链表的套路)。
提交结果:
AC代码1:
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
struct Node{
int address;
int data;
int next;
int flag;
int id;
}nodes[100005];
vector<Node> list;// 链表
bool cmp(const Node &a,const Node &b){
return a.flag!=b.flag?a.flag<b.flag:a.id<b.id;
}
int main(){
int begin_address,N,K;
scanf("%d %d %d",&begin_address,&N,&K);
int address,data,next;
for (int i = 0; i < N; ++i) {
scanf("%d %d %d",&address,&data,&next);
nodes[address].address = address;
nodes[address].data = data;
nodes[address].next = next;
if(data<0){
nodes[address].flag = 0;
} else if(data<=K){
nodes[address].flag = 1;
} else {
nodes[address].flag = 2;
}
}
// 遍历所有节点,过滤无效节点
int num = 1;
while (begin_address!=-1){
nodes[begin_address].id = num++;// 记录相对位置
list.push_back(nodes[begin_address]);
begin_address = nodes[begin_address].next;
}
sort(list.begin(),list.end(),cmp);
for (int j = 0; j < list.size(); ++j) {
printf("%05d %d ",list[j].address,list[j].data);
if(j==list.size()-1){
printf("-1");
} else {
printf("%05d\n",list[j+1].address);
}
}
return 0;
}
AC代码2:
#include<cstdio>
#include<cstring>
using namespace std;
struct Node{
int address;
int data;
int next;
}node1[100005];
int main(){
int start,n,k;
scanf("%d %d %d",&start,&n,&k);
Node nodes[n];
for(int i=0;i<n;++i){
Node nd;
scanf("%d %d %d",&nd.address,&nd.data,&nd.next);
node1[nd.address] = nd;
}
int cnt = 0;
//第一次找出data为负数的
Node root = node1[start];
while (root.next!=-1){
if (root.data<0){
nodes[cnt++] = root;
}
root = node1[root.next];
}
if (root.data<0){
nodes[cnt++] = root;
}
//第二次遍历,[0,K]范围的所有节点
root = node1[start];
while (root.next!=-1){
if (root.data>=0&&root.data<=k){
nodes[cnt++] = root;
}
root = node1[root.next];
}
if (root.data>=0&&root.data<=k){
nodes[cnt++] = root;
}
//第三次遍历,大于K的所有节点
root = node1[start];
while (root.next!=-1){
if (root.data>k){
nodes[cnt++] = root;
}
root = node1[root.next];
}
if (root.data>k){
nodes[cnt++] = root;
}
//更新next
for (int i=0;i<cnt-1;++i){
nodes[i].next = nodes[i+1].address;
}
nodes[cnt-1].next = -1;
for (int i=0;i<cnt;++i){
printf("%05d %d",nodes[i].address,nodes[i].data);
if (nodes[i].next!=-1){
printf(" %05d\n",nodes[i].next);
}else {
printf(" -1\n");
}
}
return 0;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。