02-线性结构3 Reversing Linked List(满分答案+十分笨拙且只有21分的“真”链表)

PTA 中国大学mooc数据结构课程02-3

原题:

Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elements on L. For example, given L being 1→2→3→4→5→6, if K=3, then you must output 3→2→1→6→5→4; if K=4, you must output 4→3→2→1→5→6.

Input Specification:

Each input file contains one test case. For each case, the first line contains the address of the first node, a positive N (≤105) which is the total number of nodes, and a positive K (≤N) which is the length of the sublist to be reversed. The address of a node is a 5-digit nonnegative integer, and NULL is represented by -1.

Then N lines follow, each describes a node in the format:

Address Data Next

where Address is the position of the node, Data is an integer, and Next is the position of the next node.

Output Specification:

For each case, output the resulting ordered linked list. Each node occupies a line, and is printed in the same format as in the input.

Sample Input:

00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218

Sample Output:

00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1

(2023.4.23)更新一下满分答案(非常不解的是flag自减没有放进if(flag)语句内的时候最大N那个测试点是没法通过的,给出了答案错误的提示,希望有大佬能指点一下)。

#include<stdio.h>
#define max_n 100001

struct list{
    int data;
    int next;
}l[max_n];

int reverselink(int head,int k);
void printlink(int head);
int countn(int head);
int main(){
    int N,K,head,addressi,datai,nexti;
    scanf("%d %d %d",&head,&N,&K);
    for(int i=0;i<N;i++){
        scanf("%d %d %d",&addressi,&datai,&nexti);
        l[addressi].data=datai;l[addressi].next=nexti;
    }
    head=reverselink(head,K);
    printlink(head);
    return 0;
}
void printlink(int head){
    while(head!=-1){
        if(l[head].next!=-1) printf("%05d %d %05d\n",head,l[head].data,l[head].next);
        else printf("%05d %d %d\n",head,l[head].data,l[head].next);
        head=l[head].next;
    }
}
int countn(int head){
    int ptr=head;
    int count=1;
    while(l[ptr].next!=-1){
        count++;
        ptr=l[ptr].next;
    }
    return count;
}
int reverselink(int head,int k){
    int ptr,new=head,old=head,newhead=head,lasttail,flag=1;
    int n=countn(head)/k;
    if(n&&k!=1){
        int tail=lasttail=head;
        while(n>0){
        	new=old;
        	ptr=l[old].next;
        	old=ptr;
            for(int i=1;i<k;i++){
                ptr=l[old].next;
                l[old].next=new;
                new=old;
                old=ptr;
            }
            n--;
            if(flag){
                newhead=new;
                flag--;
            }else{
            	l[lasttail].next=new;
			}
			l[tail].next=ptr;
            lasttail=tail;
            tail=ptr;
        }
    }
    return newhead;
}


(2023.4.11)

一开始不知道该用结构数组建立这个链表,然后用了真的链表做这题。

反转链表的K意思是每K个进行一次反转,一开始没读懂看到题目的3-2-1-6-5-4样例我还以为是题目写错了。如果没有对每K个进行反转的话只能有18分。(ps:在千辛万苦修改那么多次写完这么多行过后终于不是零分了但是却只有18/25分真是让人又兴奋又绝望啊hhh,最后还是求助答案和mooc小白课程了)

最后两个测试点:最大N,最后剩K-1不反转、有多余结点不在链表上无法通过,因为没有考虑陈越姥姥加入的“内存垃圾”。

之后又用了建链、筛选实际链的步骤浅试了一遍,但是自己测试的结果粗略看了下是对的,结果所有测试点一个都过不了哈哈哈,所以最后还是注释掉了。未来有时间再回来翻翻哪里出问题了。

有机会再用结构数组做一遍。

#include<stdio.h>
#include<stdlib.h>

typedef struct Node{
    int address;
    int data;
    int nextadd;
    struct Node* next;
}Node;

typedef struct Link{
    Node* head;
    Node* tail;
}link;
void scanandcreat(link* l,int add,int dat,int nex);
void add_node(link* l,int add,int dat,int nex);
void reverselink(link* l,int k,int rvnum);
void printlink(link *l);
link sort(link *l1,int head);

int main(){
    int firstaddress,numberofnode,k;
    int add,dat,nex;
    link l1,l2;
    l1.head=l1.tail=NULL;
    scanf("%d %d %d",&firstaddress,&numberofnode,&k);
    for(int i=0;i<numberofnode;i++){
        scanf("%d %d %d",&add,&dat,&nex);
        add_node(&l1,add,dat,nex);
        //scanandcreat(&l1,add,dat,nex);
    }
    reverselink(&l1,numberofnode,k);
    //l2=sort(&l1,firstaddress);
    //reverselink(&l2,numberofnode,k);
    printlink(&l1);
    //printlink(&l2);
    return 0;
}

