算法思路
1. 求链表总长度,取得一半数,遍历链表一半的数量,取得中间节点
2. 用两个指针,一个每次都移动一回,一个每两次移动一回,当第一个指针遍历完链表,后一个指针就正好指向中间
代码实现1
st_dataNode * getListMidNode(st_dataNode * head){
if(NULL == head){
printf("%s: param error\n",__func__);
return NULL;
}
int len = 0;
int m = 0;
st_dataNode * mid = NULL;
len = getListLen(head);
m = (len / 2 - 1); // 注意应该建议,因为下标是从0开始的
if(m == 0){
return head;
}
mid = head;
while(m > 0){
mid = mid->next;
m--;
}
return mid;
}
代码实现2
/* 通过一次遍历来完成寻找中间节点 */
st_dataNode * getListMidNode2(st_dataNode * head){
if(NULL == head){
printf("%s: param error\n",__func__);
return NULL;
}
int step1 = 0, step2 = 0;
st_dataNode * cur = NULL, * mid = NULL;
cur = mid = head;
while(NULL != cur){
if(step2 /2 > step1){ /* cur 移动两步,mid 移动一步*/
mid = mid->next;
step1++;
}
cur = cur->next;
step2++;
}
return mid;
}
void testGetListMidNode2(void){
st_dataNode * mid = NULL;
mid = getListMidNode(ghead);
printf("======== Mid2 Node %p, data: %d==========\n", mid, mid->data);
return;
}
调试编译
gcc listMain.c list.c -o a.exe -DDEBUG
调试输出
========= Dump List 0x2150010 ===========
22 32 19 53 0 47 29 116 4 6
===================================
List length = 10
======== Mid Node 0x2150090, data: 0==========
======== Mid2 Node 0x2150090, data: 0==========