寻找单链表的中间节点
2016-05-22 14:23
267 查看
思路:
(1)首先求解单链表的长度length,然后遍历 length / 2 的距离即可查到单链表的中间节点,但一般此种方法需要遍历两次链表,第一次遍历求解单链表的长度,第二次遍历根据索引获取中间节点。
(2)如果是双向链表,可以首尾并行,利用两个指针一个从头到尾,一个从尾到头,当两个指针相遇的时候,就找到中间元素。以此思想为基础,进一步思考,单链表也可以采用双指针的方式来实现中间节点的快速查找。但双指针的使用和双向链表不同,具体如下:
<1> 有2个指针同时从头开始遍历;
<2> 一个快指针一次走2步,一个慢指针一次走一步。
<3> 快指针先到链表尾部,而慢指针则恰好到达链表中部;
快指针到达链表尾部,当链表长度为奇数时,慢指针指向的就是链表中间节点。当链表长度为偶数时,慢指针指向的节点和慢指针指向节点的下一个节点都是链表的中间节点。
具体实现见代码:
(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; }
相关文章推荐
- 再谈深度学习文本的表示
- 学习SpringMVC
- 鸡兔同笼共有15只 脚有四十只
- javaScript Uncaught reference error: $ is not defined error
- jsp页面 utf-8 向后台传值乱码(spring)
- 传智.燕青Mybatis教程二(高级映射)
- Android某些机型上面无法获取图片路径。
- 配置vsftpd配合filezilla使用
- 常用mysql数据库引擎——MyISAM和InnoDB区别
- 使用aidl工具快速在应用层实现binder进程间通信
- <s:iterator>及<s:property>的用法
- JDK并发工具包CompletionService和ExecutorCompletionService的好处和使用场景
- Git创建一个自己的本地仓库
- java特殊转义字符 \\[] \\|(分隔符)
- 【Spring Framework 深入】—— IoC容器初始化 -> Bean定义资源的Resource定位
- 1/2 2/3 3/5 5/8...前二十项之和
- Maven之(三)Maven插件
- Maven之(四)Maven命令
- 驱动Makefile
- [疯狂Java]基础类库:Random(随机数生成)、ThreadLocalRandom(线程安全随机数生成)