算法描述:
输入一个链表,输出该链表中倒数第k个结点
算法实现:
/*************************************************************************
> File Name: main.c
> Author: cyf
> Mail: XXX@qq.com
> Created Time: 2016年05月19日 星期四 09时38分46秒
************************************************************************/
#include "findKthToTail.h"
void Test1()
{
printf("=====Test1 starts:=====\n");
struct ListNode* pNode1 = CreateListNode(1);
struct ListNode* pNode2 = CreateListNode(2);
struct ListNode* pNode3 = CreateListNode(3);
struct ListNode* pNode4 = CreateListNode(4);
struct ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
printf("expected result: 4.\n");
struct ListNode* pNode = findKthToTail(pNode1, 2);
PrintListNode(pNode);
DestroyList(pNode1);
}
// 测试要找的结点是链表的尾结点
void Test2()
{
printf("=====Test2 starts:=====\n");
struct ListNode* pNode1 = CreateListNode(1);
struct ListNode* pNode2 = CreateListNode(2);
struct ListNode* pNode3 = CreateListNode(3);
struct ListNode* pNode4 = CreateListNode(4);
struct ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
printf("expected result: 5.\n");
struct ListNode* pNode = findKthToTail(pNode1, 1);
PrintListNode(pNode);
DestroyList(pNode1);
}
// 测试要找的结点是链表的头结点
void Test3()
{
printf("=====Test3 starts:=====\n");
struct ListNode* pNode1 = CreateListNode(1);
struct ListNode* pNode2 = CreateListNode(2);
struct ListNode* pNode3 = CreateListNode(3);
struct ListNode* pNode4 = CreateListNode(4);
struct ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
printf("expected result: 1.\n");
struct ListNode* pNode = findKthToTail(pNode1, 5);
PrintListNode(pNode);
DestroyList(pNode1);
}
// 测试空链表
void Test4()
{
printf("=====Test4 starts:=====\n");
printf("expected result: NULL.\n");
struct ListNode* pNode = findKthToTail(NULL, 100);
PrintListNode(pNode);
}
// 测试输入的第二个参数大于链表的结点总数
void Test5()
{
printf("=====Test5 starts:=====\n");
struct ListNode* pNode1 = CreateListNode(1);
struct ListNode* pNode2 = CreateListNode(2);
struct ListNode* pNode3 = CreateListNode(3);
struct ListNode* pNode4 = CreateListNode(4);
struct ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
printf("expected result: NULL.\n");
struct ListNode* pNode = findKthToTail(pNode1, 6);
PrintListNode(pNode);
DestroyList(pNode1);
}
// 测试输入的第二个参数为0
void Test6()
{
printf("=====Test6 starts:=====\n");
struct ListNode* pNode1 = CreateListNode(1);
struct ListNode* pNode2 = CreateListNode(2);
struct ListNode* pNode3 = CreateListNode(3);
struct ListNode* pNode4 = CreateListNode(4);
struct ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
printf("expected result: NULL.\n");
struct ListNode* pNode = findKthToTail(pNode1, 0);
PrintListNode(pNode);
DestroyList(pNode1);
}
int main()
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
return 0;
}/*************************************************************************
> File Name: main.c
> Author: cyf
> Mail: XXX@qq.com
> Created Time: 2016年05月19日 星期四 09时38分46秒
************************************************************************/
#include "findKthToTail.h"
void Test1()
{
printf("=====Test1 starts:=====\n");
struct ListNode* pNode1 = CreateListNode(1);
struct ListNode* pNode2 = CreateListNode(2);
struct ListNode* pNode3 = CreateListNode(3);
struct ListNode* pNode4 = CreateListNode(4);
struct ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
printf("expected result: 4.\n");
struct ListNode* pNode = findKthToTail(pNode1, 2);
PrintListNode(pNode);
DestroyList(pNode1);
}
// 测试要找的结点是链表的尾结点
void Test2()
{
printf("=====Test2 starts:=====\n");
struct ListNode* pNode1 = CreateListNode(1);
struct ListNode* pNode2 = CreateListNode(2);
struct ListNode* pNode3 = CreateListNode(3);
struct ListNode* pNode4 = CreateListNode(4);
struct ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
printf("expected result: 5.\n");
struct ListNode* pNode = findKthToTail(pNode1, 1);
PrintListNode(pNode);
DestroyList(pNode1);
}
// 测试要找的结点是链表的头结点
void Test3()
{
printf("=====Test3 starts:=====\n");
struct ListNode* pNode1 = CreateListNode(1);
struct ListNode* pNode2 = CreateListNode(2);
struct ListNode* pNode3 = CreateListNode(3);
struct ListNode* pNode4 = CreateListNode(4);
struct ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
printf("expected result: 1.\n");
struct ListNode* pNode = findKthToTail(pNode1, 5);
PrintListNode(pNode);
DestroyList(pNode1);
}
// 测试空链表
void Test4()
{
printf("=====Test4 starts:=====\n");
printf("expected result: NULL.\n");
struct ListNode* pNode = findKthToTail(NULL, 100);
PrintListNode(pNode);
}
// 测试输入的第二个参数大于链表的结点总数
void Test5()
{
printf("=====Test5 starts:=====\n");
struct ListNode* pNode1 = CreateListNode(1);
struct ListNode* pNode2 = CreateListNode(2);
struct ListNode* pNode3 = CreateListNode(3);
struct ListNode* pNode4 = CreateListNode(4);
struct ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
printf("expected result: NULL.\n");
struct ListNode* pNode = findKthToTail(pNode1, 6);
PrintListNode(pNode);
DestroyList(pNode1);
}
// 测试输入的第二个参数为0
void Test6()
{
printf("=====Test6 starts:=====\n");
struct ListNode* pNode1 = CreateListNode(1);
struct ListNode* pNode2 = CreateListNode(2);
struct ListNode* pNode3 = CreateListNode(3);
struct ListNode* pNode4 = CreateListNode(4);
struct ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
printf("expected result: NULL.\n");
struct ListNode* pNode = findKthToTail(pNode1, 0);
PrintListNode(pNode);
DestroyList(pNode1);
}
int main()
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
return 0;
}
/*************************************************************************
> File Name: findKthToTail.h
> Author: cyf
> Mail: XXX@qq.com
> Created Time: 2016年05月19日 星期四 09时21分05秒
************************************************************************/
#ifndef _FINDKTHTOTAIL_H
#define _FINDKTHTOTAIL_H
#include <stdio.h>
#include <stdlib.h>
#include "List.h"
struct ListNode *findKthToTail(struct ListNode *pHead, unsigned int k);
#endif
/*************************************************************************
> File Name: findKthToTail.c
> Author: cyf
> Mail: XXX@qq.com
> Created Time: 2016年05月19日 星期四 09时32分11秒
************************************************************************/
#include "findKthToTail.h"
struct ListNode *findKthToTail(struct ListNode *pHead, unsigned int k)
{
if (pHead == NULL || k==0)
return NULL;
struct ListNode *pFirst = pHead;
struct ListNode *pLast = NULL;
unsigned int i = 0;
for (i=0; i< k-1; i++)
{
if (pFirst->next != NULL)
pFirst = pFirst->next;
else
return NULL;
}
pLast = pHead;
while (pFirst->next != NULL)
{
pFirst = pFirst->next;
pLast = pLast->next;
}
return pLast;
}
/************************************************************************
> File Name: List.h
> Author: cyf
> Mail: 1097189275@qq.com
> Created Time: 2016年03月23日 星期三 17时27分15秒
************************************************************************/
#ifndef ALGRITHMN_LIST_H
#define ALGRITHMN_LIST_H
struct ListNode
{
int data;
struct ListNode *next;
};
struct ListNode *CreateListNode(int value);
void ConnectListNodes(struct ListNode *pCurrent, struct ListNode *pNext);
void PrintListNode(struct ListNode *pNode);
void PrintList(struct ListNode *pHead);
void AddToTail(struct ListNode **pHead, int value);
void RemoveNode(struct ListNode **pHead,int value);
unsigned int GetListLength(struct ListNode *pHead);
void DestroyNode(struct ListNode *pNode);
void DestroyList(struct ListNode *pHead);
#endif
/*************************************************************************
> File Name: List.cpp
> Author: cyf
> Mail: 1097189275@qq.com
> Created Time: 2016年03月23日 星期三 17时32分11秒
************************************************************************/
#include "List.h"
#include <stdio.h>
#include <stdlib.h>
/*
* 创建一个链表的结点
* */
struct ListNode *CreateListNode(int value)
{
struct ListNode *pNode =(struct ListNode *)malloc(sizeof(struct ListNode));
pNode->data = value;
pNode->next = NULL;
return pNode;
}
/*
* 将两个结点连接起来
* */
void ConnectListNodes(struct ListNode *pCurrent, struct ListNode *pNext)
{
if(!pCurrent)
{
printf("ERROR!connect two ListNode.\n");
exit(1);
}
pCurrent->next = pNext;
}
/*
* 打印结点
* */
void PrintListNode(struct ListNode *pNode)
{
if(!pNode)
{
printf("the node is null!\n");
exit(1);
}
printf("The value of the node is %d\n",pNode->data);
}
/*
* 打印链表
* */
void PrintList(struct ListNode *pHead)
{
printf("print the list:\n");
struct ListNode *pNode = pHead;
if(!pNode)
{
printf("the list is null\n");
exit(1);
}
while(pNode != NULL)
{
printf("%d ",pNode->data);
pNode = pNode->next;
}
}
/*
* 在链表结尾添加结点
* */
void AddToTail(struct ListNode **pHead, int value)
{
struct ListNode *pNew = (struct ListNode*)malloc(sizeof(struct ListNode));
pNew->data = value;
pNew->next = NULL;
if(!pHead)
*pHead = pNew;
else
{
struct ListNode *pNode = *pHead;
while(pNode != NULL)
{
pNode = pNode->next;
}
pNode->next = pNew;
}
}
/*
* 删除链表中结点值为value的结点
* */
void RemoveNode(struct ListNode **pHead, int value)
{
if(pHead == NULL||*pHead == NULL)
{
printf("the list is null");
return;
}
struct ListNode *ToBeDel = NULL;
if((*pHead)->data == value)
{
ToBeDel = *pHead;
*pHead = (*pHead)->next;
}
else
{
struct ListNode *pNode = *pHead;
while(pNode->next != NULL && pNode->next->data != value)
pNode = pNode->next;
if(pNode->next != NULL && pNode->next->data == value)
{
ToBeDel = pNode->next;
pNode->next = pNode->next->next;
}
}
if(ToBeDel != NULL)
{
free(ToBeDel);
ToBeDel = NULL;
}
}
/*
* 计算链表的长度
* */
unsigned int GetListLength(struct ListNode *pHead)
{
unsigned int length = 0;
struct ListNode *pNode = pHead;
while(pNode != NULL)
{
++length;
pNode = pNode->next;
}
return length;
}
/*
* 销毁一个结点
* */
void DestroyNode(struct ListNode *pNode)
{
free(pNode);
pNode = NULL;
}
void DestroyList(struct ListNode* pHead)
{
struct ListNode *pNode = pHead;
while (pNode != NULL)
{
pHead = pHead->next;
free(pNode);
pNode = pHead;
}
}
.SUFFIXES:.c.o
CC = gcc
CFLAGS = -g -O2 -Wall
SRCS = main.c\
List.c\
findKthToTail.c
OBJS = $(SRCS:.c=.o)
EXE = main
all:$(OBJS)
$(CC) $(OBJS) -o $(EXE) $(CFLAGS)
.c.o:
$(CC) -o $@ -c $(CFLAGS) $<
clean:
rm -rf $(OBJS) $(EXE)