思想
声明两个指针r,h,开始位置都为头节点,然后向后移动,r的移动速度是h 的两倍(移动速度是指跨越的节点个数比如r = r->next->next跨越了两个节点,h = h->next,跨越了一个节点)当r到达链表尾部,那么h就刚好在链表的中间。
代码
#include <stdio.h>
#include <stdlib.h>
typedef struct Node{
int data;
struct Node *next;
}*Linklist,Node;
//创建头节点,创建链表
Linklist CreateHead(){
Linklist head;
head = (Linklist)malloc(sizeof(Node));
head->next = NULL;
return head;
}
//插入随机数据,这里插入奇数个,方便理解中间值
void InsertData(Linklist *L){
Linklist r,p;
int i;
r = (*L);
srand(time(NULL));
for(i = 0; i < 10; i++){
p = (Linklist)malloc(sizeof(Node));
p->data = rand()%100+1;
p->next = NULL;
r->next = p;
r = p;
}
}
void Disp(Linklist *L){
Linklist h;
int i = 1;
h = (*L);
while(h->next != NULL){
printf("%d %d \n",i++,h->next->data);
h = h->next;
}
printf("\n");
}
//通过快慢指针的方法求出中间值
void KuaiManZhiZheng(Linklist *L){
Linklist r,h;//声明两个一快一慢的指针
r = (*L);//初始位置都指向头节点
h = r;
while(1){
//这里并不知道总的节点个数为多少个,奇偶情况通过数学规律得出
//链表节点数为偶数时,快指针移动到最后时下个元素为空
if(r->next == NULL){
/*在这里我判定为他们两个都为中间值,其实也可以说节点为偶数个数
时并没有中间值*/
printf("中间值为%d和%d\n",h->data,h->next->data);
break;
}
//链表节点为奇数时,快指针移动到最后时下个的下个元素为空
if(r->next->next == NULL){
printf("中间值为%d\n",h->data);
break;
}
r = r->next->next;
h = h->next;
}
}
int main()
{
Linklist head;
head = CreateHead();
InsertData(&head);
Disp(&head);
KuaiManZhiZheng(&head);
return 0;
}