查找单链表的倒数第k个值

刚开始,我想到的是一种笨方法,先遍历单链表,计算出单链表的长度len,然后再从头遍历单链表到第len-k个节点,那么

这个节点既是单链表的倒数第k个节点。

不过这种算法时间复杂度挺高的,还有一种更简单的方法,就是设置两个指针,分别指向单链表的头节点,然后让其中一个指针,先走k步,

之后,再让两个指针同时走,直到第一个指针走到单链表尾节点结束。

那么,第二个指针所指向的节点,就是倒数第k个节点。

代码如下:

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

#include <iostream>

#include <cstdlib>

using
namespace std;

typedef
struct list{

    int
data;

    struct
list *next;

}list_node,*listNode;

void
createList(listNode &list,int
arr[],int
n)

{

    int
i;

    listNode temp;

    for(i=0;i<n;i++)

    {

          temp=(list_node*)malloc(sizeof(list_node));     //为节点分配内存

          if(temp)

          {

               temp->data=arr[i];

               temp->next=NULL;

               temp->next=list->next;

               list->next=temp;

          }

          else

          {

             cout<<"内存分配失败"<<endl;

          }

    }

}

/**

     查找倒数第k个节点

*/

int
find_knode(listNode list,int
k)

{

    if(list==NULL||k<0)

    {

        cout<<"链表不能为空或k值不能小于0"<<endl;

        return
0;

    }

    listNode first;

    listNode second;

    int
i=0;

    first=list->next;

    second=list->next;

    while(i<k)

    {

        first=first->next;

        i++;

    }

    if(first==NULL)

    {

        cout<<"链表长度小于k"<<endl;

        return
-1;

    }

    while(first)

    {

       first=first->next;

       second=second->next;

    }

    return
second->data;

}

void 
show_list(listNode list)

{

    listNode temp;

    temp=list;

    while(temp)

    {

        cout<<temp->data<<"---";

        temp=temp->next;

    }

}

int
main(){

    int
arr[]={12,3,6,1,9,17,19,21,22,87};

    listNode list=NULL;

    list=(list_node*)malloc(sizeof(listNode));

    list->data=0;

    list->next=NULL;

    int
k=6;

    

    int
val;

    cout<<"创建链表:"<<endl;

    createList(list,arr,10);

    val=find_knode(list,k);

    cout<<"倒数第<<k<<个节点为:"<<val<<endl;

    cout<<"show list:"<<endl;

    show_list(list);

    return
0;

}

  运行结果如下:

在运行sublime text2时发现出现 error2的错误。

解决办法如下:打开F:\SublimeText2\Data\Packages\C++\c++.sublime-build

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

{

    "cmd": ["g++", "${file}", "-o", "${file_path}/${file_base_name}"],

    "file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",

    "working_dir": "${file_path}",

    "selector": "source.c, source.c++",

    "variants":

    [

        {

            "name": "Run",

            //"cmd": ["bash", "-c", "g++ ‘${file}‘ -o ‘${file_path}/${file_base_name}‘ && ‘${file_path}/${file_base_name}‘"]

            "cmd": [ "${file_path}/${file_base_name}.exe"]

        }

    ]

}

  看到有注释的那一行,是原先配置的,现在把它注释掉,添加下面的一行:

"cmd": [
"${file_path}/${file_base_name}.exe"]

重新运行,就可以了。

查找单链表的倒数第k个值

时间: 2024-10-13 09:52:22

查找单链表的倒数第k个值的相关文章

C++单链表找倒数第k个节点(时间复杂度为o(n)哦,用相距k节点的2个指针进行操作)

//输入一个单向链表,输出该链表中倒数第k个结点.链表的倒数第0个结点为链表的尾指针. //我的思路是2个指针往后面找,你想啊,如果是一个指针,肯定需要遍历2次,第一个遍历总共节点数,第二次才遍历最终结果 //这样的做法明显是不够好的,时间复杂度变成了2n,但是如果我们用2个指针,他们之间的距离差k个节点,有一个节点到达NULL //时(尾部),另一个节点就是我们要求的节点可以返回得到结果. #include <iostream> using namespace std; template&l

删除单链表中倒数第 k 个节点

