今日总算弄懂了关于单链表就地转置的问题!
仍是在面试的时分遇到过的这个问题。尽管标题没说就地转置(也便是所谓的使用现有结点),但要求肯定是这样的。所以用附加结点写的答案可想而知是不令人满意的。
其时的主意是把整个单链表从尾到头的整个转置,才会想到要附加原单链表结点个数的结点空间。今日发现了别的一种办法,便是分段转置的办法。
例如:A->B->C->D->E->F->G->^ (^表明完毕,即NULL)
在要求不附加结点空间的时分转置,可这样完成:A->^,B->A,C->B,D->C,E->D,F->E,G->F
按这种要求,即可用如下代码:
node *reverse(node *head)
{
node *temp1,*temp2,*temp3;
if((!head)||(!(head->next))) //链表为空,则回来,链表只要一个结点的话,转置即为自身,也只需回来自身
return head;
temp1=head;
temp2=temp1->next;
temp3=temp2->next;
head->next=NULL;
while(temp3!=NULL)
{
temp2->next=temp1; //temp2->temp1 (A->B段的转置)
temp1=temp2; //temp1,temp2,temp3后移一个结点,持续下一段的转置
temp2=temp3;
temp3=temp3->next;
} //在跳出while()后,并不是一切段都转置完了,当temp3=NULL时,temp2=G temp1=F还没有转置
temp2->next=temp1; //在temp3==NULL时,还应该持续树立一个衔接。
return temp2
}
以上述链表为例:程序开端:temp1=A temp2=B temp3=C A->NULL
在while()中运转第一次后的成果为:B->A temp1=B temp2=C temp3=D
在while()中运转第2次后的成果为:C->B temp1=C temp2=D temp3=E
。。。。。。
。。。。。。
在while()中运转最终一次的成果为:F->E temp1=F temp2=G temp3=NULL
退出while()后再运转一次temp2->next=temp1 成果为:G->F
所以,在履行到return 之前程序运转成果为:temp2=G->F->E->D->C->B->A->^
因而,明显,需求回来的头结点应该是temp2
注:经过剖析程序运转头部,可进行一点改善,即while()循环的参数可用temp2,只要当temp2=NULL时,程序才应该中止转置。而相应的回来则应该为temp1