我的直观想法是遍历单链表,统计元素个数,然后确定中间元素的位置,在此进行遍历。。。
看到的比较精妙的算法是,用二个指针first,second分别走一步,二步。。当second走到队尾/接近的时候,first应该就是中间/接近中间元素的位置
这里的关键是,处理"接近"这个模糊的概念。。。
来二个图,直观的展示一下..
首先是元素个数分别为偶数/奇数个的情况
所以每次都要判断second->next==NULL || second->next->next==NULL 若此条件满足,则first指针即为中间元素,否则second=second->next->next,first=first->next
还要考虑几种特殊情况:
(1)head==NULL,没有中间元素,return NULL
(2)只有一个元素,满足前述条件中的second->next==NULL,retrun first
(3)只有二个元素,满足second->next->next==NULL,return first
(4)三个或三个以上的元素,同样满足条件
上述归纳证明了算法的正确性
核心代码:
struct node* linkList_midElement(struct node* head)
{
if(!head) return NULL;
struct node *first;
struct node *second;
first=second=head;
while((second->next)&&(second->next->next))
{
second = second->next->next;
first = first->next;
}
return first;
}
OVER!!!
面对这个题目要求,还是展现了我现在见识/积累不够,思维局限性比较大。。好在总算还有解决方案,尽管有些贻笑大方。。。