查找链表中倒数第k个结点
题目:输入一个单向链表,输出该链表中倒数第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); }