【面试题十五】链表中倒数第k个结点

来源:互联网 发布:微盘软件下载 编辑:程序博客网 时间:2024/06/06 08:42

链表中倒数第k个结点


可以用两个指针,当第一个指针指向了第k个时候,第二个指针让他指向链表的第一个元素,然后这两个指针同时向后面移动,当第一个指针移动到末尾的时候,第二个指针指向的就是倒数第K个结点;

两个指针的间距保持为k-1;

当我们遍历列表的时候发现用一个指针是解决不了问题的,我们可以尝试用两个指针来解决问题,一个指针走的比另外一个指针走得快一点,或者先让其中的一个指针走了若干步,然后再让第二个指针来走;

kth.cpp:

#include <iostream>#include <cstdio>#include "List.h"ListNode* FindKthToTail(ListNode* pListHead, unsigned int k){if(pListHead == NULL || k == 0){return NULL;}ListNode* pAhead = pListHead;ListNode* pBehind = NULL;for(unsigned int i = 0; i < k - 1; ++i){if(pAhead->m_pNext != NULL){pAhead = pAhead->m_pNext;}else{return NULL;}}pBehind = pListHead;while(pAhead->m_pNext != NULL){pAhead = pAhead->m_pNext;pBehind = pBehind->m_pNext;}return pBehind;}// ====================测试代码====================// 测试要找的结点在链表中间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: NULL.\n");    ListNode* pNode = FindKthToTail(NULL, 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: NULL.\n");    ListNode* pNode = FindKthToTail(pNode1, 6);    PrintListNode(pNode);    DestroyList(pNode1);}// 测试输入的第二个参数为0void 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: NULL.\n");    ListNode* pNode = FindKthToTail(pNode1, 0);    PrintListNode(pNode);    DestroyList(pNode1);}int main(){Test1();    Test2();    Test3();    Test4();    Test5();    Test6();return 0;}


List.h:

#ifndef _List_H_#define _List_H_struct ListNode{    int       m_nValue;    ListNode* m_pNext;};ListNode* CreateListNode(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);#endif /*_List_H_*/


List.cpp:

#include "List.h"#include <stdio.h>#include <stdlib.h>ListNode* CreateListNode(int value){    ListNode* pNode = new ListNode();    pNode->m_nValue = value;    pNode->m_pNext = NULL;    return pNode;}void ConnectListNodes(ListNode* pCurrent, ListNode* pNext){    if(pCurrent == NULL)    {        printf("Error to connect two nodes.\n");        exit(1);    }    pCurrent->m_pNext = pNext;}void PrintListNode(ListNode* pNode){     if(pNode == NULL)    {        printf("The node is NULL\n");    }    else    {        printf("The key in node is %d.\n", pNode->m_nValue);    }}void PrintList(ListNode* pHead){    printf("PrintList starts.\n");        ListNode* pNode = pHead;    while(pNode != NULL)    {        printf("%d\t", pNode->m_nValue);        pNode = pNode->m_pNext;    }    printf("\nPrintList ends.\n");}void DestroyList(ListNode* pHead){    ListNode* pNode = pHead;    while(pNode != NULL)    {        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 = NULL;    if(*pHead == NULL)    {        *pHead = pNew;    }    else    {        ListNode* pNode = *pHead;        while(pNode->m_pNext != NULL)            pNode = pNode->m_pNext;        pNode->m_pNext = pNew;    }}void RemoveNode(ListNode** pHead, int value){    if(pHead == NULL || *pHead == NULL)        return;    ListNode* pToBeDeleted = NULL;    if((*pHead)->m_nValue == value)    {        pToBeDeleted = *pHead;        *pHead = (*pHead)->m_pNext;    }    else    {        ListNode* pNode = *pHead;        while(pNode->m_pNext != NULL && pNode->m_pNext->m_nValue != value)            pNode = pNode->m_pNext;        if(pNode->m_pNext != NULL && pNode->m_pNext->m_nValue == value)        {            pToBeDeleted = pNode->m_pNext;            pNode->m_pNext = pNode->m_pNext->m_pNext;        }    }    if(pToBeDeleted != NULL)    {        delete pToBeDeleted;        pToBeDeleted = NULL;    }}


Makefile:

.PHONY:cleanCPP=g++CFLAGS=-Wall -gBIN=testOBJS=Kth.o List.oLIBS=$(BIN):$(OBJS)$(CPP) $(CFLAGS) $^ -o $@ $(LIBS)%.o:%.cpp$(CPP) $(CFLAGS) -c $< -o $@clean:rm -f *.o $(BIN)


运行结果:

=====Test1 starts:=====expected result: 4.The key in node is 4.=====Test2 starts:=====expected result: 5.The key in node is 5.=====Test3 starts:=====expected result: 1.The key in node is 1.=====Test4 starts:=====expected result: NULL.The node is NULL=====Test5 starts:=====expected result: NULL.The node is NULL=====Test6 starts:=====expected result: NULL.The node is NULL


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 去上海没有流量怎么办 去外地没流量怎么办 外地流量不够用怎么办 手机在外地流量怎么办 联通网卡在外地怎么办 套餐流量不够用怎么办 省内流量去省外怎么办 在外省流量不够怎么办 榨汁机开关坏了怎么办 健伍dvd没遥控器怎么办 佳能 显示屏关不了怎么办 iqos充电闪红灯怎么办 航班取消了乘客怎么办 摩托罗拉电话静音了怎么办 对讲机话筒坏了怎么办 摩托罗拉xt1570费电怎么办 主板没有rgb接口怎么办 对讲机频段没了怎么办 怀孕查出宫颈囊怎么办 办养殖场没地怎么办 宝宝睡觉衣服湿透怎么办 开衫衣服往下滑怎么办 迷你世界没有牛怎么办 火龙果树烂了怎么办 误喝鸵鸟墨水怎么办 被鸵鸟啄伤怎么办 被鸵鸟啄住怎么办 鸟翅膀受伤了怎么办 北京卖房户口怎么办 深户挂人才市场集体户小孩怎么办? 郑州房子限购怎么办 外地怎么送东西怎么办 晚上登华山下雨怎么办 北京摇不到号想买车怎么办 北京买车摇不到号怎么办 朋友代购贵了怎么办 赢时通把车开走怎么办 杭州房子租不起怎么办 质量效应2吵架怎么办 学生有两个学籍怎么办 孩子出现双学籍怎么办