数据结构线性结构 —— 编程作业 03 :Reversing Linked List
Posted 大彤小忆
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构线性结构 —— 编程作业 03 :Reversing Linked List相关的知识,希望对你有一定的参考价值。
题目描述: 给定一个常数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。
输入格式: 每个输入文件包含一个测试用例。
对于每种情况,第一行包含第一个结点的地址,结点的总数为
N
N
N(
⩽
1
0
5
\\leqslant10^{5}
⩽105),要反转的子列表的长度为K(
⩽
N
\\leqslant N
⩽N)。结点的地址为5位非负整数,NULL用-1表示。
接着是
N
N
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<iomanip>
using namespace std;
#define MAXSIZE 100005
typedef int ElementType;
typedef struct node {
ElementType data;
ElementType next;
} Node;
//反转链表函数,每K个结点,反转一下
int reverList(Node list[], int K, int head, int N)
{
int flag = 1;
int last_head; //用于记录上一次反转后,子链表的最后结点地址
//待与下一次反转的子链表的头部相连
int rev_head = head;//下一次待反转子链表的头结点地址
int mid_head = head;//反转过程中的中间结点地址
int mid_next; //反转过程中的中间结点地址
while (N - K >= 0)//当剩余结点不够K个时,则不再反转
{
N -= K;
//反转子链表
for (int i = 0; i < K - 1; i++)
{
mid_next = list[rev_head].next;
list[rev_head].next = list[mid_next].next;
list[mid_next].next = mid_head;
mid_head = mid_next;
}//反转子链表
//从第二次开始,需要把这次反转后的子链表的头结点连接到上一段的尾部
if (flag == 0)
{
list[last_head].next = mid_head;
}
//记录第一次反转后的头结点,作为最终List的头结点并返回
if (flag)
{
head = mid_head;
flag = 0;
}
last_head = rev_head;
rev_head = list[rev_head].next;//下次开始的头结点地址
mid_head = rev_head;
}
return head;
}
void printList(Node list[], int head)
{
int next = head;
while (list[next].next != -1)
{
cout << setw(5) << setfill('0') << next << " " << list[next].data << " " << setw(5) << setfill('0') << list[next].next << endl;
next = list[next].next;
}
cout << setw(5) << setfill('0') << next << " " << list[next].data << " " << list[next].next << endl;
}
int main()
{
int Head, N, K; //Head为第一个结点的地址,N为结点的总数,K为要反转的子列表的长度
cin >> Head >> N >> K;
Node list[MAXSIZE];
int i, Address, Data, Next; //Address是结点的位置,Data是一个整数,Next是下一个结点的位置
for (i = 0; i < N; i++)
{
cin >> Address >> Data >> Next;
list[Address].data = Data;
list[Address].next = Next;
}
int next = Head;
int num = 1;//所给数据结点并不都是链表中的结点,用于计数真正的结点个数
while (list[next].next != -1) {
num++;
next = list[next].next;
}
if (K > 1) //如果是1,则不需要反转,原序输出
Head = reverList(list, K, Head, num);
printList(list, Head);
system("pause");
return 0;
}
测试: 输入样例的测试效果如下图所示。
以上是关于数据结构线性结构 —— 编程作业 03 :Reversing Linked List的主要内容,如果未能解决你的问题,请参考以下文章
数据结构线性结构 —— 编程作业 04 :Pop Sequence