1. 约瑟夫环 1.1 实验内容 约瑟夫(Joseph)问题的一种描述是:编号为 1, 2, …, n 的 n 个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。开始任选一个正整数作为报数上限值 m,从第一个人开始按顺时针方向自 1 开始顺序报数,报到 m 时停止报数。报 m 的人出列,将他的密码作为新的 m 值,从他在顺时针方向上的下一个人开始重新从 1 报数,如此下去,直至所有人全部出列为止。试设计一个程序求出出列顺序。
1.2 实验目的 掌握链表的基本操作:插入、删除、查找等运算,能够灵活应用链表这种数据结构。
1.3 程序清单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 #include <stdio.h> #include <stdlib.h> typedef struct node_s { int id; struct node_s *next ; } node_t ;node_t * create_node (int id) { node_t *node = (node_t *)calloc (1 , sizeof (node_t )); if (node == NULL ) { printf ("ERROR: Failed to create new node;\r\n" ); exit (1 ); } node->id = id; node->next = NULL ; return node; }int main () { int n; int m; node_t *head = NULL ; node_t *tail = NULL ; if (scanf ("%d %d" , &n, &m) != 2 || n <= 0 || m <= 0 ) { printf ("ERROR: Invalid parameter;\r\n" ); return -1 ; } for (int i = 1 ; i <= n; i++) { node_t *node = create_node(i); if (head == NULL ) { head = node; tail = node; } else { tail->next = node; tail = node; } } tail->next = head; node_t *curr = head; node_t *prev = tail; while (n > 0 ) { for (int i = 1 ; i < m; i++) { prev = curr; curr = curr->next; } printf ("%d" , curr->id); prev->next = curr->next; node_t *temp = curr; curr = curr->next; free (temp); n--; if (n > 0 ) { printf (" " ); } } printf ("\r\n" ); return 0 ; }
1.4 调试步骤
输入测试数据
程序输出
1.5 分析与思考 设人数为 n,初始密码为 m。
空间复杂度:$O(n \cdot m)$
时间复杂度:$O(n)$
2. 重排链表 2.1 实验内容 给定一个单链表 $L_1 \to L_2 \to \cdots \to L_{n-1} \to L_n$ ,请编写程序将链表重新排列为 $L_n \to L_1 \to L_{n-1} \to L_2 \to \cdots$ 。
例如:给定L为 $1 \to 2 \to 3 \to 4 \to 5 \to 6$ ,则输出应该为 $6 \to 1 \to 5 \to 2 \to 4 \to 3$ 。
2.2 实验目的 掌握链表的基本操作:插入、删除、查找等运算,能够灵活应用链表这种数据结构。
2.3 程序清单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 #include <stdio.h> #include <stdlib.h> #define MAX_ADDR 100000 typedef struct node_s { int addr; int value; struct node_s *next ; } node_t ;node_t * create_node (int addr, int value) { node_t *node = (node_t *)calloc (1 , sizeof (node_t )); if (node == NULL ) { printf ("ERROR: Failed to create new node;\r\n" ); exit (1 ); } node->addr = addr; node->value = value; node->next = NULL ; return node; }void print_list (node_t *head) { if (head == NULL ) { return ; } while (head != NULL ) { printf ("%05d %d " , head->addr, head->value); if (head->next != NULL ) { printf ("%05d\r\n" , head->next->addr); } else { printf ("-1\r\n" ); } head = head->next; } }node_t * reorder_list (node_t *head) { if (head == NULL || head->next == NULL ) { return NULL ; } node_t *slow = head; node_t *fast = head->next; while (fast != NULL && fast->next != NULL ) { slow = slow->next; fast = fast->next->next; } node_t *head_1 = head; node_t *head_2 = slow->next; slow->next = NULL ; node_t *prev = NULL ; node_t *curr = head_2; while (curr != NULL ) { node_t *temp = curr->next; curr->next = prev; prev = curr; curr = temp; } head_2 = prev; node_t dummy; node_t *tail = &dummy; dummy.next = NULL ; while (head_1 != NULL || head_2 != NULL ) { if (head_2 != NULL ) { tail->next = head_2; head_2 = head_2->next; tail = tail->next; } if (head_1 != NULL ) { tail->next = head_1; head_1 = head_1->next; tail = tail->next; } } return dummy.next; }int main () { int n; int first_addr; scanf ("%d %d" , &first_addr, &n); int data[MAX_ADDR]; int next_addr[MAX_ADDR]; int valid[MAX_ADDR] = { 0 }; for (int i = 0 ; i < n; i++) { int addr, val, nxt; scanf ("%d %d %d" , &addr, &val, &nxt); data[addr] = val; next_addr[addr] = nxt; valid[addr] = 1 ; } node_t *head = NULL ; node_t *tail = NULL ; int cur = first_addr; while (cur != -1 && valid[cur]) { node_t *node = create_node(cur, data[cur]); if (!head) { head = tail = node; } else { tail->next = node; tail = node; } cur = next_addr[cur]; } head = reorder_list(head); print_list(head); node_t *temp; while (head != NULL ) { temp = head; head = head->next; free (temp); } return 0 ; }
2.4 调试步骤
输入测试数据
1 2 3 4 5 6 7 00100 6 00000 4 99999 00100 1 12309 68237 6 -1 33218 3 00000 99999 5 68237 12309 2 33218
程序输出
1 2 3 4 5 6 68237 6 00100 00100 1 99999 99999 5 12309 12309 2 00000 00000 4 33218 33218 3 -1
2.5 分析与思考
空间复杂度:$O(n)$
时间复杂度:$O(n)$