链表逆转的一个算法

今天想到一个链表逆转的简单算法,向大家介绍一下。

链表的定义大家都十分熟悉,我们不再累述。链表分文单链表和双向链表,谈到链表逆转,这里仅仅需要考虑单链表即可。因为双向链表的每个节点都有指向其前驱和后继的指针,用不到对其逆转。

如下图表示的单链表:

只需要额外定义三个临时节点指针,分别为crrt, pretail crrt表示当前节点指针,pre表示前节点的前驱节点,tail表示当前节点后继节点指针。

算法思想分两个关键点,1 crrt为当前要逆转的节点,要把crrtnext指针从指向tail改为指向pre,所以要先用pre记录下crrt的前驱节点,crrt->next=pre就完成了当前节点的指针逆转,2 这一步骤完成之后,crrt节点需要向后移动,如果crrt->next的值没变,仍然指向其后继节点,那么向后移动节点我们可以使用crrt=crrt->next的方法,但是现在crrt->next已经改变成了指向前驱的指针,所以我们要用另一个tail指针指向crrt->next,向后移动当前指针,只需要crrt=tail即可。这样就完成了向后移动节点的工作。

算法复杂分析,首先来分析空间复杂度,上面也已经说的很清楚,只需要三个辅助的节点空间即可,不需要其他额外空间,所以时间复杂度为O(1)。然后再分析空间复杂度,三个指针一同从链表头到尾移动一趟,逆转的操作就可完成,所以时间复杂度为O(n)

从理论上分析链表逆转的时间复杂度,最低也是O(n),因为要完成链表逆转,需呀对每个节点操作一次,对链表的每个节点都遍历一次的时间复杂度就是O(n)。所以本算法已经达到了最低的时间复杂度。如果有哪个朋友还有更简便的算法,希望不吝赐教。

算法的完整code

typedef struct strlink{

char data;

struct strlink *next;

}strlink;

/* function name:translate, translate the string

param: the string that to be translate

return value: the list that have been translated

*/

strlink* translate( strlink* s)

{

    static strlink* rtn;

    if(NULL==s||NULL==s->next)

    return NULL;

    strlink *pre, *now, *tail;

    now=s;

    tail=now->next;

    //pre=now;

    //pre->next=NULL;

    while(NULL!=tail)

    {

    pre=now;

    now=tail;

    tail=now->next;

    now->next=pre;

    }

    pre=s;

    pre->next=NULL;

    s=now;

    rtn=now;

    return rtn;

}

 

       

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值