javascript循环链表之约瑟夫环的实现方法


Posted in Javascript onJanuary 16, 2017

前言

传说在公元1 世纪的犹太战争中,犹太历史学家弗拉维奥·约瑟夫斯和他的40 个同胞被罗马士兵包围。犹太士兵决定宁可自杀也不做俘虏,于是商量出了一个自杀方案。他们围成一个圈,从一个人开始,数到第三个人时将第三个人杀死,然后再数,直到杀光所有人。约瑟夫和另外一个人决定不参加这个疯狂的游戏,他们快速地计算出了两个位置,站在那里得以幸存。写一段程序将n 个人围成一圈,并且第m个人会被杀掉,计算一圈人中哪两个人最后会存活。使用循环链表解决该问题。

看到这个问题首先想到的是要用到循环链表,还有就是要计算链表中有多少个元素,这两点很重要。再有就是找到当前节点和在链表中向前移动m个节点。下面一一分析:循环链表很容易实现,就是初始化的时候使链表的头节点的下一个指向它自己,这样初始化一个空节点,注意链表的头不是节点。写法如下:this.head.next = this.head;计算链表中有多少个元素也很简单,只需要找到头节点,然后往下走直到再次回到头结点

代码如下:

var node = this.head;
var i = 0;
while (!(node.next.element == "head")){
 node = node.next;
 i++;
}
return i;

在初始化链表的时候我们定义一个当前节点,将它赋值为头节点this.currentNode = this.head; ,这样在移动节点的时候就可以用它指向下一个节点。向前移动节点的时候有个地方需要注意,如果当前移动到头节点上需要再向前移动一个节点this.currentNode.next.next

代码如下:

while (n>0){
 if(this.currentNode.next.element == "head"){
 this.currentNode = this.currentNode.next.next;
 }else{
 this.currentNode = this.currentNode.next;
 } 
 n--;
}

代码实现

/**
 * 使用循环链表实现解决约瑟夫环问题
 * */

//链表节点
function Node(element){
 this.element = element;
 this.next = null;
}

//定义链表类
function LList(){
 this.head = new Node("head");
 this.head.next = this.head;
 this.find = find;
 this.insert = insert;
 this.findPrevious = findPrevious;
 this.remove = remove;
 this.currentNode = this.head;
 //从链表当前节点向前移动n个节点
 this.advance = advance; 
 //当前链表中有多少个元素
 this.count = count;
 this.display = display;
}

//查找节点
function find(item){
 var currNode = this.head;
 while (currNode.element != item){
 currNode = currNode.next;
 }
 return currNode;
}

//插入新节点
function insert(newElement, item){
 var newNode = new Node(newElement);
 var current = this.find(item);
 newNode.next = current.next;
 current.next = newNode;
}

//查找当前节点的上一个节点
function findPrevious(item){
 var currNode = this.head;
 while (!(currNode.next == null) && (currNode.next.element != item)){
 currNode = currNode.next;
 }
 return currNode;
}

//移除当前节点
function remove(item){
 var prevNode = this.findPrevious(item);
 if(!(prevNode.next == null)){
 prevNode.next = prevNode.next.next;
 }
}

//向前移动n个节点
function advance(n){
 while (n>0){
 if(this.currentNode.next.element == "head"){
  this.currentNode = this.currentNode.next.next;
 }else{
  this.currentNode = this.currentNode.next;
 } 
 n--;
 }
}

//当前链表中有多少个元素
function count(){
 var node = this.head;
 var i = 0;
 while (!(node.next.element == "head")){
 node = node.next;
 i++;
 }
 return i;
}

//输出所有节点
function display(){
 var currNode = this.head;
 while (!(currNode.next == null) && !(currNode.next.element == "head")){
 document.write(currNode.next.element + " ");
 currNode = currNode.next;
 }
}

var person = new LList();
person.insert('1','head');
person.insert('2', '1');
person.insert('3', '2');
person.insert('4' , '3');
person.insert('5' , '4');
person.insert('6' , '5');
person.insert('7' , '6');
person.insert('8' , '7');
person.insert('9' , '8');
person.insert('10' , '9');


person.display();
document.write('<br>');


var n = 3;
while (person.count() > 2){
 person.advance(n);
 person.remove(person.currentNode.element);
 person.display();
 document.write('<br>');
}

这里我们假设有10个人,每次数到第三个人的时候这个人自杀,最后输出的结果如下:

最后结果是约瑟夫和他的同伴一个站在队伍的第4个,一个站在队伍的第10个,最后只剩下他们两个人。不知道历史上有没有这件事,如果真的有这件事,在这么短的时间内解决这个问题,约瑟夫真他么是个天才,不知道当时他有没有用指针来解决这个问题,还是用普通的数组递归解决。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

Javascript 相关文章推荐
firefox中用javascript实现鼠标位置的定位
Jun 17 Javascript
不使用XMLHttpRequest实现异步加载 Iframe和script
Oct 29 Javascript
IE6-IE9中tbody的innerHTML不能赋值的解决方法
Sep 26 Javascript
浅析上传头像示例及其注意事项
Dec 14 Javascript
jQuery插件autocomplete使用详解
Feb 04 Javascript
原生js仿浏览器滚动条效果
Mar 02 Javascript
详解vue-cli 脚手架项目-package.json
Jul 04 Javascript
js提取中文拼音首字母的封装工具类
Mar 12 Javascript
微信小程序实现跑马灯效果
Oct 21 Javascript
详解JavaScript修改注册表的方法
Jan 05 Javascript
vue 组件销毁并重置的实现
Jan 13 Javascript
实例讲解JavaScript 计时事件
Jul 04 Javascript
函数四种调用模式以及其中的this指向
Jan 16 #Javascript
js实现导航栏中英文切换效果
Jan 16 #Javascript
Bootstrap面板使用方法
Jan 16 #Javascript
codeMirror插件使用讲解
Jan 16 #Javascript
微信小程序 图片边框解决方法
Jan 16 #Javascript
微信小程序 scroll-view隐藏滚动条详解
Jan 16 #Javascript
微信小程序 video详解及简单实例
Jan 16 #Javascript
You might like
精致的人儿就要挑杯子喝咖啡
2021/03/03 冲泡冲煮
Adodb的十个实例(清晰版)
2006/12/31 PHP
ThinkPHP CURD方法之table方法详解
2014/06/18 PHP
php常用的url处理函数总结
2014/11/19 PHP
php中文乱码问题的终极解决方案汇总
2017/08/01 PHP
JavaScript高级程序设计 读书笔记之十一 内置对象Global
2012/03/07 Javascript
js arguments对象应用介绍
2012/11/28 Javascript
用box固定长宽实现图片自动轮播js代码
2014/06/09 Javascript
Jquery动态添加及删除页面节点元素示例代码
2014/06/16 Javascript
JS自定义对象实现Java中Map对象功能的方法
2015/01/20 Javascript
jQuery实现可编辑的表格实例讲解(2)
2015/09/17 Javascript
nodeJs爬虫获取数据简单实现代码
2016/03/29 NodeJs
js和jq使用submit方法无法提交表单的快速解决方法
2016/05/17 Javascript
详解JavaScript权威指南之对象
2016/09/27 Javascript
浅谈js闭包理解
2019/03/28 Javascript
Python函数参数操作详解
2018/08/03 Python
Python中Proxypool库的安装与配置
2018/10/19 Python
详解pandas安装若干异常及解决方案总结
2019/01/10 Python
Python中字符串与编码示例代码
2019/05/20 Python
解决pycharm 工具栏Tool中找不到Run manager.py Task的问题
2019/07/01 Python
Python 实现输入任意多个数,并计算其平均值的例子
2019/07/16 Python
解决django model修改添加字段报错的问题
2019/11/18 Python
python元组的概念知识点
2019/11/19 Python
通过 Python 和 OpenCV 实现目标数量监控
2020/01/05 Python
基于python SMTP实现自动发送邮件教程解析
2020/06/02 Python
HTML5在微信内置浏览器下右上角菜单的调整字体导致页面显示错乱的问题
2021/01/19 HTML / CSS
SHEIN香港:价格实惠的女性时尚服装
2018/08/14 全球购物
LivingSocial英国:英国本地优惠
2019/02/22 全球购物
Holland & Barrett爱尔兰:英国领先的健康零售商
2019/03/31 全球购物
台湾三立电视电商平台:电电购
2019/09/09 全球购物
远程教育心得体会
2014/01/03 职场文书
学校党员对照检查材料
2014/08/28 职场文书
应届毕业生求职信范文
2015/03/19 职场文书
《自己去吧》教学反思
2016/02/16 职场文书
Java实战之用Swing实现通讯录管理系统
2021/06/13 Java/Android
java版 联机五子棋游戏
2022/05/04 Java/Android