题目:输入一个单向链表,输出该链表中倒数第k个结点。链表的倒数第0个结点为链表的尾指针。(尾节点为倒数第0个节点,有头节点,头节点数据为空,尾节点数据不为空)

链表结点定义如下:

 
  1. struct ListNode  
  2.  {   
  3.     int m_nKey;   
  4.     ListNode* m_pNext;   
  5. };  

思路一:遍历整个链表,找到链表中节点的个数,根据节点个数能够确定倒数第k个节点从头开始数的序号,从而找到倒数第k个节点

 
  1. ListNode *Find(ListNode* head,int k)  
  2. {  
  3.     int num=0;//除去头  节点个数  
  4.     ListNode *now=head;  
  5.     while(now->m_pNext!=NULL)  
  6.     {  
  7.         now=now->m_pNext;  
  8.         num++;  
  9.     }  
  10.     if(num<k)  
  11.         return NULL;  
  12.     now=head;  
  13.     for(int i=0;i<num-k;i++)  
  14.         now=now->m_pNext;  
  15.     return now;  
  16. }  

思路二:如果我们在遍历时维持两个指针,第一个指针从链表的头指针开始遍历,在第k-1步之前,第二个指针保持不动;在第k-1步开始,第二个指针也开始从链表的头指针开始遍历。由于两个指针的距离保持在k-1,当第一个(走在前面的)指针到达链表的尾结点时,第二个指针(走在后面的)指针正好是倒数第k个结点。

 

 
  1. ListNode * Find2(ListNode *head,int k)  
  2. {  
  3.     ListNode *ahead=head;  
  4.     ListNode *after=head;  
  5.     for(int i=0;i<k;i++)  
  6.     {     
  7.         if(ahead->m_pNext!=NULL)  
  8.         ahead=ahead->m_pNext;  
  9.         else 
  10.             return NULL;  
  11.     }  
  12.     while(ahead->m_pNext!=NULL)  
  13.     {  
  14.         ahead=ahead->m_pNext;  
  15.         after=after->m_pNext;  
  16.     }  
  17.     return after;  
  18. }  
  19. void main()  
  20. {  
  21.     ListNode a[7];  
  22.     a[0].m_pNext=&a[1];  
  23.     a[1].m_nKey=1;  
  24.     a[1].m_pNext=&a[2];  
  25.     a[2].m_nKey=2;  
  26.     a[2].m_pNext=&a[3];  
  27.     a[3].m_nKey=3;  
  28.     a[3].m_pNext=&a[4];  
  29.     a[4].m_nKey=4;  
  30.     a[4].m_pNext=&a[5];  
  31.     a[5].m_nKey=5;  
  32.     a[5].m_pNext=&a[6];  
  33.     a[6].m_nKey=6;  
  34.     a[6].m_pNext=NULL;  
  35.     cout<<Find(&a[0],1)->m_nKey<<endl;