《关于建立了一年的博客终于打算动手——关于约瑟夫环的链表实现》
这是《数据结构(c语言)》的一次简单记录
第一次实验课是用链表完成了约瑟夫环
然后课上写完以后差点摸鱼被抓(写代码的事情能叫摸鱼吗(大声
其实链表也是有难点的,对于初学者来说可能链表抽象的地方就是:L = L -> next这里。
首先 L 是一个节点指针,里面的节点储存了数据和下一个节点的坐标。
L = L -> next其实就是让指针L指向L储存的下一个节点。
例如存在一个链表head -> 1 -> 2 -> 3 -> 4
L = head -> next (这里可以看出来,L此刻指向了1)
那么我们换一种写法
L= head;
L= L-> next(这里是不是就是和上面语句的作用是一样的呢,现在L的指向节点1)
让我们在操作一次
L= L ->next (这里就是由1 指向了2)
由这个例子我们就可以直观的明白了L = L->next的意思了
来,试试看(
以下就是上课水的代码了
1 #include <stdio.h> 2 #include <stdlib.h> //包含malloc和free 3 #include <stdbool.h> //引入bool 4 typedef int Elem; //定义链表中的元素类型 5 typedef struct List List; //快捷定义struct List 6 7 typedef struct List 8 { 9 Elem data; //储存数据 10 List* next; //储存下一个节点地址 11 } List; 12 13 void InitList(List* L) 14 { 15 L->next = L; //让头节点跟着的地址变为头指针; 16 L->data = 0; //在头节点中储存该链表的长度 17 } 18 bool addList(List* L, int i, Elem data) //i为插入位置,data为插入的数据 19 { 20 List* e = (List*)malloc(sizeof(List)); //为即将插入的节点申请内存空间 21 if (i <= 0 && i > L->data) //如果插入位置非法则返回false 22 return false; 23 (L->data)++; //链表长度加一 24 for (int j = 1; j < i; j++) //循环到(i-1)的位置 25 { 26 L = L->next; //每次循环指针都移动到下一个位置 27 } 28 e->data = data; //将数据存入待插入节点中 29 e->next = L->next; //e -> next = 原先第i个节点的地址 (原链表中的第i个节点变为了第(i+1)个节点) 30 L->next = e; // L -> next = 待插入的节点的地址 ((i-1)-> next = e) e变成了第i个节点 31 return true; 32 } 33 34 void allList(List* L) 35 { 36 int len = L->data; //记录链表长度 37 for (int i = 1; i <= len; i++) 38 { 39 L = L->next; 40 printf("%d ", L->data); 41 } 42 printf("\n"); 43 } 44 void Josephus(List* L, int m, int k) //从第m个人开始报数,报出k时退出 45 { 46 int len = L->data, num = 1; //记录长度,初始化计数器 47 List* head = L; //记录头指针地址 48 for (int i = 1; i < m; i++) // 因为是单向链表,为了后面删除方便让指针指向第(m-1)个元素 49 { 50 L = L->next; 51 if (head == L) { //当指向头指针时,跳过头指针 52 L = L->next; 53 } 54 55 } 56 /*以第二次循环为例*/ 57 //此时指针指向3,且计时器(num == 2) 与k相等 58 while (len) { //当链表长度为0是跳出循环 59 if (head == L) { 60 L = L->next; 61 continue; //跳过头指针且不让计数器增加 62 } 63 if (num == k) //如果计数器与k相等 64 { 65 List* empty = (List*)malloc(sizeof(List)); //申请临时空间储存被删除的节点 66 empty = L->next; //empty此时指向了4 67 if (empty == head) //如果empty指向头节点,跳过头节点指向下一个位置 68 { 69 empty = empty->next; 70 L = L->next; 71 } 72 printf("出局编号为:%d\n", empty->data); //输出出局的编号 73 L->next = empty->next; // 3 -> next = 4->next (1->2->3->5) 74 num = 1; //计数器归一 75 len--; //链表长度减一 76 free(empty); //释放4 77 } 78 L = L->next; //指针右移一 79 num++; //计数器加一 80 } 81 } 82 int main() 83 { 84 List L; 85 int x; 86 InitList(&L); //创建链表 87 for (int i = 1,j = 1; i <= 5; i++) //添加链表中的元素 88 { 89 addList(&L, i, i); //该部分可以自行修改参数 90 } 91 allList(&L); //输出链表中的所有元素 92 Josephus(&L, 3, 2); //约瑟夫环 m = 3 k = 2 93 return 0; 94 }
(菜鸡发言

浙公网安备 33010602011771号