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 翻牌或百叶窗效果(内容三秒自动切换)
Jun 14 Javascript
基于JavaScript实现继承机制之构造函数+原型链混合方式的使用详解
May 07 Javascript
点击按钮或链接不跳转只刷新页面的脚本整理
Oct 22 Javascript
jquery选择器之基本过滤选择器详解
Jan 27 Javascript
js 判断js函数、变量是否存在的简单示例代码
Mar 04 Javascript
JavaScript数据类型学习笔记
Jan 25 Javascript
VueJs与ReactJS和AngularJS的异同点
Dec 12 Javascript
Javascript 链式作用域详细介绍
Feb 23 Javascript
jquery select插件异步实时搜索实例代码
Oct 20 jQuery
js原生实现移动端手指滑动轮播图效果的示例
Jan 02 Javascript
node前端开发模板引擎Jade的入门
May 11 Javascript
js中Object.defineProperty()方法的不详解
Jul 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
解析如何修改phpmyadmin中的默认登陆超时时间
2013/06/25 PHP
php实现的百度搜索某地天气的小偷代码
2014/04/23 PHP
php建立Ftp连接的方法
2015/03/07 PHP
Laravel框架基于ajax和layer.js实现无刷新删除功能示例
2019/01/17 PHP
javascript radio 联动效果
2009/03/04 Javascript
jQuery 使用手册(三)
2009/09/23 Javascript
jQuery动画animate方法使用介绍
2013/05/06 Javascript
JavaScript实现的一个计算数字步数的算法分享
2014/12/06 Javascript
分享ES6的7个实用技巧
2018/01/18 Javascript
createObjectURL方法实现本地图片预览
2019/09/30 Javascript
[36:19]2018DOTA2亚洲邀请赛 小组赛 A组加赛 Newbee vs LGD
2018/04/03 DOTA
[01:04:31]DOTA2-DPC中国联赛定级赛 iG vs Magma BO3第二场 1月8日
2021/03/11 DOTA
Python进阶学习之特殊方法实例详析
2017/12/01 Python
解决python3爬虫无法显示中文的问题
2018/04/12 Python
Python贪心算法实例小结
2018/04/22 Python
python实现银行管理系统
2019/10/25 Python
在Python中使用MongoEngine操作数据库教程实例
2019/12/03 Python
Python time库基本使用方法分析
2019/12/13 Python
基于TensorFlow的CNN实现Mnist手写数字识别
2020/06/17 Python
基于python实现操作git过程代码解析
2020/07/27 Python
Python如何创建装饰器时保留函数元信息
2020/08/07 Python
CSS3中Transition动画属性用法详解
2016/07/04 HTML / CSS
CSS3实现渐变背景兼容问题
2020/05/06 HTML / CSS
现代生活方式的家具和装饰:Dot & Bo
2018/12/26 全球购物
美国家庭鞋店:Shoe Sensation
2019/09/27 全球购物
广州品高软件.net笔面试题目
2012/04/18 面试题
大学生个人简历自我评价
2013/11/16 职场文书
羽毛球比赛策划方案
2014/06/13 职场文书
八荣八耻演讲稿
2014/09/15 职场文书
领导班子奢靡之风查摆问题及整改措施
2014/09/27 职场文书
2014年商场工作总结
2014/11/22 职场文书
学术会议通知
2015/04/15 职场文书
赞助商致辞
2015/07/30 职场文书
PyTorch梯度裁剪避免训练loss nan的操作
2021/05/24 Python
Python+tkinter实现高清图片保存
2022/03/13 Python
Python中request的基本使用解决乱码问题
2022/04/12 Python