void add_node(link* l,int add,int dat,int nex){
    if(!l->head){
        l->head=l->tail=(Node*)malloc(sizeof(Node));
        l->tail->address=add;
        l->tail->data=dat;
        l->tail->nextadd=-1;
        l->tail->next=NULL;
    }else if(dat>l->tail->data){
        l->tail->next=(Node*)malloc(sizeof(Node));
        l->tail->nextadd=add;
        l->tail=l->tail->next;
        l->tail->address=add;l->tail->data=dat;l->tail->nextadd=-1;
        l->tail->next=NULL;
    }else{
        Node* p=(Node*)malloc(sizeof(Node));
        p->address=add;p->data=dat;p->nextadd=nex;
        if(dat<l->head->data){
            p->next=l->head;p->nextadd=l->head->address;
            l->head=p;
        }else{
            Node* ptr,*front;
            for(ptr=l->head;dat>ptr->data;ptr=ptr->next){
                front=ptr;
            }
            front->nextadd=p->address;front->next=p;
            p->next=ptr;p->nextadd=ptr->address;
        }
    }
}
void reverselink(link* l1,int k,int rvnum){
    if(rvnum==1) return;
    Node* rvnext=l1->head,*ptr=l1->head,*ptrnext,*ptr2next,*thistail,*nexttail;
    int frontadd,flag=0,n=k/rvnum;
    if(rvnum<k){
        while(n--){
            nexttail=rvnext;
            if(flag!=0){ptr=rvnext;ptrnext=ptr->next;}
            for(int i=1;i<=rvnum;i++,rvnext=rvnext->next);
            if(flag==0){ptr=l1->head;ptrnext=ptr->next;thistail=l1->head;}
            do{
                ptr2next=ptrnext->next;
                ptrnext->nextadd=ptr->address;
                ptrnext->next=ptr;
                ptr=ptrnext;ptrnext=ptr2next;
            }while(ptr2next!=rvnext);
            if(flag==0){
                l1->head->nextadd=rvnext->address;
                l1->head->next=rvnext;
                l1->head=ptr;
                flag=-1;
            }else{
                thistail->nextadd=ptr->address;
                thistail->next=ptr;
                if(!rvnext){nexttail->nextadd=-1;nexttail->next=NULL;}
                else{nexttail->nextadd=rvnext->address;nexttail->next=rvnext;}
                thistail=nexttail;
            }
        }
    }else{
        rvnext->nextadd=-1;
        ptr=l1->head;ptrnext=ptr->next;
        if(k>2){
            do{
                ptr2next=ptrnext->next;
                ptrnext->nextadd=ptr->address;
                ptrnext->next=ptr;
                ptr=ptrnext;ptrnext=ptr2next;
            }while(ptr2next);
            l1->tail=l1->head;l1->tail->next=NULL;
            l1->head=ptr;
        }else{
            ptr->next=NULL;
            ptrnext->next=ptr;ptrnext->nextadd=ptr->address;
            l1->head=ptrnext;l1->tail=ptr;
        }
    }
}

void printlink(link *l){
    Node* ptr=l->head;
    while(ptr){
        if(ptr->nextadd!=-1){
            printf("%05d %d %05d\n",ptr->address,ptr->data,ptr->nextadd);
        }else{
            printf("%05d %d %d\n",ptr->address,ptr->data,ptr->nextadd);
        }
        ptr=ptr->next;
    }
}

void scanandcreat(link* l,int add,int dat,int nex){
    if(!l->head){
        l->head=l->tail=(Node*)malloc(sizeof(Node));
        l->tail->address=add;
        l->tail->data=dat;
        l->tail->nextadd=nex;
        l->tail->next=NULL;
    }else{
        l->tail->next=(Node*)malloc(sizeof(Node));
        l->tail=l->tail->next;
        l->tail->address=add;l->tail->data=dat;l->tail->nextadd=nex;
        l->tail->next=NULL;
    }
}
link sort(link* l1,int head){
    link l2;
    Node* ptr;
    int cnt=2;
    l2.head=l2.tail=(Node*)malloc(sizeof(Node));
    l2.tail->address=head;l2.tail->data=1;
    for(ptr=l1->head;ptr&&ptr->address!=head;ptr=ptr->next);
    if(!ptr){free(l2.tail);l2.tail=l2.head=NULL;return l2;}
    else{l2.tail->nextadd=ptr->nextadd;l2.tail->next=NULL;}
    while(l2.tail->nextadd!=-1){
        for(ptr=l1->head;ptr&&ptr->address!=l2.tail->nextadd;ptr=ptr->next);
        l2.tail->next=(Node*)malloc(sizeof(Node));
        l2.tail=l2.tail->next;
        l2.tail->address=ptr->address;l2.tail->nextadd=ptr->nextadd;
        l2.tail->data=cnt++;
        l2.tail->next=NULL;
    }
    return l2;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值