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

链表的翻转是程序员面试中出现频度最高的问题之一 非递归(迭代)方式   迭代的方式是从链头开始处理,如下图给定一个存放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; }

经验分享 程序员 微信小程序 职场和发展