思路:
(1)首先求解单链表的长度length,然后遍历 length / 2 的距离即可查到单链表的中间节点,但一般此种方法需要遍历两次链表,第一次遍历求解单链表的长度,第二次遍历根据索引获取中间节点。
(2)如果是双向链表,可以首尾并行,利用两个指针一个从头到尾,一个从尾到头,当两个指针相遇的时候,就找到中间元素。以此思想为基础,进一步思考,单链表也可以采用双指针的方式来实现中间节点的快速查找。但双指针的使用和双向链表不同,具体如下:
<1> 有2个指针同时从头开始遍历;
<2> 一个快指针一次走2步,一个慢指针一次走一步。
<3> 快指针先到链表尾部,而慢指针则恰好到达链表中部;
快指针到达链表尾部,当链表长度为奇数时,慢指针指向的就是链表中间节点。当链表长度为偶数时,慢指针指向的节点和慢指针指向节点的下一个节点都是链表的中间节点。
具体实现见代码:
#include <iostream>
typedef struct node
{
int data;
struct node *next;
} NODE;
NODE *create_end(int arr[], int len)
{
NODE *head = (NODE *)malloc(sizeof(NODE *));
head->next = NULL;
NODE *end = head;
for (int i = 0; i < len; i++) {
NODE *p = (NODE *)malloc(sizeof(NODE *)); // 也可用 new NODE();
p->data = arr[i];
end->next = p;
end = p;
}
end->next = NULL;
return head;
}
// 此方法适用于不带头节点的单链表的打印,对于带头节点的单链表要稍作处理。
void print(NODE *head)
{
if (head == NULL) return;
while (head != NULL) {
printf("%d ",head->data);
head = head->next;
}
}
// 寻找单链表的中间节点
// 当链表中有偶数个元素时,最中间的两个节点都可以算作中间节点;
// 但通过该方法查找到的是前面那个节点;如{1,2,3,4,5,6},通过该方法查找到的中间节点是3。
NODE *searchMid1(NODE *head)
{
NODE *temp = head;
NODE *mid = head;
while (head != NULL && head->next != NULL && head->next->next != NULL)
{
head = head->next->next;
temp = temp->next;
mid = temp;
}
return mid;
}
// 寻找单链表的中间节点(对searchMid1略作修改)
// 当链表中有偶数个元素时,最中间的两个节点都可以算作中间节点;
// 但通过该方法查找到的是后面那个节点;如{1,2,3,4,5,6},通过该方法查找到的中间节点是4。
NODE *searchMid2(NODE *head)
{
NODE *temp = head;
NODE *mid = head;
while (head != NULL && head->next != NULL)
{
head = head->next->next;
temp = temp->next;
mid = temp;
}
return mid;
}
// 寻找单链表的中间节点(length)
// 当链表中有偶数个元素时,最中间的两个节点都可以算作中间节点;
// 但通过该方法查找到的是后面那个节点;如{1,2,3,4,5,6},通过该方法查找到的中间节点是4。
NODE *searchMid3(NODE *head,int len)
{
NODE *p = NULL;
for (int i = 0; i < len / 2; i++) {
p = head->next;
head= head->next;
}
return p;
}
int main(int argc, const char * argv[]) {
int arr[] = {1,2,3,4,5,6,7,8};
int len = sizeof(arr)/sizeof(int);
NODE *head = create_end(arr, len);
// 因为创建的链表是带头节点的,所以此处打印要稍作处理;
NODE *first = head->next;
print(first);
printf("\n");
NODE *p1 = searchMid1(head->next);
printf("%d\n",p1->data);
NODE *p2 = searchMid2(head->next);
printf("%d\n",p2->data);
NODE *p3 = searchMid3(head->next, len);
printf("%d\n",p3->data);
return 0;
}
输出如下: