链表——逆序/反转

究竟要如何反转呢?我们不妨拿一个例子来说明一下算法。

我先画一个单链表,这个单链表有4个元素。我的思路就是,每次把第二个元素提到最前面来。比如下面是第一次交换,我们先让头结点的next域指向结点a2,再让结点a1的next域指向结点a3,最后将结点a2的next域指向结点a1,就完成了第一次交换。

第一次交换
  • 然后进行相同的交换将结点a3移动到结点a2的前面,然后再将结点a4移动到结点a3的前面就完成了反转。
第二次交换
第三次交换
  • 思路有了,那就可以写代码了。这里我们需要额外的两个工作指针来辅助交换。这个下面的步骤慢慢理解下,结合图片。注意结点之间的关系要先断再连。

步骤:

  1. 定义当前结点 current,初始值为首元结点,current = L->next;
  2. 定义当前结点的后继结点 pnext, pnext = current->next; 
  3. 只要 pnext 存在,就执行以下循环:
    • 定义新节点 prev,它是 pnext的后继结点,prev = pnext->next;
    • 把pnext的后继指向current, pnext->next = current;
    • 此时,pnext 实际上已经到了 current 前一位成为新的current,所以这个时候 current 结点实际上成为新的 pnext,current = pnext;
    • 此时,新的 current 就是 pnext,current = pnext;
    • 而新的 pnext 就是 prev,pnext = prev;
  4. 最后将头结点与 current 重新连上即可,L->next = current;

函数设计如下:

/*单链表反转/逆序 */

02StatusListReverse(LinkList L)

03{

04   LinkList current,pnext,prev;

05    if(L == NULL || L->next == NULL)

06       return L;

07    current = L->next;  /* p1指向链表头节点的下一个节点 */

08    pnext = current->next;

09    current->next = NULL;

10    while(pnext)

11    {

12        prev = pnext->next;

13        pnext->next = current;

14        current = pnext;

15        pnext = prev;

16        printf("交换后:current = %d,next = %d\n",current->data,current->next->data);

17    }

18       L->next = current;  /* 将链表头节点指向p1 */

19    return L;

20}

理解要点:

1、  current->next = NULL; 先断开,然后再连;

2、每次循环的时候,把下一个节点(Pnext)移动到最前面,然后将Pnext指向下一个即将移动的节点。



参考:http://www.nowamagic.net/librarys/veda/detail/2241


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值