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 相关文章推荐
我见过最全的个人js加解密功能页面
Dec 12 Javascript
用JavaScript页面不刷新时全选择,全删除(GridView)
Apr 14 Javascript
关于onchange事件在IE和FF下的表现及解决方法
Mar 08 Javascript
JQuery弹出层示例可自定义
May 19 Javascript
JS实现支持Ajax验证的表单插件
Mar 24 Javascript
jQuery多级联动下拉插件chained用法示例
Aug 20 Javascript
工厂模式在JS中的实践
Jan 18 Javascript
Bootstrap媒体对象学习使用
Mar 07 Javascript
Angular组件化管理实现方法分析
Mar 17 Javascript
koa上传excel文件并解析的实现方法
Aug 09 Javascript
layui table 表格上添加日期控件的两种方法
Sep 28 Javascript
工作中常用js功能汇总
Nov 07 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实现打包下载文件的方法示例
2017/10/07 PHP
使用Zookeeper分布式部署PHP应用程序
2019/03/15 PHP
通过PHP实现获取访问用户IP
2020/05/09 PHP
js模仿html5 placeholder适应于不支持的浏览器
2013/01/13 Javascript
解读JavaScript中 For, While与递归的用法
2013/05/07 Javascript
js中通过split函数分割字符串成数组小例子
2013/09/21 Javascript
通过实例理解javascript中没有函数重载的概念
2015/06/03 Javascript
实现音乐播放器的代码(html5+css3+jquery)
2015/08/04 Javascript
基于JS实现横线提示输入验证码随验证码输入消失(js验证码的实现)
2016/10/27 Javascript
jQuery实现按比例缩放图片的方法
2017/04/29 jQuery
浅谈通过JS拦截 pushState和replaceState事件
2017/07/21 Javascript
jquery.uploadView 实现图片预览上传功能
2017/08/10 jQuery
JavaScript监听手机物理返回键的两种解决方法
2017/08/14 Javascript
vue+vuecli+webpack中使用mockjs模拟后端数据的示例
2017/10/24 Javascript
vue 插件的方法代码详解
2019/06/06 Javascript
简单了解微信小程序 e.target与e.currentTarget的不同
2019/09/27 Javascript
详解JavaScript匿名函数和闭包
2020/07/10 Javascript
详解Vue的七种传值方式
2021/02/08 Vue.js
[03:08]迎霜节狂欢!2018年迎霜节珍藏Ⅰ一览
2018/12/25 DOTA
[46:14]完美世界DOTA2联赛PWL S3 Magma vs INK ICE 第一场 12.11
2020/12/16 DOTA
浅谈Python中的数据类型
2015/05/05 Python
Python实现数据库并行读取和写入实例
2017/06/09 Python
Python彻底删除文件夹及其子文件方式
2019/12/23 Python
Python RabbitMQ实现简单的进程间通信示例
2020/07/02 Python
python脚本第一行如何写
2020/08/30 Python
舒适的豪华鞋:Taryn Rose
2018/05/03 全球购物
下面代码从性能上考虑,有什么问题
2015/04/03 面试题
中文系师范生自荐信
2013/10/01 职场文书
化学相关工作求职信
2013/10/02 职场文书
总经理助理岗位职责
2013/11/08 职场文书
商务助理求职信范文
2014/04/20 职场文书
厨师长岗位职责范本
2014/08/25 职场文书
医生爱岗敬业演讲稿
2014/08/26 职场文书
购房个人委托书范本
2014/10/11 职场文书
女方离婚起诉书
2015/05/18 职场文书
公司的力量观后感
2015/06/05 职场文书