掌握链表(二)——LeetCode206.反转链表

反转链表

题目描述

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
题目来源
思路一、
把链表的的每个链接的方向取反
在这里插入图片描述
要使两个结点之间的指针指向反转,看似用两个变量足矣,直接让后一个结点指向前一个结点。但是仔细思考后发现并没有那么简单,我们如果直接让后一个结点指向前一个结点,那么后一个结点所指向的再后面一个结点的位置就无从知晓了。所以,我们还得定义3个指针变量:n1,n2,n3 。
1)初始条件
n1=NULL
n2=head
n3=head->next
在这里插入图片描述
2)翻转核心逻辑
1.n3 用来记录n2下个结点,
2.改变n2的指针域,之前指向n3,现在指向n1,
![在这里插入图片描述](https://img-blog.csdnimg.cn/4d4c05a9f475453385dfdde5a19c4e97.png
在这里插入图片描述
3)迭代条件(n1,n2,n3向后挪动一位)
n1=n2
n2=n3;
n3=n3->next;
在这里插入图片描述
4)结束条件
n2==NULL;
在这里插入图片描述

代码的实现一、

// 方法一、  
//             链表换方向
struct ListNode* reverseList2(struct ListNode* head) {
        //如果链表没结点或只有一个结点,无需处理,返回头指针
    if (head == NULL || head->next == NULL)
    {
        return head;
    }
    struct ListNode* n1 = NULL;
    struct ListNode* n2 = head;
    struct ListNode* n3 = head->next;
    while (n2)
    {
        n2->next = n1;
        n1 = n2;
        n2 = n3;
        if (n3)
            n3 = n3->next;
    }
    return n1;
}

思路二、头插法

创建一个新链表头,然后把旧链表的结点,挨个挨个头插到新链表中
1)初始化
新链头 newhead
cur 指向头插结点
next 记录下一个头插结点
cur=head;
newhead=NULL;
next=head->next;

在这里插入图片描述
2)翻转逻辑
让cur的指针域指向新链头
在这里插入图片描述
3)迭代条件
newhead=cur
cur=next
next=next->next;
注意:在迭代时,如果next==NULL,接下来next无需迭代了
在这里插入图片描述
4)结束条件
cur==NULL;
在这里插入图片描述

代买实现二、

struct ListNode* reverseList(struct ListNode* head){

   if(head==NULL||head->next==NULL)
   {
       return head;
   }
  // 初始化
    struct ListNode *cur=head;
    struct ListNode *newhead=NULL;
    struct ListNode *next=head->next;
    //
    while(cur)
    {
        cur->next=newhead;
        newhead=cur;
        cur=next;
        if(next!=NULL)
        next=next->next; 

    }
    return newhead;

}

思路三、

两两交换数据域,
在这里插入图片描述
初始化:
头和尾
通过计算链表的长度,就可以用循环来控制,尾
方法很简单,但是写起来不那么容易

struct ListNode* reverseList1(struct ListNode* head) {

    if (head == NULL)
    {
        return head;
    }
    int count2 = 0;
    int count3 = 0;//3
    int count = 0;//0

//计算链表长度
    struct ListNode* tail = head;
    while (tail->next)
    {
        tail = tail->next;
        count++;
    }
    int count4 = count / 2 + 1;
    while (count4--)
    {
        struct ListNode* cur = head;
        struct ListNode* tail2 = head;
        //计算左边链表
        count2 = count3;
        while (count2--)
        {
            cur = cur->next;
        }
        count3++;
        // 计算右边链表
        int tail2i = count;
        while (tail2i--)
        {
            tail2 = tail2->next;
        }
        count--;


        if (tail2 == cur || cur->next == NULL)
        {
            return head;
        }
        int tmp = cur->val;
        cur->val = tail2->val;
        tail2->val = tmp;
    }

    return head;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

2023框框

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值