链表中倒数第K个结点
Posted 三颗心
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了链表中倒数第K个结点相关的知识,希望对你有一定的参考价值。
题目:输入一个链表,输出该链表中倒数第K个结点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾结点是倒数第1个结点。例如一个链表有6个结点,从头结点开始它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个结点是值为4的结点。
思路:设定两个指针p1和p2,两个指针刚开始都指向链表的第一个结点,然后让p1指针先走(k-1)步,然后再让两个指针一起往后走,当p1指针指向链表最后一个结点的时候,p2指针刚好指向链表中的倒数第k个结点。
在写代码的时候需要考虑鲁棒性,最好采用防御性编程,就是考虑在哪些地方会出错,然后提前加上错误判断,这样避免因此错误输入而导致程序崩溃。
1 #include<iostream> 2 #include<stdio.h> 3 #include<tchar.h> 4 using namespace std; 5 6 //链表结构 7 struct ListNode 8 { 9 int m_nValue; 10 ListNode* m_pNext; 11 }; 12 13 //创建一个链表结点 14 ListNode* CreateListNode(int value) 15 { 16 ListNode* pNode = new ListNode(); 17 pNode->m_nValue = value; 18 pNode->m_pNext = NULL; 19 20 return pNode; 21 } 22 23 //输出链表中的某一结点的值 24 void PrintListNode(ListNode* pNode) 25 { 26 if(pNode == NULL) 27 printf("The node is NULL\\n"); 28 else 29 printf("The key in node is %d.\\n", pNode->m_nValue); 30 } 31 32 //输出链表 33 void PrintList(ListNode* pHead) 34 { 35 ListNode *pNode = pHead; 36 while(pNode != NULL) 37 { 38 cout << pNode->m_nValue<< " "; 39 pNode = pNode->m_pNext; 40 } 41 cout<<endl; 42 } 43 44 //删除结点 45 void DestroyList(ListNode* pHead) 46 { 47 ListNode* pNode = pHead; 48 while(pNode != NULL) 49 { 50 pHead = pHead->m_pNext; 51 delete pNode; 52 pNode = pHead; 53 } 54 } 55 56 //往链表末尾添加结点 57 /* 58 注意这里pHead是一个指向指针的指针,在主函数中一般传递的是引用。 59 因为如果要为链表添加结点,那么就会修改链表结构,所以必须传递引用才能够保存修改后的结构。 60 */ 61 void AddToTail(ListNode** pHead, int value) 62 { 63 ListNode* pNew = new ListNode(); 64 pNew->m_nValue = value; 65 pNew->m_pNext = NULL; 66 67 if(*pHead == NULL) 68 { 69 *pHead = pNew; 70 } 71 else 72 { 73 ListNode* pNode = *pHead; 74 while(pNode->m_pNext != NULL) 75 pNode = pNode->m_pNext; 76 77 pNode->m_pNext = pNew; 78 } 79 } 80 81 82 //链接两个结点 83 //void ConnectListNodes(ListNode* pCurrent, ListNode* pNext) 84 //{ 85 // if(pCurrent == NULL) 86 // { 87 // printf("Error to connect two nodes.\\n"); 88 // exit(1); 89 // } 90 // pCurrent->m_pNext = pNext; 91 //} 92 93 //防御性编程,鲁棒性更好 94 ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) 95 { 96 if(pListHead == NULL || k == 0) 97 return NULL; 98 99 ListNode *pAhead = pListHead; 100 ListNode *pBehind = NULL; 101 102 for(unsigned int i = 0 ; i < k- 1 ; i ++) 103 { 104 if(pAhead->m_pNext != NULL) 105 pAhead = pAhead->m_pNext; 106 else 107 return NULL; 108 } 109 110 pBehind = pListHead; 111 while(pAhead->m_pNext != NULL) 112 { 113 pAhead = pAhead->m_pNext; 114 pBehind = pBehind->m_pNext; 115 } 116 117 return pBehind; 118 } 119 120 int main() 121 { 122 //创建结点 123 ListNode* pNode1=CreateListNode(1);//创建一个结点 124 PrintList(pNode1);//打印 125 //往链表中添加新结点 126 AddToTail(&pNode1, 2);//为链表添加一个结点 127 AddToTail(&pNode1, 3);//为链表添加一个结点 128 AddToTail(&pNode1, 4);//为链表添加一个结点 129 AddToTail(&pNode1, 5);//为链表添加一个结点 130 AddToTail(&pNode1, 6);//为链表添加一个结点 131 AddToTail(&pNode1, 7);//为链表添加一个结点 132 //打印链表 133 PrintList(pNode1);//打印 134 //反转链表 135 ListNode* KthNode=FindKthToTail(pNode1,3); 136 137 PrintListNode(KthNode); 138 139 DestroyList(pNode1); 140 141 return 0; 142 }
以上是关于链表中倒数第K个结点的主要内容,如果未能解决你的问题,请参考以下文章