您的位置:首页 > 其它

查找链表中倒数第k个结点

2012-10-25 19:14 483 查看
题目:输入一个单向链表,输出该链表中倒数第k个结点。链表的倒数第0个结点为链表的尾指针。链表结点定义如下:

struct ListNode
  {
  int m_nKey;
  ListNode* m_pNext;
  };

两个方法,第一个先遍历,获得链表总共的长度,这样就知道从head到达倒数第k个需要移动多少次,从头在移动一遍。

第二个,两个指针,第二个比第一个多移动k次之后,两个指针再一起移动,这样两个指针之间始终有k个距离,当第二个指针移动到NULL的时候,第一个指针所指向的就是倒数第K个。代码如下:

template <typename T>
struct ListNode
{
T m_key;
ListNode* next;
};

void createList(ListNode<int>* &pHead)
{
pHead = new ListNode<int>;
pHead->m_key= 0;
pHead->next = NULL;
ListNode<int>* p = pHead;
for(int i=1; i<10; i++)
{
ListNode<int>* pNewNode = new ListNode<int>;
pNewNode->m_key = i;
pNewNode->next = NULL;
p->next = pNewNode;
p = pNewNode;
}
}

void destoryList(ListNode<int>* pHead)
{
assert(pHead!=NULL);
ListNode<int>* pNext = pHead->next;
while(pNext != NULL)
{
delete pHead;
pHead = pNext;
pNext = pHead->next;
}
delete pHead;
pHead = NULL;
return;
}

//找到倒数第K个节点,最后一个节点为倒数第一个
ListNode<int>* FindKthTail1(ListNode<int>* pHead, int k)
{
assert(pHead != NULL);
// 先获得链表的长度
int length = 0;
ListNode<int>* p = pHead;
while(p!= NULL)
{
length++;
p = p->next;
}
assert(length>=k);
p = pHead;
// 在从头移动 length-k次就好了
for(int i=0; i<length-k; i++)
p = p->next;
return p;
}

// 用两个指针,第二个比第一个多移动k次,这样在第二个到达NULL的时候
// 第一个正好在倒数第k个
ListNode<int>* FindKthTail2(ListNode<int>*pHead, int k)
{
assert(pHead!=NULL);
ListNode<int>* p1 = pHead, *p2 = pHead;
int i=0;
for(i=0; i<k && p2!=NULL; i++)
{
p2 = p2->next;
}
assert(i==k);
while(p2!=NULL)
{
p1 = p1->next;
p2 = p2->next;
}

return p1;
}

int main()
{
ListNode<int>* head = NULL;
createList(head);

ListNode<int>* pKth = FindKthTail1(head, 6);
cout<<pKth->m_key<<endl;
pKth = FindKthTail2(head, 6);
cout<<pKth->m_key<<endl;
destoryList(head);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: