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 相关文章推荐
如何使用jQuery Draggable和Droppable实现拖拽功能
Jul 05 Javascript
JSF中confirm弹出框的用法示例介绍
Jan 07 Javascript
javascript使用prototype完成单继承
Dec 24 Javascript
Node.js事件驱动
Jun 18 Javascript
Node.js插件安装图文教程
May 06 Javascript
jQuery EasyUI API 中文帮助文档和扩展实例
Aug 01 Javascript
js实现按钮控制带有停顿效果的图片滚动
Aug 30 Javascript
详解Node.Js如何处理post数据
Sep 19 Javascript
Javascript 正则表达式校验数字的简单实例
Nov 02 Javascript
解决vue页面DOM操作不生效的问题
Mar 17 Javascript
JS实现获取当前所在周的周六、周日示例分析
May 11 Javascript
node.js Promise对象的使用方法实例分析
Dec 26 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
php中json_encode中文编码问题分析
2011/09/13 PHP
PHP内置的Math函数效率测试
2014/12/01 PHP
PHP入门教程之数学运算技巧总结
2016/09/11 PHP
JavaScript游戏之优化篇
2010/11/08 Javascript
JavaScript类型转换方法及需要注意的问题小结(挺全面)
2010/11/11 Javascript
JavaScript实现网页上的浮动广告的简单方法
2013/06/14 Javascript
用innerhtml提高页面打开速度的方法
2013/08/02 Javascript
JS实现的用来对比两个用指定分隔符分割的字符串是否相同
2014/09/19 Javascript
jQuery UI插件自定义confirm确认框的方法
2015/03/20 Javascript
用户代理字符串userAgent可实现的四个识别
2015/09/20 Javascript
javascript实现checkbox复选框实例代码
2016/01/10 Javascript
Bootstrap表单组件教程详解
2016/04/26 Javascript
vue.js初学入门教程(2)
2016/11/07 Javascript
p5.js入门教程之平滑过渡(Easing)
2018/03/16 Javascript
超出JavaScript安全整数限制的数字计算BigInt详解
2018/06/24 Javascript
Webstorm2016使用技巧(SVN插件使用)
2018/10/29 Javascript
Nodejs实现用户注册功能
2019/04/14 NodeJs
详解关于表格合并span-method方法的补充(表格数据由后台动态返回)
2019/05/21 Javascript
Vue 实现复制功能,不需要任何结构内容直接复制方式
2019/11/09 Javascript
基于JQuery和DWR实现异步数据传递
2020/10/16 jQuery
用vue设计一个日历表
2020/12/03 Vue.js
jQuery实现穿梭框效果
2021/01/19 jQuery
Python中的字典与成员运算符初步探究
2015/10/13 Python
Python进阶-函数默认参数(详解)
2017/05/18 Python
python中使用iterrows()对dataframe进行遍历的实例
2018/06/09 Python
使用Python的networkx绘制精美网络图教程
2019/11/21 Python
python 获取计算机的网卡信息
2021/02/18 Python
Roxy荷兰官方网站:冲浪、滑雪板、服装和配件
2019/10/22 全球购物
公共事业管理本科生求职信
2013/10/07 职场文书
食品工程专业求职信
2014/06/15 职场文书
白莲教口号
2014/06/18 职场文书
学生检讨书怎么写
2014/10/09 职场文书
2015年学校图书室工作总结
2015/05/19 职场文书
辛德勒的名单观后感
2015/06/03 职场文书
格列佛游记读书笔记
2015/06/30 职场文书
2022年四月新番
2022/03/15 日漫