PAT_B_1025 反转链表 (25 分)【最后两个测试点】

最后两个测试点出错的原因是:不是所有的结点都有效!不是所有的结点都有效!不是所有的结点都有效!(真坑人)

给定一个常数 K 以及一个单链表 L,请编写程序将 L 中每 K 个结点反转。例如:给定 L 为 1→2→3→4→5→6,K 为 3,则输出应该为 3→2→1→6→5→4;如果 K 为 4,则输出应该为 4→3→2→1→5→6,即最后不到 K 个元素不反转。

输入格式:

每个输入包含 1 个测试用例。每个测试用例第 1 行给出第 1 个结点的地址、结点总个数正整数 N (≤10​5​​)、以及正整数 K (≤N),即要求反转的子链结点的个数。结点的地址是 5 位非负整数,NULL 地址用 −1 表示。

接下来有 N 行,每行格式为:

Address Data Next

其中 Address 是结点地址,Data 是该结点保存的整数数据,Next 是下一结点的地址。

输出格式:

对每个测试用例,顺序输出反转后的链表,其上每个结点占一行,格式与输入相同。

输入样例:

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

输出样例:

00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1
#include <iostream>
#include <stdio.h>
using namespace std;
typedef struct node
{
	int prevadd;
	int nextadd;
	int data;
	node* next;
}node;
int main()
{
	int startadd, n, k;
	scanf("%d %d %d",&startadd,&n,&k);
	int countn=0;      //统计有效结点,否则最后两个测试点会报错
	node* List = new node;
	node* FinList = new node;
	List->next = NULL;
	node* p = new node;
	node* pre = new node;
	int prevadd, data, nextadd;
	int prevaddTemp=startadd;
	p = List;
	for (int i = 0; i<n; i++)    //存储输入结点
	{
		node* num = new node;
		num->next = NULL;
		scanf("%d %d %d",&prevadd,&data,&nextadd);  //用scanf和printf,不然5会超时
		num->prevadd = prevadd;
		num->data = data;
		num->nextadd = nextadd;
		p->next=num;
		p=p->next;
	}
	node* fpre=new node;
	fpre=FinList;        //FinList的pre结点
	pre=List;
	p=List->next;
//得出最终仅含有有效结点的有序链表
	while(prevaddTemp != -1)
        {
            if(p==NULL)
            {pre=List;p=List->next;}
            if(p->prevadd==prevaddTemp)
            {
                fpre->next=p;
                pre->next=p->next;
                p->next=NULL;
                p=pre->next;
                fpre=fpre->next;
                prevaddTemp=fpre->nextadd;
                countn++;
                continue;
            }
            pre=p;
            p=p->next;
        }
	n=countn;
	node* head=new node;
	pre = FinList->next;
	p = pre->next;
	head=FinList;
	int flag=n/k;
	while (flag!=0)
	{
		for (int i = 1; i<k; i++)
		{
			pre->next = p->next;
			p->next = head->next;
			head->next = p;
			p = pre->next;
		}
		head=pre;
		pre = p;
		if(p!=NULL) p = p->next;
		n -= k;
		flag=n/k;
	}
	pre = FinList->next;
	p=pre->next;
	int m=countn-n;
	int mo=0;
	while (pre != NULL)
	{
	    if(mo<m&&p!=NULL) pre->nextadd=p->prevadd;
	    if(p==NULL) pre->nextadd=-1;
	    printf("%05d %d ",pre->prevadd,pre->data);
		if (p!=NULL)
            printf("%05d\n",pre->nextadd);
		else
            printf("%d\n",pre->nextadd);
		pre=p;
		if(p!=NULL)
        {
            p = p->next;
        }
		mo++;
	}
	return 0;
}

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值