思路 1 :两个指针 p1 ,p2 ,p1从头开始遍历,当 p1 到达第 k 个节点时,p2 开始: 当 P1 到达链表的最后一个节点时,p2 所指的节点则为链表中倒数第 k 个节点. public class Node{ public int data; public Node next; public Node(int data){ this.data = data; } public Node removeLastKNode(Node head,int k){ if(head == nul

输出链表的倒数第K个值

题目描述 输入一个链表,输出该链表中倒数第k个结点. 思路一:链表不能向前遍历,只能向后遍历.因此倒数第K个结点就是 正序的  :len(链表)-1-K的下一个.  注意,此处的思路与代码中具体实现有点不同,但是 是一致的.假设用i=0计数,那么应该就是i<len(链表)-k  或者 i<=len(链表)-k-1. 下列代码中是设置i=1开始,那么应该就是 i<len(链表)-k+1  或者 i<=len(链表)-k. /* struct ListNode { int val; s

C++获取单链表的倒数第k个节点

/* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } };*/ class Solution { public: ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) { if(pListHead == NULL || k == 0){ return NULL; } ListNode *pAhea

输出单链表中倒数第k个结点(Java版)

题目:输入带头结点的单链表L,输出该单链表中倒数第k个结点.单链表的倒数第0个结点为该单链表的尾指针.要求只能遍历一次单链表. 解题思路: 如果不要求只能遍历一次单链表,我们可以先遍历一次单链表,求出它的结点的总个数n(包括头结点),所以单链表的结点是从倒数第n-1个到倒数第0个,然后再遍历一次单链表,遍历时访问的第n-k-1个结点就是该单链表中倒数第k个结点.现在要求只能遍历一次单链表,可以设两个指针p和q,最开始时它们都指向头结点,然后p向后移动k位,最后p,q同时向后移动直到p为最后一个结

13输入一个单向链表,输出该链表中倒数第k个结点。链表的倒数第0个结点为链表的尾指针。

转载请注明出处:http://www.cnblogs.com/wuzetiandaren/p/4250795.html 声明:现大部分文章为寻找问题时在网上相互转载,此博是为自己做个记录记录,方便自己也方便有类似问题的朋友,本文的思想也许有所借鉴,但源码均为本人实现,如有侵权,请发邮件表明文章和原出处地址,我一定在文章中注明.谢谢. 题目:输入一个单向链表,输出该链表中倒数第k个结点.链表的倒数第0个结点为链表的尾指针. 题目分析: 1.链表的倒数第0个结点为链表的尾指针,设为r,则r指向最后一

输出单链表中倒数第k个结点

题目:输入带头结点的单链表L,输出该单链表中倒数第k个结点.单链表的倒数第0个结点为该单链表的尾指针.要求只能遍历一次单链表. 解题思路: 如果不要求只能遍历一次单链表,我们可以先遍历一次单链表,求出它的结点的总个数n(包括头结点),所以单链表的结点是从倒数第n-1个到倒数第0个,然后再遍历一次单链表,遍历时访问的第n-k-1个结点就是该单链表中倒数第k个结点.现在要求只能遍历一次单链表,可以设两个指针p和q,最开始时它们都指向头结点,然后p向后移动k位,最后p,q同时向后移动直到p为最后一个结

数据结构与算法-链表查找倒数第K个值

查找链表中倒数第k个结点题目:输入一个单向链表,输出该链表中倒数第k个结点.链表的倒数第0个结点为链表的尾指针.链表结点定义如下: struct ListNode { int m_nKey; ListNode* m_pNext; }; int FindCoundDownInList(pListNode head,int num) { pListNode p1,p2; p1=p2=head; while(num-->0 && p1!=NULL) p1=p1->m_pNext; i

【剑指offer】九,链表中倒数第k个结点

题目描述 输入一个链表,输出该链表中倒数第k个结点. 分析:此题为常见的快慢指针问题,java实现时要注意空指针错误以及边界条件.使用两个指针p和q,一个指针先走k-1步,然后第二个指针开始走.当第一个指针指向单链表的最后一个节点时,第二个指针指向倒数第k个节点.代码如下: 1 /* 2 public class ListNode { 3 int val; 4 ListNode next = null; 5 6 ListNode(int val) { 7 this.val = val; 8 }