今天课间的时候偶然看到了一个面试题:单链表的逆置,看了题解感觉乖乖的,貌似和以前看的版本不搭,于是重新进行了一番探究
单链表的逆置分为两种方法:头插法和就地逆置法,这两种方法虽然都能够达到逆置的效果,但还是有着不小的差别
头插法
算法思路:依次取原链表中的每一个节点,将其作为第一个节点插入到新链表中,指针用来指向当前节点,p为空时结束。
核心代码
void reverse(node*head) { node*p; p=head->next; head->next=NULL;while(p) { q=p; p=p->next; q->next=head->next; head->next=q; } }
以上面图为例子,说白了就是不断的将1后面的节点插入到head后面,即为头插法
完整代码
View Code
程序截图
就地逆置法
//单链表定义 typedefstruct ListNode{ int m_nValue; ListNode* pNext; };
//单链表逆置实现
ListNode* ReverseList(ListNode* pHead) {if (pHead == NULL || pHead->pNext == NULL) { retrun pHead; } ListNode* pRev = NULL; ListNode* pCur = pHead;while(pCur != NULL) { ListNode* pTemp = pCur;// 步骤① pCur = pCur->pNext;// 步骤② pTemp->pNext = pRev;// 步骤③ pRev = pTemp; }return pRev; }
链表的翻转是程序员面试中出现频度最高的问题之一,常见的解决方法分为递归和迭代两种。最近在复习的时候,发现网上的资料都只告诉了怎么做,但是根本没有好好介绍两种方法的实现过程与原理。所以我觉得有必要好好的整理一篇博文,来帮忙大家一步步理解其中的实现细节。
我们知道迭代是从前往后依次处理,直到循环到链尾;而递归恰恰相反,首先一直迭代到链尾也就是递归基判断的准则,然后再逐层返回处理到开头。总结来说,链表翻转操作的顺序对于迭代来说是从链头往链尾,而对于递归是从链尾往链头。