剑指offer --反向输出链表与输出链表的倒数第k个元素

List.h

#ifndef LIST_H
#define LIST_H
#include <stdio.h>
#include <stdlib.h>

struct ListNode
{
  int m_nValue;
  ListNode* m_pNext;
};
ListNode* CreatListNode(int value);
void ConnectListNodes(ListNode* pCurrent,ListNode pNext);
void PrintListNode(ListNode* pNode);
void PrintList(ListNode* phead);
void DestroyList(ListNode* phead);
void AddToTail(ListNode** phead,int value);
void RemoveNode(ListNode** phead,int value);

ListNode* CreateListNode(int value)
{
    ListNode *pNode = new ListNode();
    pNode->m_nValue = value;
    pNode->m_pNext = nullptr;

    return pNode;
}
void ConnectListNodes(ListNode* pCurrent,ListNode* pNext)
{
    if(pCurrent==nullptr)
    {
        printf("Error to connect two nodes!!\n");
        exit(1);
    }

    pCurrent->m_pNext = pNext;

}

void PrintListNode(ListNode* pNode)
{
    if(pNode==nullptr)
    {
        printf("The node is nullptr.\n");
    }
    else
    {
        printf("The key in node is %d.\n",pNode->m_nValue);
    }

}
void PrintList(ListNode* phead)
{
    printf("\n Print list starts.\n");
    ListNode* pNode = phead;
    while(pNode!=nullptr)
    {
        printf("%d\t",pNode->m_nValue);
        pNode = pNode->m_pNext;
    }
    printf("\nPrint List end.\n");
}
void DestroyList(ListNode* phead)
{
    ListNode* pNode = phead;
    while(pNode!=nullptr)
    {
        phead = phead->m_pNext;
        delete pNode;
        pNode = phead;
    }
}
void AddToTail(ListNode** phead,int value)
{
    ListNode* pNew = new ListNode();
    pNew->m_nValue = value;
    pNew->m_pNext = nullptr;

    if(*phead == nullptr)
    {
        *phead = pNew;
    }
    else
    {
        ListNode* pNode = *phead;
        while(pNode->m_pNext!=nullptr)
            pNode = pNode->m_pNext;
        pNode->m_pNext = pNew;
    }
}
void RemoveNode(ListNode** phead,int value)
{
  if(*phead == nullptr||phead == nullptr)
    return ;
  ListNode* pToBeDeleted = nullptr;

  if((*phead)->m_nValue == value)
  {
      pToBeDeleted = *phead;
      *phead = (*phead)->m_pNext;
  }
  else
  {
      ListNode* pNode = *phead;
      while(pNode->m_pNext!=nullptr&&pNode->m_pNext->m_nValue!=value)
        pNode = pNode->m_pNext;
      if(pNode->m_pNext!=nullptr&&pNode->m_pNext->m_nValue==value)
      {
          pToBeDeleted = pNode->m_pNext;
          pNode->m_pNext = pNode->m_pNext->m_pNext;
      }
      if(pToBeDeleted!=nullptr)
      {
          delete pToBeDeleted;
          pToBeDeleted = nullptr;
      }
  }
}



#endif // LIST_H



 
#include "List.h"
#include <stack>
#include <cstdio>

void PrintListReversingly_Iteratively(ListNode* pHead)
{
    std::stack<ListNode*> nodes;

    ListNode* pNode = pHead;
    while(pNode!=nullptr)
    {
        nodes.push(pNode);
        pNode = pNode->m_pNext;
    }
    while(!nodes.empty())
    {
        pNode = nodes.top();
        printf("%d\t",pNode->m_nValue);
        nodes.pop();
    }
}

