PAT_甲级_1133 Splitting A Linked List

题目大意:

给定一个单链表,节点数目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就是就是下一个节点的地址。

算法思路:

开辟第二个链表,第一遍遍历将所有的负数节点添加进新链表,第二次遍历将所有在[0,K]范围的节点添加进新链表,第三次遍历将剩余所有的节点添加进新链表。

注意点:

  • 1、需要过滤输入的数据,防止出现无效节点(PAT静态链表的套路)。

提交结果:

截屏2020-11-26 下午3.16.10.png

AC代码1:

#include
#include
#include

using namespace std;

struct Node{
    int address;
    int data;
    int next;
    int flag;
    int id;
}nodes[100005];
vector list;// 链表

bool cmp(const Node &a,const Node &b){
    return a.flag!=b.flag?a.flag

AC代码2:

#include
#include

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=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

你可能感兴趣的:(算法-数据结构,c++,链表)