题目:输入一个单向链表,输出该链表中倒数第k个结点。链表的倒数第0个结点为链表的尾指针。
链表结点定义如下:
struct ListNode
{
int m_nKey;
ListNode* m_pNext;
};
方法一:这里可以先扫描一遍,得到链表的个数。然后找到正数的第N-K个节点,就是要找到的。
方法二:先将链表逆置,然后偶顺着找第K个节点。
以上的两种方法都要扫描整个链表之后,还要扫描 k 或(n-k)次,第三种方法只需要扫描一次。
方法三:指针追赶
a b c d e f g
0 1 2 3 4 5 6
假设上面一行是内容,下面一行是指针。我们现在要求第倒数2个节点,就是e。定义两个指针ListNode* temp1 ,*temp2,temp1先从头开始扫描,当扫描k个节点之后,就是指向c,这是令temp2指向a。这样两个指针一直往后走,直到temp1为空!
#include <iostream>
struct ListNode
{
int m_nKey;
ListNode* m_pNext;
ListNode();
ListNode(int n);
};
void insert(ListNode** root,int n);
ListNode* findpos(ListNode* root , int k) ;
int main()
{
ListNode* root=NULL;
ListNode* kroot=NULL;
insert(&root,1);
insert(&root,2);
insert(&root,3);
insert(&root,4);
insert(&root,5);
insert(&root,6);
int k = 1 ; //要查找的第k个节点
kroot = findpos(root,1);
system("pause");
return 0;
}
void insert(ListNode** root,int n)
{
ListNode* temp = new ListNode(n) ;
temp->m_pNext = (*root) ;
(*root) = temp ;
}
ListNode::ListNode()
{
m_pNext = NULL ;
}
ListNode::ListNode(int n)
{
m_nKey = n ;
m_pNext = NULL ;
}
ListNode* findpos(ListNode* root , int k)
{
ListNode* temp = root; //记录开始位置
ListNode* temp2 = NULL; //用于遍历
for (int i=0;temp!=NULL;i++)
{
if (temp2 != NULL)
temp2 = temp2->m_pNext ;
if (i==k)
temp2 = root ;
temp = temp->m_pNext ;
}
return temp2;
}