反转链表
遇过两种第一种是leetcode上的链表反转:
206:反转链表 https://leetcode-cn.com/problems/reverse-linked-list/A->B->C->D
ListNode *p = head, *q, *tmp = NULL;
while(p){
q = p;
p = p->next;
q->next = tmp;
tmp = q;
}
return tmp;
这个一共分为三个步骤:
两个临时变量指针,其中一个作为最后答案返回,令q = p,p直接往后遍历,
然后q->next = tmp,再把tmp往前,这一步实际就是在实现反转。最后p遍历结束就全部反转完成。
第二种是pat上面的,给定了地址和next还有值的链表,这种将地址作为一种索引,从第一个结点开始遍历,形成一个完整的路径,然后反转索引的值,用索引表示出值和next
pat乙级1025 https://pintia.cn/problem-sets/994805260223102976/problems/994805296180871168
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
代码
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 100010;
int n, k;
int e[N], ne[N], h;
int link[N];
// 从a -> b建立一条边, 尾插法
void add(int a, int b, int c)
{
e[a] = c, ne[a] = b;
}
int main()
{
cin >> h >> n >> k;
for(int i = 0; i < n; i ++ )
{
int a, b, c;
cin >> a >> b >> c;
add(a, c, b);
}
//可能存在单独结点,所以从头结点开始遍历,将所有与头节点相连接的结点取出来
int cnt = 0;
while(h != -1)
{
link[cnt ++ ] = h;
h = ne[h];
}
//因为共有cnt个数,有k个数要翻转,所以是<=
for(int i = 0; i + k <= cnt; i += k) reverse(link + i, link + i + k);
for(int i = 0; i < cnt; i ++ )
if(i != cnt - 1) printf("%05d %d %05d\n", link[i], e[link[i]], link[i + 1]);
else printf("%05d %d -1\n", link[i], e[link[i]]);
return 0;
}