您的位置:首页 > 其它

将一个链表按逆序排列,即将链头当链尾,链尾当链头。

2013-10-27 18:01 274 查看
STU *invert(STU *head){
STU *new_head=NULL,*p1,*p2,*new;
do{
for(p1=head;p1->next!=NULL;p1=p1->next)
p2=p1;
if(new_head==NULL)
{
new_head=p1;
new_head->next=p2;
}
else
{
new->next=p2;
}
new=p2;
p2->next=NULL;
}while(head->next!=NULL);
return new_head;
}


完整的代码我就不贴了,只贴用来进行逆序的函数。链表的新建和输出在前面的博客里可以找到。

谭浩强答案书上的答案可能是印刷错误,调试不出答案,我揣摩答案的思路重新整理了一下函数。

算法的思路是这样的:

第1次循环:

  找到链表的最后一个结点p1和倒数第二个结点p2;

  把p1当作新链头(Line 8),p2当作新链的第二个结点(Line 9),也是新链中最新的结点(Line 15);

  把原来链表的最后一个结点删去(Line 16)。

  这次循环完成之后,原来链表的结点少了一个,新链表的结点多了两个。

第2次循环:

  找到链表的最后一个结点p1和倒数第二个结点p2,此时的p1是原先的倒数第二个结点,p2是原先的倒数第3个结点;

  把p2连接在新链表的后面(Line 13),此时p2是新链中最新的结点(Line 15);

  再从原来的链表删去一个结点(Line 16)。

  这次循环完成之后,原来链表的结点少了一个,新链表的结点多了一个。

……

从第2次循环开始,每次是把链表中的倒数第二个结点加入到新链中。当head->next==NULL时,链表中只有一个结点,没有倒数第二个结点,所以循环结束,新链表已经产生。最后一次循环过程中,p1是指向最初链表的第二个结点,p2指向最初链表的头结点,把p2加入到新链中,同时使p2->next=NULL,成为新链的链尾。

如果知道链表的长度len的话,可以用以下更容易理解的代码:

STU *invert(STU *head){
STU *new_head=NULL,*p1,*p2,*new;
int i;
for(i=0;i<len;i++)
{
p2=head;
for(p1=head;p1->next!=NULL;p1=p1->next)
p2=p1;
if(new_head==NULL)
new_head=p1;
else
new->next=p1;
new=p1;
p2->next=NULL;
}
return new_head;
}


循环len次,每次把链表末尾的结点加入到新链表。Line 6的目的是预防链表中只有一个结点时,p2的值为不确定的值的情况。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