反转链表

遇过两种第一种是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;
}
posted @ 2022-02-22 16:27  天然气之子  阅读(40)  评论(0编辑  收藏  举报