剑指offer-链表中倒数第K个结点以及获取链表中中间结点

/*******************************************************************
Copyright(c) 2016, Tyrone Li
All rights reserved.
*******************************************************************/
// 作者:TyroneLi
//

/*
Q:
    链表中倒数第K个结点:
        输一个链表,输出链表中倒数第K个结点,为了符合大家使用习惯
        本题从1开始计数,即链表中尾结点是倒数第1个结点。
S:
    可以使用两个指针,第一个指针先往前走(k-1)步,然后两个指针同时往前走,
    知道第一个节点指向的是尾节点,则第二个结点就是所求的倒数第k个结点。
*/

#include "../utils/List.h"
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>

ListNode*getKListNode(ListNode**pHead, int k)
{
    if(pHead == nullptr || k <= 0)
        return nullptr;
    
    ListNode*pAhead = *pHead;
    ListNode*pBehind = nullptr;
    for(int i = 0; i < (k-1); ++i)
    {
        if(pAhead->m_pNext != nullptr)
        {
            pAhead = pAhead->m_pNext;
        }else{
            return nullptr;
        }
    }
    
    pBehind = *pHead;
    while(pAhead->m_pNext != nullptr)
    {
        pAhead = pAhead->m_pNext;
        pBehind = pBehind->m_pNext;
    }
    return pBehind;
}

/* 
获取链表中的中间结点,如果为链表具有奇数个结点,
则放回中间一个结点;否则返回中间两个结点中任意一个。
*/
ListNode*getMidListNode(ListNode**pHead)
{
    if(pHead == nullptr)
        return nullptr;

    ListNode*pAhead = *pHead;
    ListNode*pBehind = *pHead;
    while(pBehind->m_pNext != nullptr && pBehind->m_pNext->m_pNext != nullptr)
    {
        pAhead = pAhead->m_pNext;
        pBehind = pBehind->m_pNext->m_pNext;
    }
    return pAhead;
}

void test_1()
{
    std::cout << "test num 4 node " << std::endl;
    ListNode*pHead = createListNode(1);
    addToHead(&pHead, 2);
    addToHead(&pHead, 3);
    addToHead(&pHead, 4);
    addToHead(&pHead, 5);
    addToHead(&pHead, 6);
    printList(pHead);
    ListNode*pNode = getKListNode(&pHead, 4);
    printListNode(pNode);

    destroyList(pHead);
}

void test_2()
{
    std::cout << "test num 1 node " << std::endl;
    ListNode*pHead = createListNode(1);
    addToHead(&pHead, 2);
    addToHead(&pHead, 3);
    addToHead(&pHead, 4);
    addToHead(&pHead, 5);
    addToHead(&pHead, 6);
    printList(pHead);
    ListNode*pNode = getKListNode(&pHead, 1);
    printListNode(pNode);

    destroyList(pHead);
}

void test_3()
{
    std::cout << "test num 6 node " << std::endl;
    ListNode*pHead = createListNode(1);
    addToHead(&pHead, 2);
    addToHead(&pHead, 3);
    addToHead(&pHead, 4);
    addToHead(&pHead, 5);
    addToHead(&pHead, 6);
    printList(pHead);
    ListNode*pNode = getKListNode(&pHead, 6);
    printListNode(pNode);

    destroyList(pHead);
}

void test_4()
{
    std::cout << "test num 7 node " << std::endl;
    ListNode*pHead = createListNode(1);
    addToHead(&pHead, 2);
    addToHead(&pHead, 3);
    addToHead(&pHead, 4);
    addToHead(&pHead, 5);
    addToHead(&pHead, 6);
    printList(pHead);
    ListNode*pNode = getKListNode(&pHead, 7);
    printListNode(pNode);

    destroyList(pHead);
}

void test_5()
{
    std::cout << "test num 0 node " << std::endl;
    ListNode*pHead = createListNode(1);
    addToHead(&pHead, 2);
    addToHead(&pHead, 3);
    addToHead(&pHead, 4);
    addToHead(&pHead, 5);
    addToHead(&pHead, 6);
    printList(pHead);
    ListNode*pNode = getKListNode(&pHead, 0);
    printListNode(pNode);

    destroyList(pHead);
}

void test_6()
{
    std::cout << "test num nullptr list " << std::endl;
    ListNode*pHead = nullptr;
    printList(pHead);
    ListNode*pNode = getKListNode(&pHead, 0);
    printListNode(pNode);

    destroyList(pHead);
}

void test_getKListNode()
{
    test_1();
    test_2();
    test_3();
    test_4();
    test_5();
    test_6();
}

void test_getMidListNode()
{
    std::cout << "test getMidListNode" << std::endl;
    ListNode*pHead = createListNode(1);
    printList(pHead);
    ListNode*pNode = getMidListNode(&pHead);
    printListNode(pNode);

    ListNode*pHead2 = createListNode(1);
    addToHead(&pHead2, 2);
    printList(pHead2);
    ListNode*pNode2 = getMidListNode(&pHead2);
    printListNode(pNode2);

    ListNode*pHead3 = createListNode(1);
    addToHead(&pHead3, 2);
    addToHead(&pHead3, 3);
    printList(pHead3);
    ListNode*pNode3 = getMidListNode(&pHead3);
    printListNode(pNode3);

    ListNode*pHead4 = createListNode(1);
    addToHead(&pHead4, 2);
    addToHead(&pHead4, 3);
    addToHead(&pHead4, 4);
    printList(pHead4);
    ListNode*pNode4 = getMidListNode(&pHead4);
    printListNode(pNode4);

    ListNode*pHead5 = createListNode(1);
    addToHead(&pHead5, 2);
    addToHead(&pHead5, 3);
    addToHead(&pHead5, 4);
    addToHead(&pHead5, 5);
    addToHead(&pHead5, 6);
    addToHead(&pHead5, 7);
    printList(pHead5);
    ListNode*pNode5 = getMidListNode(&pHead5);
    printListNode(pNode5);

    ListNode*pHead6 = createListNode(1);
    addToHead(&pHead6, 2);
    addToHead(&pHead6, 3);
    addToHead(&pHead6, 4);
    addToHead(&pHead6, 5);
    addToHead(&pHead6, 6);
    addToHead(&pHead6, 7);
    addToHead(&pHead6, 8);
    printList(pHead6);
    ListNode*pNode6 = getMidListNode(&pHead6);
    printListNode(pNode6);

    destroyList(pHead);
    destroyList(pHead2);
    destroyList(pHead3);
    destroyList(pHead4);
    destroyList(pHead5);
    destroyList(pHead6);
}

int main(int argc, char**argv)
{

    test_getKListNode();
    test_getMidListNode();

    return 0;
}
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值