链表——反转链表

目录

头插法反转链表

算法说明

算法实现

算法代码

迭代法反转链表

算法说明

算法实现

算法代码

递归法反转链表

算法说明

算法实现

 算法代码

就地逆置法反转链表

算法说明

算法实现

​算法代码


头插法反转链表

算法说明

在原有链表的基础上,依次将位于链表头部的节点摘下,然后采用从头部插入的方式生成一份新的链表。

算法实现

1、创建一个新的空链表

2、原链表中摘下头部节点,从新链表头部插入

3、重复操作

算法代码


struct ListNode* ReverseList(struct ListNode* head ) {
        struct    ListNode*    next=NULL;
        struct    ListNode*    new_head=NULL;
        if (head == NULL || head->next == NULL)     // 空链或只有一个结点,直接返回头指针
        {
            return head;
        }
        while(head!=NULL)
        {
            next=head->next;
            head->next=new_head;
            new_head=head;
            head=next;
        }
    return new_head;
}

迭代法反转链表

算法说明

从当前的首源节点开始,一直遍历值链表的最后一个节点,这期间会逐个改变遍历到的节点的指针指向,使其指向前驱。

算法实现

借助三个指针来实现指针的变向beg,mid,end。

1、改变mid的指针指向,指向beg

2、将三个指针整体后移一个节点

 

 3、循环上述过程

 5、mid已经指向了最后一个节点,但是反转未完成,需要再次修改mid的指向,

 6、head指针指向与mid相同

算法代码

struct ListNode* ReverseList(struct ListNode* head ) {
        struct    ListNode*    beg=NULL;
        struct    ListNode*    mid=head;
        struct    ListNode*    end=head->next;
        if (head == NULL || head->next == NULL)     // 空链或只有一个结点,直接返回头指针
        {
            return head;
        }
        while(1)
        {
            //修改mid节点
            mid->next=beg;
            //判断是否结束迭代
            if(end==NULL)
            {
                break;
            }
            //三个指针依次后移
            beg=mid;
            mid=end;
            end=end->next;
        }
            //将头节点指向mid
            head=mid;
            return head;
}


递归法反转链表

算法说明

从链表的尾节点开始,一次向前遍历,遍历过程一次改变各节点的指向,指向它的前驱。

算法实现

1、一直递归,找到链表的最后一个节点

2、逐层退出时,new_head指向不变,一直指向原链表中的最后一个节点

3、递归每退出一层,函数中的head指针的指向都会发生改变,指向前驱

4、每退出一层,都需要改变head->next的指向,同时令head所指节点的指针域为NULL

5、每一层递归结束后,将新的头指针返回给上一层

 算法代码

struct ListNode* ReverseList(struct ListNode* head ) {
        struct    ListNode*    new_head=NULL;
        if (head == NULL || head->next == NULL)     // 空链或只有一个结点,直接返回头指针
        {
            return head;
        }

        else
        {
        //一直递归,找到链表中最后一个节点
            new_head = ReverseList(head->next);
            head->next->next = head;
            head->next = NULL;
            return new_head;
        }
}

就地逆置法反转链表

算法说明

与头插法类似,区别在于头插法通过建立一个新链表实现,逆置法直接对原链表作出修改,借助两个指针实现。

算法实现

1、初始状态,令beg指向第一个的开始节点,end指向beg->next

 2、将end节点摘除,添加到新链表的头部

3、将end指向beg->next,然后将end所指节点摘除并且添加到当前头部

 

 算法代码

struct ListNode* ReverseList(struct ListNode* head ) {
        struct    ListNode*    beg=NULL;
        struct    ListNode*    end=NULL;
        if (head == NULL || head->next == NULL) // 空链或只有一个结点,直接返回头指针
        {
            return head;
        }
        else
        {
        //beg和end指针指向相应的head和head->next
            beg=head;
            end=head->next;
            while(end!=NULL){
        //摘下节点
            beg->next=end->next;
        //将节点添加到表头
            end->next=head;
            head=end;
            end=beg->next;
            }
        }
        return head;
}

参考链接:单链表反转详解(4种算法实现) (biancheng.net) 

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
链表的原地反转是一种常见的链表操作,它可以通过改变链表节点之间的指针来实现链表的反转。原地反转链表的方法有多种,其中一种常见的方法是使用两个指针对链表进行调整,从而达到反转的效果。即通过改变节点的next指针的指向,将链表的方向翻转。 在原地反转链表的过程中,可以使用三个指针来进行操作。首先,设定一个指针pre指向当前节点的前一个节点,一个指针cur指向当前节点,一个指针next指向当前节点的后一个节点。 具体的原地反转链表的步骤如下: 1. 初始化pre为None,cur为链表的头节点。 2. 使用一个循环遍历链表,直到cur为None。 3. 在循环中,首先将next指针指向cur的下一个节点,以便在后面的操作中能够访问到该节点。 4. 将cur的next指针指向pre,即将当前节点的指针翻转。 5. 将pre指针指向cur,将cur指针指向next。 6. 重复步骤3-5,直到遍历完整个链表。 通过以上步骤,就可以实现链表的原地反转。这种方法的空间复杂度为O(1),即只需要常数级别的额外空间。 引用提供了一个模型来说明整个链表的反转过程,引用中的图片也展示了通过四个步骤来实现链表的反转。这些方法都可以帮助我们更好地理解和实现链表的原地反转操作。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值