链表翻转的图文讲解(递归与迭代两种实现)

链表的翻转是程序员面试中出现频度最高的问题之一
非递归(迭代)方式 
  迭代的方式是从链头开始处理,如下图给定一个存放5个数的链表。


这里写图片描述


  首先对于链表设置两个指针:


这里写图片描述


  然后依次将旧链表上每一项添加在新链表的后面,然后新链表的头指针NewH移向新的链表头,如下图所示。此处需要注意,不可以上来立即将上图中P->next直接指向NewH,这样存放2的地址就会被丢弃,后续链表保存的数据也随之无法访问。而是应该设置一个临时指针tmp,先暂时指向P->next指向的地址空间,保存原链表后续数据。然后再让P->next指向NewH,最后P=tmp就可以取回原链表的数据了,所有循环访问也可以继续展开下去。


这里写图片描述


  指针继续向后移动,直到P指针指向NULL停止迭代。


这里写图片描述


  最后一步:


这里写图片描述


非递归实现的程序

struct ListNode* reverseList(struct ListNode* head) {
    if(head==NULL||head->next==NULL)
        return head;
    
    struct ListNode *p=head;    //头节点给*P
    struct ListNode *newhead=NULL;
    while(p!=NULL)
    {
        struct node *tmp=p->next;  //暂存p的下一个地址
        {
            p->next=newhead;   //新链尾:p->next指向前一个空间
            newhead=p;        //新链表的头移动到p,扩长一步链表
            p=tmp;              //节点后移 p=p->next;
        }
    }
   return newhead;        
}

 

你可能感兴趣的:(链表翻转的图文讲解(递归与迭代两种实现))