02-线性结构2 Reversing Linked List

时间:2023-03-07 15:46:38

由于最近学的是线性结构,且因数组需开辟的空间太大。因此这里用的是纯链表实现的这个链表翻转。

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(<= 10^5​​) 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 NN 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 Nextis 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

 #include <stdio.h>
#include <stdlib.h> typedef struct Node
{
int address;
int data;
int nextAddress;
struct Node *next;
}Node;
typedef struct Node *LinkList; int main()
{
//排序前
LinkList L1, p1, q1;
L1 = (LinkList)malloc(sizeof(Node)); //创建头指针
L1->next = NULL;
int firstAddress;
int N, K;//N为总结点数 K为需翻转的数
scanf("%d %d %d", &firstAddress, &N, &K);
p1 = L1;
for(int i = ; i < N; i++) {
q1 = (LinkList)malloc(sizeof(Node));
scanf("%d %d %d",&q1->address, &q1->data, &q1->nextAddress);
p1->next = q1;
p1 = q1;
}
p1->next = NULL; // //测试没问题
// printf("测试1 :\n");
// p1 = L1->next;
// while(p1){
// printf("%05d %d %d\n", p1->address, p1->data, p1->nextAddress);
// p1 = p1->next;
// } //排序后
LinkList L2, p2;
L2 = (LinkList)malloc(sizeof(Node)); //创建头指针
L2->next = NULL;
int count = ;
int findAddress = firstAddress;
p2 = L2;
while(findAddress != -) { //while(count < N) {有多余结点不在链表上没通过 q1 = L1;
while(q1->next) {
if(q1->next->address == findAddress) {
p2->next = q1->next;
q1->next = q1->next->next;
p2 = p2->next;
count++;
// printf("count = %d\n",count);
findAddress = p2->nextAddress;
// printf("findAddress = %d\n",findAddress);
}else {
q1 = q1->next;
}
}
}
p2->next = NULL; // //测试没问题
// printf("测试2 :\n");
// p2 = L2->next;
// while(p2){
// printf("%05d %d %05d\n", p2->address, p2->data, p2->nextAddress);
// p2 = p2->next;
// }
//Reversing
LinkList L3, p3, q3, tail;
L3 = (LinkList)malloc(sizeof(Node)); //创建头指针
L3->next = NULL;
//将L2以头插法插入L3
int n = count; //防止有多余结点影响 n=N 会影响
int k = K;
p3 = L3;
p2 = L2;
while(n >= k) {
n -= k;
for(int i = ; i < k; i++) {
p3->next = p2->next;
p2->next = p2->next->next;
if(i == )
tail = p3->next;
else
p3->next->next = q3;
q3 = p3->next;
}
p3 = tail;
}
p3->next = L2->next; p3 = L3->next;
while(p3->next) {
printf("%05d %d %05d\n",p3->address, p3->data, p3->next->address);//不到五位数用0补全
p3 = p3->next;
}
printf("%05d %d -1\n",p3->address, p3->data);
return ;
}

----------------------------------------陈越老师讲解----------------------------------

02-线性结构2 Reversing Linked List

单链表逆转模板代码

 LinkList Reverse (LinkList head, int K)    //单链表逆转K个结点 且仅一次
{
int cnt = ; //用于计数已逆转的结点数
LinkList new_ = head->next;
LinkList old = new_->next;
LinkList tmp;
while(cnt < K) {
tmp = old->next; //用于old结点逆转后 记录未逆转链表的头结点
old->next = new_; //逆转
new_ = old; //向后移位
old = tmp; //向后移位
cnt++; //逆转节点+1
}
head->next->next = old;
return new_; //新的头结点
}