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异步按一定的时间间隔刷新问题
Dec 10 Javascript
document.createElement()用法及注意事项(ff下不兼容)
Mar 13 Javascript
js跳转页面方法总结
Jan 29 Javascript
jquery ajax 局部刷新小案例
Feb 08 Javascript
JQuery限制复选框checkbox可选中个数的方法
Apr 20 Javascript
jQuery实现鼠标单击网页文字后在文本框显示的方法
May 06 Javascript
JS使用eval解析JSON的注意事项分析
Nov 14 Javascript
Vue 2.5 Level E 发布了: 新功能特性一览
Oct 24 Javascript
JavaScript设计模式之装饰者模式实例详解
Jan 17 Javascript
vue下axios拦截器token刷新机制的实例代码
Jan 17 Javascript
vue-cli —— 如何局部修改Element样式
Oct 22 Javascript
详解Vue中的watch和computed
Nov 09 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下安装配置fckeditor编辑器的方法
2011/03/02 PHP
Android ProgressBar进度条和ProgressDialog进度框的展示DEMO
2013/06/19 PHP
PHP实现表单提交时去除斜杠的方法
2016/12/26 PHP
JavaScript使用prototype定义对象类型(转)[
2006/12/22 Javascript
再次更新!MSClass (Class Of Marquee Scroll通用不间断滚动JS封装类 Ver 1.6)
2007/02/05 Javascript
JavaScript 三种创建对象的方法
2009/10/16 Javascript
JavaScript中检测变量是否存在遇到的一些问题
2013/11/11 Javascript
js数组中如何随机取出一个值
2014/06/13 Javascript
input:checkbox多选框实现单选效果跟radio一样
2014/06/16 Javascript
js实现简单的可切换选项卡效果
2015/04/10 Javascript
js结合正则实现国内手机号段校验
2015/06/19 Javascript
JavaScript类型系统之正则表达式
2016/01/05 Javascript
微信小程序  TLS 版本必须大于等于1.2问题解决
2017/02/22 Javascript
JS实现双击内容变为可编辑状态
2017/03/03 Javascript
jquery仿京东商品放大浏览页面
2017/06/06 jQuery
js对象实例详解(JavaScript对象深度剖析,深度理解js对象)
2017/09/21 Javascript
深入理解Angularjs 脏值检测
2018/10/12 Javascript
在vue中使用G2图表的示例代码
2019/03/19 Javascript
JS数组方法reverse()用法实例分析
2020/01/18 Javascript
JS判断浏览器类型与操作系统的方法分析
2020/04/30 Javascript
[01:13:01]2018DOTA2亚洲邀请赛 4.4 淘汰赛 TNC vs VG 第三场
2018/04/05 DOTA
python中xrange和range的区别
2014/05/13 Python
简单介绍Python中的decode()方法的使用
2015/05/18 Python
在python中pandas的series合并方法
2018/11/12 Python
django的ORM操作 删除和编辑实现详解
2019/07/24 Python
python函数参数(必须参数、可变参数、关键字参数)
2019/08/16 Python
Pycharm2020.1安装无法启动问题即设置中文插件的方法
2020/08/07 Python
javascript实现用户必须勾选协议实例讲解
2021/03/24 Javascript
社区十八大感言
2014/01/19 职场文书
万年牢教学反思
2014/02/15 职场文书
公司授权委托书样本
2014/09/15 职场文书
群众路线自查自纠工作情况报告
2014/10/28 职场文书
餐厅服务员管理制度
2015/08/05 职场文书
提升Nginx性能的一些建议
2021/03/31 Servers
go语言中fallthrough的用法说明
2021/05/06 Golang
Z-Order加速Hudi大规模数据集方案分析
2022/03/31 Servers