02-线性结构3 Reversing Linked List

本文介绍了一种算法,用于解决将链表每K个元素进行翻转的问题。通过详细解析输入输出规格,提供了完整的C语言代码实现,包括读取链表、排序、翻转链表以及输出结果等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given a constant K and a singly linked list L, you are supposed to reverse the links of every Kelements 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 (≤) which is the total number of nodes, and a positive K (≤) 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

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 
 4 typedef struct LNode * PtrToLNode;
 5 typedef PtrToLNode position;
 6 struct LNode{
 7     int address;
 8     int data;
 9     int next;
10     position rear;
11 };
12 typedef PtrToLNode List;
13 
14 //读入函数 
15 void readlist( List L, int N){
16     position p = L;
17     while(N--){
18         List temp = (List)malloc(sizeof(struct LNode));
19         temp->rear = NULL;
20         scanf("%d%d%d", &temp->address, &temp->data, &temp->next);
21         p->rear = temp;
22         p = p->rear;
23     }
24 }
25 
26 //排序函数 
27 int sortlist(List L, List L2, int First){
28     position now1 = L, now2 = L2, temp;
29     int Findnode = First, cnt=0;                  //Findnode记录下一个要寻找的node地址,cnt记录在链表中的节点个数 
30     while(Findnode!=-1){
31         while(now1->rear){                        //遍历L,寻找address与Findnode相同的节点
32             if(now1->rear->address==Findnode){    //找到了将其从L中删除,插入到L2中去 
33                 temp = now1->rear;
34                 now1->rear = now1->rear->rear;     
35                 temp->rear = NULL;
36                 now2->rear = temp;
37                 now2 = now2->rear;
38                 Findnode = temp->next;
39                 cnt++;
40                 break;                         
41             }
42             now1 = now1->rear;
43         }
44         now1 = L;                 //更新now1,每一次寻找都要从头遍历l 
45     }
46     return cnt;
47 }
48 
49 //逆转链表函数 
50 void reverselist(List L2, int cnt, int K){
51     //old、new_记录进行逆转的两个节点位置,p1、p2记录要与已逆转链表头尾相连的两个节点位置 
52     position old = L2->rear->rear, new_ = L2->rear, temp, p1 = L2, p2 = L2->rear;
53     if(K==1||cnt==1) return;             //K或者链表长度cnt等于1,不需要逆转,直接返回 
54     while(cnt>=K){
55         cnt -= K;
56         for(int count=1; count<K; count++){
57             temp = old->rear;            //temp记录未逆转链表的头节点
58             old->rear = new_;            //逆转 
59             old->next = new_->address;
60             new_ = old;          //向后移位 
61             old = temp;          //向后移位 
62         }
63         p1->rear = new_;
64         p1->next = new_->address; 
65         p2->rear = old;
66         if(old) p2->next = old->address;    
67         else break;
68         p1 = p2;
69         p2 = p2->rear;
70         new_ = old;
71         old = old->rear;
72     }
73 }
74 
75 //输出函数 
76 void print(List L){
77     position now = L->rear;
78     while(now){
79         if(now->rear==NULL) printf("%05d %d -1\n", now->address, now->data); 
80         else printf("%05d %d %05d\n", now->address, now->data, now->next);
81         now = now->rear;
82     }
83 }
84 
85 //主程序框架 
86 int main( ){
87     List L1, L2;
88     L1 = (List)malloc(sizeof(struct LNode));
89     L1->next = NULL;
90     L2 = (List)malloc(sizeof(struct LNode));
91     L2->rear = NULL;
92     int First, N, k, cnt;             //因为有可能有多余节点不在链表上,用cnt记录在链表上的节点个数 
93     scanf("%d%d%d", &First, &N, &k);
94     readlist(L1, N);
95     cnt = sortlist(L1, L2, First);
96     reverselist(L2, cnt, k);
97     print(L2);
98     return 0;
99 }

 

转载于:https://www.cnblogs.com/shin0324/p/9790322.html

题目描述 给定一个常数 $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 个结点的地址、结点总个数正整数 $N (\le 10^5)$、以及正整数 $K (\le 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 23333 2 33218 输出样例 00000 4 33218 33218 3 12309 12309 1 99999 99999 5 68237 68237 6 23333 23333 2 -1 题目分析 本题需要将链表中每 $K$ 个结点反转,可以采用迭代的方法,每次找到 $K$ 个结点,将这 $K$ 个结点反转,然后将这 $K$ 个结点的前驱结点指向反转后的第一个结点,将反转后的 $K$ 个结点的最后一个结点指向下一个要反转的结点,然后继续进行下一轮反转。 需要注意的是,如果链表长度不足 $K$,则不进行反转。 代码实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值