思路:設定兩個指針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 }