简单算法 - 找到链表的中间点和倒数第K个节点(普通方法和快慢指针方法开销一样)
2012-12-13 13:24
417 查看
1.1.1 单向链表的中间节点
思路一先遍历一次链表,得到链表长度,求出中间节点的位置,再从链表头开始遍历,直到找到中间节点的位置。
复杂度大概是O(3/2n),
思路二
设置两个指针从链表头节点开始往下遍历,其中一个指针一次往下走2个节点,一个指针一次往下走一个节点,当快的指针到达最后一个时,慢的指针正好到达中间的节点。
复杂度大概为O(n)
比较两个思路
思路一好比让一个人去找某一个路程的中间位置,思路二好比让两个人去找某一个路程的中间位置。
思路一,这个人需要走1.5倍路程就能找到中间点(假设他到达终点后可以马上到达起点)。
思路二,一个人走完了全程,另一个人走了半程,两个人加起来也是1.5倍的路程。
所以,从这个意思上讲,两个方法花销其实是一样的。
1.1.1 找到倒数第K个节点
思路一先遍历一次链表,得到链表长度,求出倒数第K的位置,再从链表头开始遍历,所以一共走了(2L-K)个节点。
思路二
和找到中间点思路有点相同,只是让一个指针先走K个节点,然后两个指针每次都走一个节点,当在前面的指针到达终点时,后面的指针正好在倒数第K个节点。所以也一共走了(2L-K)个节点。
所以两个方法复杂度也是一样的。
代码如下:
/* * * Introduction : reverse list * Author : Gykimo * Date : 20121212 * */ #include <stdio.h> #include <malloc.h> typedef struct Node{ int data; struct Node* next; }Node; #define LIST_LEN 12 //链表长度 Node * List = NULL; //链表 //找到链表的中间点 void find_median_ite(){ Node * fast = List;//每次走两个节点 Node * slow = List;//每次走一个节点 while(fast != NULL){ fast = fast->next; if(fast == NULL) break; fast = fast->next; slow = slow->next; } printf("the media is %d\n", slow->data); } void find_one_reverse(int seq){ Node * first = List; Node * second = List; int first_steps = seq; //first先走seq个节点 while(first != NULL && first_steps>0){ first = first->next; first_steps--; } //说明链表长度小于seq,所以不存在倒数第seq的节点 if(first_steps > 0){ printf("the %d node does not exist\n", seq); return; } while(first != NULL){ first = first->next; second = second->next; } printf("the %d node is %d\n", seq, second->data); } //生成链表 void make_list(){ List = (Node *)malloc(sizeof(Node) * LIST_LEN); int i = 0; for(i = 0; i < (LIST_LEN - 1); i++){ (List + i)->data = i + 1; (List + i)->next = List + i + 1; } (List + LIST_LEN - 1)->data = LIST_LEN; (List + LIST_LEN - 1)->next = NULL; } void print_list(){ Node * cur = List; while(cur!=NULL){ printf("%d ", cur->data); cur = cur->next; } printf("\n"); } int main(){ make_list(); print_list(); find_median_ite();//找到中间节点 find_one_reverse(4);//找到倒数第4个节点 }
相关文章推荐
- 输入一个链表,找到倒数第K个节点。使得只扫描一次链表。
- 经典算法学习——链表中倒数第k个节点
- 算法:查找链表中倒数第k个节点
- 【简单算法】22.删除链表的倒数第N个节点
- 20140719 找到单链表的倒数第K个节点 判断一个链表是否成为一个环形 反转
- 删除链表的倒数第K个节点(每日一道算法题)
- C++ 算法之 链表中倒数第k个节点
- 找出单向链表中倒数第k个节点的算法
- (算法)输出单链表的倒数第k个节点,删除特点的节点和从链表尾一次输出节点值
- 算法:查找链表中倒数第k个节点
- 剑指offer12--找到链表中倒数第k个节点
- 算法学习-----输出链表的倒数第k个节点
- 微软算法100题13 查找单向链表倒数第K个节点
- 算法学习之旅,初级篇(29)-–链表中倒数第k个节点
- 程序员面试100题(算法)之查找链表中倒数第k个节点(含单向链表的创建和打印)
- PHP获取链表中倒数第K个节点的方法
- 每天一个小算法(5)----找到链表倒数第K个结点
- 【算法之链表(一)】判断单链表中是否有环、环的长度、环的入口节点,单链表的倒数第K个节点等
- 左程云_算法与数据结构 — 链表问题 — 02在单链表和双链表中删除倒数第K个节点
- 算法与数据结构面试题(13)-求链表倒数第K个节点