/** * Implement an algorithm to find the nth to last element of a singly linked list */ #include <stdio.h> #include <stdlib.h> typedef struct link { int value; struct link *next; } link; /** * 创建单链表 * * T = O(n) * */ void createLinklist(link **head, int data) { link *pre, *cur, *new; cur = *head; pre = NULL; while (cur != NULL) { pre = cur; cur = cur->next; } new = (link *)malloc(sizeof(link)); new->value = data; if (pre == NULL) *head = new; else pre->next = new; } /** * 打印单链表 * * T = O(n) */ void printLinklist(link *head) { while (head->next != NULL) { printf("%d ", head->value); head = head->next; } printf("%d\n", head->value); } /** * 寻找单链表倒数第m个节点 * * T = O(n) * */ void findMthToLast(link *head, int m) { if (head == NULL) return; link *s1, *s2; int i; // s1指向表头,s2指向从s1开始后m个元素的位置,然后s1与s2同时后移,到s2为NULL时停止,s1为mth to last s1 = s2 = head; for (i = 0; i < m; i ++) { s2 = s2->next; } while (s2 != NULL) { s1 = s1->next; s2 = s2->next; } printf("%d\n", s1->value); } int main(void) { int i, n, m, data; link *head; while (scanf("%d", &n) != EOF) { for (i = 0, head = NULL; i < n; i ++) { scanf("%d", &data); createLinklist(&head, data); } // 接收mth to last scanf("%d", &m); if (m > n) { printf("输入数据有误!\n"); } else { printLinklist(head); findMthToLast(head, m); } } return 0; }
/** * Given a circular linked list, implement an algorithm which returns * node at the begining of the loop */ #include <stdio.h> #include <stdlib.h> typedef struct link { int value; struct link *next; } link; /** * 创建单链表 * * T = O(n) * */ void createLinklist(link **head, int data) { link *cur, *pre, *new; cur = *head; pre = NULL; while (cur != NULL) { pre = cur; cur = cur->next; } new = (link *)malloc(sizeof(link)); new->value = data; new->next = cur; if (pre == NULL) { *head = new; } else { pre->next = new; } } /** * 从m个节点开始构建循环链表 * * T = O(n) * */ void initLoopList(link *head, int m) { link *cur, *pre, *target; cur = head; while (-- m && cur != NULL) { cur = cur->next; } target = cur; while (cur != NULL) { pre = cur; cur = cur->next; } pre->next = target; } /** * 寻找循环开始点的value * * T = O(n) * */ void loopStart(link *head) { link *fast, *slow, *p, *q; int i, len; for (slow = head, fast = slow->next->next; fast != slow;) { slow = slow->next; fast = fast->next->next; } for (len = 1, slow = slow->next; slow != fast; slow = slow->next) { len += 1; } p = q = head; for (i = 0; i < len; i ++) { q = q->next; } while (p != q) { p = p->next; q = q->next; } printf("%d\n", q->value); } int main(void) { link *head; int i, n, m, data; while (scanf("%d", &n) != EOF) { // 创建单链表 for (i = 0, head = NULL; i < n; i ++) { scanf("%d", &data); createLinklist(&head, data); } // 第m个点开始循环 scanf("%d", &m); if (m > n) continue; initLoopList(head, m); // 查找循环起始节点(只提供头节点) loopStart(head); } return 0; }