void PrintListReversingly_Recursively(ListNode* pHead)
{
    if(pHead!=nullptr)
    {
        if(pHead->m_pNext!=nullptr)
        PrintListReversingly_Recursively(pHead->m_pNext);

        printf("%d\t",pHead->m_nValue);
    }

}
ListNode* FindKthToTail(ListNode* pHead,unsigned int k)
{
    if(pHead==nullptr||k==0)
        return nullptr;

    ListNode* pAhead=pHead;
    ListNode* pBehind =nullptr;
    for(unsigned 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;
}
//void Test(ListNode* pHead)
//{
//    PrintList(pHead);
//    PrintListReversingly_Iteratively(pHead);
//    printf("\n");
//    PrintListReversingly_Recursively(pHead);
//}
//void Test1()
//{
//    printf("\n Test1 begin. \n");
//
//    ListNode *pNode1 = CreatListNode(1);
//    ListNode *pNode2 = CreatListNode(2);
//    ListNode *pNode3 = CreatListNode(3);
//    ListNode *pNode4 = CreatListNode(4);
//    ListNode *pNode5 = CreatListNode(5);
//
//    ConnectListNodes(pNode1,pNode2);
//    ConnectListNodes(pNode2,pNode3);
//    ConnectListNodes(pNode3,pNode4);
//    ConnectListNodes(pNode4,pNode5);
//
//    Test(pNode1);
//    DestroyList(pNode1);
//}
//void Test2()
//{
//    printf("\n Test2 begin. \n");
//    ListNode *pNode1 = CreatListNode(1);
//    Test(pNode1);
//    DestroyList(pNode1);
//}
//void Test3()
//{
//    printf("\n Test3 begin. \n");
//    ListNode *pNode1 = nullptr;
//    Test(pNode1);
//    DestroyList(pNode1);
//}

// ====================测试代码====================
// 测试要找的结点在链表中间
void Test1()
{
    printf("=====Test1 starts:=====\n");
    ListNode* pNode1 = CreateListNode(1);
    ListNode* pNode2 = CreateListNode(2);
    ListNode* pNode3 = CreateListNode(3);
    ListNode* pNode4 = CreateListNode(4);
    ListNode* pNode5 = CreateListNode(5);

    ConnectListNodes(pNode1, pNode2);
    ConnectListNodes(pNode2, pNode3);
    ConnectListNodes(pNode3, pNode4);
    ConnectListNodes(pNode4, pNode5);

    printf("expected result: 4.\n");
    ListNode* pNode = FindKthToTail(pNode1, 2);
    PrintListNode(pNode);

    DestroyList(pNode1);
}
// 测试要找的结点是链表的尾结点
void Test2()
{
    printf("=====Test2 starts:=====\n");
    ListNode* pNode1 = CreateListNode(1);
    ListNode* pNode2 = CreateListNode(2);
    ListNode* pNode3 = CreateListNode(3);
    ListNode* pNode4 = CreateListNode(4);
    ListNode* pNode5 = CreateListNode(5);

    ConnectListNodes(pNode1, pNode2);
    ConnectListNodes(pNode2, pNode3);
    ConnectListNodes(pNode3, pNode4);
    ConnectListNodes(pNode4, pNode5);

    printf("expected result: 5.\n");
    ListNode* pNode = FindKthToTail(pNode1, 1);
    PrintListNode(pNode);

    DestroyList(pNode1);
}
// 测试要找的结点是链表的头结点
void Test3()
{
    printf("=====Test3 starts:=====\n");
    ListNode* pNode1 = CreateListNode(1);
    ListNode* pNode2 = CreateListNode(2);
    ListNode* pNode3 = CreateListNode(3);
    ListNode* pNode4 = CreateListNode(4);
    ListNode* pNode5 = CreateListNode(5);

    ConnectListNodes(pNode1, pNode2);
    ConnectListNodes(pNode2, pNode3);
    ConnectListNodes(pNode3, pNode4);
    ConnectListNodes(pNode4, pNode5);

    printf("expected result: 1.\n");
    ListNode* pNode = FindKthToTail(pNode1, 5);
    PrintListNode(pNode);

    DestroyList(pNode1);
}
// 测试空链表
void Test4()
{
    printf("=====Test4 starts:=====\n");
    printf("expected result: nullptr.\n");
    ListNode* pNode = FindKthToTail(nullptr, 100);
    PrintListNode(pNode);
}
// 测试输入的第二个参数大于链表的结点总数
void Test5()
{
    printf("=====Test5 starts:=====\n");
    ListNode* pNode1 = CreateListNode(1);
    ListNode* pNode2 = CreateListNode(2);
    ListNode* pNode3 = CreateListNode(3);
    ListNode* pNode4 = CreateListNode(4);
    ListNode* pNode5 = CreateListNode(5);

    ConnectListNodes(pNode1, pNode2);
    ConnectListNodes(pNode2, pNode3);
    ConnectListNodes(pNode3, pNode4);
    ConnectListNodes(pNode4, pNode5);

    printf("expected result: nullptr.\n");
    ListNode* pNode = FindKthToTail(pNode1, 6);
    PrintListNode(pNode);

    DestroyList(pNode1);
}
// 测试输入的第二个参数为0
void Test6()
{
    printf("=====Test6 starts:=====\n");
    ListNode* pNode1 = CreateListNode(1);
    ListNode* pNode2 = CreateListNode(2);
    ListNode* pNode3 = CreateListNode(3);
    ListNode* pNode4 = CreateListNode(4);
    ListNode* pNode5 = CreateListNode(5);

    ConnectListNodes(pNode1, pNode2);
    ConnectListNodes(pNode2, pNode3);
    ConnectListNodes(pNode3, pNode4);
    ConnectListNodes(pNode4, pNode5);

    printf("expected result: nullptr.\n");
    ListNode* pNode = FindKthToTail(pNode1, 0);
    PrintListNode(pNode);

    DestroyList(pNode1);
}

int main(int argc, char* argv[])
{
    Test1();
    Test2();
    Test3();
    Test4();
    Test5();
    Test6();

    return 0;
}


Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值