原题:1074. Reversing Linked List (25)
解题思路:
构造双链表。主要在原链表中加入一个pre表示前一个节点,反转只要将next与pre互换即可,当然首尾需要特殊处理。
代码如下:
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 100000;
struct Node
{
int data, ad;
int pre, next;
} node[maxn];
int rev(int st, int k, int pre) //部分反转
{
int n_st, p = st;
for(int i = 0; i < k-1; i++)
p = node[p].next;
n_st = p;//记录第k个节点
int q = node[p].next;//记录第k个节点的下一个节点
for(int i = 0; i < k-1; i++)
{
swap(node[p].pre, node[p].next);
p = node[p].next;
}
//当前p已经回到st位置
node[p].pre = node[p].next;//处理原头节点
node[p].next = q;
node[n_st].pre = pre;//处理原尾节点
return n_st;//返回反转后的头节点
}
int main()
{
int st, n, k;
while(scanf("%d%d%d", &st, &n, &k) == 3)
{
for(int i = 0; i < n; i++)
{
int data, ad, next;
scanf("%d%d%d", &ad, &data, &next);
node[ad].ad = ad;
node[ad].next = next;
node[ad].data = data;
}
int n_e = 0;//记录有效节点数
for(int p = st; p != -1; p = node[p].next)
{
n_e++;
if(p == st) node[p].pre = -1;
if(node[p].next != -1)
node[node[p].next].pre = p;
}
int rnd = n_e/k; //计算进行几轮反转
int n_st;
for(int i = 0; i < rnd; i++)
{
if(i == 0) n_st = rev(st, k, -1);
else
{
int pre = st;
st = node[st].next;//上一次的起点变为终点
node[pre].next = rev(st, k, pre);
}
}
for(int p = n_st; p != -1; p = node[p].next)
{
printf("%05d %d ", node[p].ad, node[p].data);
if(node[p].next == -1) printf("-1\n");
else printf("%05d\n", node[p].next);
}
}
return 0;
}