面试题:快速找到未知长度单链表的中间节点?
这个问题的解决方法分为普通方法和高级方法。
1.普通方法即我们大家都能一下子想到的,首先遍历一遍获取总长度L,然后再次遍历循环至L/2即可;时间复杂度为:
O(L+L/2)=O(3/2L)
代码简单实现:
typedef struct { int data; LNode *next; }LNode,*LinkList; /* function:普通方法 首先遍历一遍获取总长度L,然后再次遍历循环至L/2即可 */ LNode *getElement(LinkList L) { if (L == NULL) { return NULL; } int i = 1; LNode *p = L->next; while (p!=NULL) { p = p->next; i++; } int j = 1; int mid = i / 2; LNode *midNode = L->next; while (j<mid) { midNode = midNode->next; } return midNode; }
2.高级方法:快慢指针法,设置2个指针*faster,*mid都指向单链表的头节点,其中faster移动的速度为mid的2倍,当faster移动到末尾,mid即在中间位置了,以下是简单实现:
/* function:快速查找未知长度单链表中间节点 快慢指针法 */ LNode *fasterGetElement(LinkList L) { LNode *mid, *faster; mid = L->next; faster = L->next; while (faster!=NULL) { mid = mid->next; //faster = faster->next->next faster = faster->next; faster = faster->next; } return mid; }