查找链表中倒数第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);
}

 

posted @ 2012-10-25 19:14  三更_雨  阅读(929)  评论(0编辑  收藏  举报