【面试题】-求未知长度的链表的中间节点(快慢指针)
2015-06-11 16:59
471 查看
快慢指针
所谓的快慢指针的快慢是指指针向前移动的步长。比如在单链表中,快指针每次向前移动2个步长,慢指针则每次向前移动1个步长。解题思路
快速找出未知长度的链表的中间节点,暴力解法就是先遍历真个链表,算出链表的长度,再从头遍历长度的一半,即可找出,不过这个比较费时。更巧妙的办法是运用快慢指针,将快慢指针先指向头结点,快指针移动2个步长,慢指针移动1个步长,当快指针指向链表末尾的时候,慢指针刚好就在中间节点上。代码实现
1. 暴力解法
[code]void Find_mid(LinkList L) { LinkList p; int count, mid; int i = 0; if (L == NULL) { exit(ERROR); } p = L->next; count = 0; while (p) { count ++; p = p->next; } p = L->next; mid = count / 2 ; for (i = 0; i < mid; i++ ) { p = p->next; } printf("%d\n", p->data); }
2. 快慢指针
[code]void Find_mid2(LinkList L) { LinkList slow, fast; if (L == NULL) { exit(ERROR); } fast = slow = L; while(fast->next != NULL && fast->next->next != NULL){ slow = slow->next; fast = fast->next->next; } slow = slow->next; printf("%d\n", slow->data); }
测试代码
[code]#include <stdio.h> #include <stdlib.h> #include <time.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 typedef struct Node { int data; struct Node *next; } Node, *LinkList; /*随机产生n个元素的带表头的单链表(头插法)*/ void CreatList_Head(LinkList *L, int n) { LinkList p; int i; srand(time(0)); (*L) = (LinkList)malloc(sizeof(Node)); if (!(*L)) { exit(ERROR); } (*L)->next = NULL; for (i = 0; i < n; i++) { p = (LinkList)malloc(sizeof(Node)); if (!p) { exit(ERROR); } p->data = rand() % 100 + 1; p->next = (*L)->next; (*L)->next = p; } } /*随机产生n个元素的带表头的单链表(尾插法)*/ void CreatList_Tail(LinkList *L, int n) { LinkList p, r; int i; srand(time(0)); (*L) = (LinkList)malloc(sizeof(Node)); if (!(*L)) { exit(ERROR); } r = (*L); for (i = 0; i < n; i++) { p = (LinkList)malloc(sizeof(Node)); if (!p) { exit(ERROR); } p->data = rand() % 100 + 1; r->next = p; r = p; } r->next = NULL; } void Print_List(LinkList L) { LinkList p; if (!L) { exit(ERROR); } p = L->next; while (p) { printf("%d ", p->data); p = p->next; } printf("\n"); } void Print_List_noHead(LinkList L) { LinkList p; if (!L) { exit(ERROR); } p = L; while (p) { printf("%d ", p->data); p = p->next; } printf("\n"); } void Find_mid(LinkList L) { LinkList p; int count, mid; int i = 0; if (L == NULL) { exit(ERROR); } p = L->next; count = 0; while (p) { count ++; p = p->next; } p = L->next; mid = count / 2 ; for (i = 0; i < mid; i++ ) { p = p->next; } printf("%d\n", p->data); } void Find_mid2(LinkList L) { LinkList slow, fast; if (L == NULL) { exit(ERROR); } fast = slow = L; while(fast->next != NULL && fast->next->next != NULL){ slow = slow->next; fast = fast->next->next; } slow = slow->next; printf("%d\n", slow->data); } int main(int argc, char const *argv[]) { LinkList L; CreatList_Head(&L, 11); Print_List(L); Find_mid(L); Find_mid2(L); return 0; }
相关文章推荐
- 性能测试面试题汇总(二)
- 一个合格的程序员应该读过哪些书[会不会被吓到? :)]
- 性能测试面试题汇总(一)
- 面试:如何测试一个杯子
- 黑马程序员——java基础-集合
- 谈谈对程序员的培养
- 面试知识点笔记
- 黑马程序员——基础篇——多线程
- 面试题 47
- 黑马程序员---IOS基础---OC 中无参与有参方法声明实现及调用
- 程序员职业规划发展路线图
- 职业选择--再温《HP大中华区总裁孙振耀退休感言》(终)
- 挖一坑,为以后面试做准备。ssh ssi框架的各种优缺点 和概念、流程
- 黑马程序员——java基础-String类和基本数据类型包装类
- 面试题三
- 面试题二
- 职业规划的一些想法
- 面试题一
- sql面试题(学生表_课程表_成绩表_教师表)
- 转载 -- 一个平庸程序员的自白