PAT Advanced 1074 Reversing Linked List (25) [链表]

题目

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

题目分析

已知N个结点,以K为步长,反转链表

解题思路

  1. 定义结点,使用数组存储N个结点,使用order属性记录链表中结点出现序号
  2. 将链表分为n/k个段,对每个段进行反转
    2.1 每个节点的next即为反转后的下一个结点地址
    2.2 每个段最后一个节点的特殊处理:next为下一个段反转前最后一个结点
    2.3 最后一个段的处理
    • 若n%k==0,说明n可以正好分为n/k个段,最后一个段反转,并将最后一个节点置为-1
    • 若n%k!=0,说明最后一段小于k,开始下标为n/k*k,不需要反转,顺序打印,并将最后一个结点置为-1

知识点

  1. 将n个结点分为n/k个段,最后一段开始下标为n/k*k(下标从0开始)
  2. 链表反转,不一定非要对链表进行反转(即:更换每个结点next值),可以使用本题思想反向打印的办法

Code

#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=100010;
struct node {
	int adr;
	int data;
	int next;
	bool flag=false;//初始化为false
	int order=maxn;
} nds[maxn];
bool cmp(node &n1,node &n2) {
	return n1.order<n2.order;
}
int main(int argc,char *argv[]) {
	int hadr,n,k,adr;
	scanf("%d %d %d",&hadr,&n,&k);
	for(int i=0; i<n; i++) {
		scanf("%d",&adr);
		scanf("%d %d",&nds[adr].data,&nds[adr].next);
		nds[adr].adr=adr;
	}
	int count=0;
	for(int i=hadr; i!=-1; i=nds[i].next) {
//		nds[i].flag=true;
		nds[i].order=count++;
	}
	sort(nds,nds+maxn,cmp);
	n=count;
//	for(int i=0; i<n; i++) {
//		printf("%05d %05d %05d\n",nds[i].adr,nds[i].data,nds[i].next);
//	}
	for(int i=0; i<n/k; i++) {
		for(int j=(i+1)*k-1; j>i*k; j--) {
			printf("%05d %d %05d\n",nds[j].adr,nds[j].data,nds[j-1].adr);
		}
		printf("%05d %d",nds[i*k].adr,nds[i*k].data);
		if(i<n/k-1) {
			printf(" %05d\n",nds[(i+2)*k-1].adr);
		} else {
			if(n%k==0)printf(" -1\n"); //正好可以分为n/k块,并且打印最后一块
			else {
				printf(" %05d\n",nds[(i+1)*k].adr);
				for(int j=n/k*k; j<n; j++) {
					printf("%05d %d",nds[j].adr,nds[j].data);
					if(j<n-1)printf(" %05d\n",nds[j+1].adr);
					else printf(" -1\n");
				}
			}
		}
	}
	return 0;
}
posted @ 2020-02-11 21:10  JamieHou  阅读(91)  评论(0编辑  收藏  举报