您的位置:首页 > 其它

寻找单链表的中间节点

2016-05-22 14:23 267 查看
思路:

(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\n",head->data);
head = head->next;
}
}

// 寻找单链表的中间节点
NODE *searchMid(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;
}

int main(int argc, const char * argv[]) {

int arr[] = {1,2,3,4,5,6,7};
int len = sizeof(arr)/sizeof(int);

NODE *head = create_end(arr, len);

// 因为创建的链表是带头节点的,所以此处打印要稍作处理;
NODE *first = head->next;
print(first);

printf("----------------------\n");

NODE *p = searchMid(head->next); // 传入首元节点作为参数
print(p); // 此处的打印结果,以中间节点开始。

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: