9.查找單鏈表的中間節點,要求只能遍歷一次鏈表
思想:這個問題,我們需要先創建一個數組,但我們需要知道鏈表大致的範圍,我在這裏假定鏈表節點數小於1000個,然後我們每遍歷一個節點,就把節點放入數組(數組從零逐個遞增,用 i 表示存放的個數 ),最後數組pavi[i/2]存放的就是中間節點
代碼:
ListNode* ListFindMid(ListNode *pList)//找出鏈表中間節點,只遍歷一次
{
if(pList == NULL)
return NULL;
ListNode *pavi[1000] = {0};//
int i = 0;
while(pList != NULL)
{
pavi[i] = pList;
i++;
pList = pList->next;
}
return pavi[i/2];//
}
這種方法是有問題的,在不知道鏈表節點個數範圍時,數組初始化大小不能確定,所以我們又想到另一個方法:快慢指針
ListNode* ListFindMid(ListNode *pList)//找出鏈表中間節點,只遍歷一次//利用快慢指針
{
if(pList == NULL)
return NULL;
ListNode *pFast = pList;
ListNode *pSlow = pList;
while((pFast != NULL)&&(pFast->next != NULL))
{
pSlow = pSlow->next;
pFast = pFast->next->next;
}
return pFlow;
}
10.查找單鏈表的倒數第k個節點,要求只能遍歷一次鏈表
思想: 方法同查找中間節點的方法相同,可以用指針數組來求,也可用快慢指針:創建一個快指針Pfast先指向第K個節點,如果沒有第K個節點則返回NULL,再創建一個慢指針Pslow,然後同時向後移動,直到Pfast指向NULL時,Pslow指向的就是單鏈表倒數第K個節點。
ListNode* ListFindNode(ListNode *pList, int K)//倒數k個節點
{
if(pList == NULL)
return NULL;
int i = 0;
ListNode *pFast = pList;
ListNode *Pslow = pList;
for(i=0; i<K; i++)
{
if(pFast == NULL)
return NULL;
pFast = pFast->next;
}
while(pFast != NULL)
{
pFast = pFast->next;
Pslow = Pslow->next;
}
return Pslow;
}