博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C — 用单向循环链表完成“类约瑟夫环”问题
阅读量:7071 次
发布时间:2019-06-28

本文共 4693 字,大约阅读时间需要 15 分钟。

问题概述

有 n 个人围坐成一圈,其编号为从 1 到 n 的递增数列,每个人有一个正整数密码。先选定一个任意正整数 m,并从 1 号开始报 1,2号报 2,以此类推,报到 m 时停止,该人出局,并把他的密码作为新的 m 值。重复该过程,直到所有人出局,求出局人编号顺序。

修改前代码

#include 
#include
typedef struct node { int number; int password; struct node *next;} node;node *createCircularLinkedList(int n) { node *temp = NULL; node *head = (node *) malloc(sizeof(node)); head->next = head; // Necessary when n == 1; temp = head; for (int i = 0; i < n - 1; ++i) { temp->next = (node *) malloc(sizeof(node)); temp = temp->next; temp->next = NULL; } temp->next = head; return head;}int inputCircularLinkedList(node *head) { if (NULL == head) // If a blank linked list. return 0; node *temp = head; int count = 0; int password; count = 1; do { scanf("%d", &password); temp->password = password; temp->number = count++; temp = temp->next; } while (temp != head); return 1;}int printCircularLinkedList(node *head) { // Just for test. if (NULL == head) // If a blank linked list. return 0; node *temp = head; do { printf("%d-%d\n", temp->number, temp->password); temp = temp->next; } while (temp != head); return 1;}node *rearOfCircularLinkedList(node *head) { node *p = NULL; if (NULL == head) // If a blank linked list. return 0; p = head; while (p->next != head) p = p->next; return p;}node *deleteNodeOfCircularLinkedList(node *head, node *del) { if (NULL == head) // If a blank linked list. return 0; node *pre = head; while (pre->next != del) pre = pre->next; if (pre->next == head) { head = head->next; } pre->next = del->next; free(del); return head;}int main() { int n = 0, m = 0, password = 0; node *head = NULL; // Create a blank linked list. printf("Please input m:\n"); scanf("%d", &m); printf("Please input n:\n"); scanf("%d", &n); head = createCircularLinkedList(n); printf("Please input password:\n"); inputCircularLinkedList(head); printf("Data received:\n"); printCircularLinkedList(head); printf("Answer:\n"); node *p = head; node *pCopy = NULL; int count = 0; while (n > 0) { for (int i = 0; i < m-1; ++i) { p = p->next; } // P should out. printf("%d out\n", p->number); pCopy = p; m=p->password; p = p->next; head = deleteNodeOfCircularLinkedList(head, pCopy); n--; } return 0;}

代码问题

  1. 循环链表只需要有指针指向其即可,不需要固定头指针或尾指针。

  2. 删除函数又重复遍历了一遍链表,效率低下。

  3. 当密码为很大的数字时,可以用取余来提高效率。

修改后代码

#include 
#include
typedef struct node { int number; int password; struct node *next;} node;node *nodePioneerOfCll(int m, node *p) { for (int i = 0; i < m - 1; ++i) { p = p->next; } // (p+1) - out. printf("%d - out\n", p->next->number); return p;}node *rearOfCll(node *p) { while (p->next->number != 1) { p = p->next; } return p;}node *createCll(int n) { node *temp = NULL; node *head = (node *) malloc(sizeof(node)); head->next = head; // n == 1 temp = head; for (int i = 0; i < n - 1; ++i) { temp->next = (node *) malloc(sizeof(node)); temp = temp->next; temp->next = NULL; } temp->next = head; // 尾元素指向头指针 return head;}int inputCll(node *p) { if (NULL == p) return 0; node *temp = p; int count = 1; do { scanf("%d", &temp->password); temp->number = count++; temp = temp->next; } while (temp != p); return 1;}int printCll(node *p) { if (NULL == p) return 0; node *temp = p; do { printf("%d-%d\n", temp->number, temp->password); temp = temp->next; } while (temp != p); return 1;}int deleteNextNodeOfCll(node *p) { if (NULL == p) return 0; node *del = p->next; p->next = p->next->next; int m = del->password; free(del); return m;}int main() { int n = 0, m = 0, password = 0; printf("Please input m:\n"); scanf("%d", &m); // 输入m值 printf("Please input n:\n"); scanf("%d", &n); // 输入n值 node *p = createCll(n); // 创建有n元循环链表 printf("Please input password:\n"); inputCll(p); // 输入密码 printf("Data received:\n"); printCll(p); // 反显密码 printf("Answer:\n"); p = rearOfCll(p); // p移到尾 for (; n > 0; n--) { p = nodePioneerOfCll(m % n ? m % n : n, p); // 移到待删节点前驱 m = deleteNextNodeOfCll(p); // 删除p后继 } return 0;}

转载地址:http://rrkml.baihongyu.com/

你可能感兴趣的文章
Python 的经典设计格言,格言来源于 Python 但不限于 Python
查看>>
python random模块
查看>>
数据流中的中位数(未)
查看>>
利用xss偷cookie教學
查看>>
CentOS 安装过程【图片】
查看>>
深入Hadoop节点部署的策略
查看>>
linux驱动编译常见错误记录
查看>>
Android设备路径及容量的读取
查看>>
Cocos2d-x3.0模版容器详解之三:cocos2d::Value
查看>>
循环引用问题
查看>>
Linux DNS正向解析和反向解析配置实例(一)
查看>>
Google已经获得www.baidu.com.sb域名
查看>>
React Router
查看>>
c语言:将三个数按从大到小输出。
查看>>
WMI-Win32_PhysicalMemory 内存条参数
查看>>
常用的ICON图标网站
查看>>
深入分析Sleep(0)与Sleep(1)的区别
查看>>
nsq使用的TOML配置文件规范文档中文版
查看>>
Linux6.0命令界面与图形界面的切换
查看>>
Linux系统启动5个阶段
查看>>