单链表的就地逆置有多种方法,这里说说迭代与递归
迭代
其中使用了头插法
void converse(Linklist *head)
{
Linklist *p1,*p2;
p1=head->next;
head->next=NULL;
while(p1)
{
p2=p1;
p1=p1->next;
p2->next=head->next; //头插
head->next=p2;
}
}
不知道为什么,这个算法在一些OJ上会超时,以下还有一种算法采用的时同样的思路:
List Reverse( List L ){
List p,q;
p=L;
L=NULL;
while(p){
q=p;
p=p->Next;
q->Next=L;
L=q;
}
return L;
}
递归
将链表分为当前表头节点和其余节点,递归的思想就是,先将当前的表头节点从链表中拆出来,然后对剩余的节点进行逆序,最后将当前的表头节点连接到新链表的尾部
递归终止条件就是链表只剩一个节点时直接返回这个节点的指针。可以看出这个算法的核心其实是在回朔部分,递归的目的是遍历到链表的尾节点,然后通过逐级回朔将节点的next指针翻转过来
void converse(Linklist *head)
{
struct ListNode *newhead;
if(head==NULL)
return NULL;
if(head->next==NULL)
return head;
newhead=reverseList(head->next); //递归
head->next->next=head; //回溯部分
head->next=NULL;
return newhead;
}