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;
}