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

 1 STU *invert(STU *head){
 2     STU *new_head=NULL,*p1,*p2,*new;
 3     do{
 4         for(p1=head;p1->next!=NULL;p1=p1->next)
 5             p2=p1;
 6         if(new_head==NULL)
 7         {
 8             new_head=p1;
 9             new_head->next=p2;
10         }
11         else
12         {
13             new->next=p2;
14         }
15         new=p2;
16         p2->next=NULL;
17     }while(head->next!=NULL);
18     return new_head;
19 }

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

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

算法的思路是这样的:

第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的话,可以用以下更容易理解的代码:

 1 STU *invert(STU *head){
 2     STU *new_head=NULL,*p1,*p2,*new;
 3     int i;
 4     for(i=0;i<len;i++)
 5     {
 6         p2=head;
 7         for(p1=head;p1->next!=NULL;p1=p1->next)
 8             p2=p1;
 9         if(new_head==NULL)
10             new_head=p1;
11         else
12             new->next=p1;
13         new=p1;
14         p2->next=NULL;
15     }
16     return new_head;
17 }

循环len次,每次把链表末尾的结点加入到新链表。Line 6的目的是预防链表中只有一个结点时,p2的值为不确定的值的情况。

原文地址:https://www.cnblogs.com/Camilo/p/3391067.html