传说在公元1 世纪的犹太战争中,犹太历史学家弗拉维奥·约瑟夫斯和他的40 个同胞被罗马士兵包围。犹太士兵决定宁可自杀也不做俘虏,于是商量出了一个自杀方案。他们围成一个圈,从一个人开始,数到第三个人时将第三个人杀死,然后再数,直到杀光所有人。约瑟夫和另外一个人决定不参加这个疯狂的游戏,他们快速地计算出了两个位置,站在那里得以幸存。写一段程序将n个人围成一圈,并且第m个人会被杀掉,计算一圈人中哪两个人最后会存活。使用循环链表解决该问题。
这个问题就是典型的循环链表的应用,实现了循环链表后还有个问题就是找到特定元素之后的移动问题。
如下是具体链表的实现过程:
            function Node(ele) {
this.ele = ele;
this.next = null;
}
function LList() {
this.head = new Node("head");
this.head.next = this.head;
this.currentNode = this.head;
}
LList.prototype.find =function (item) {
var currNode = this.head;
while(currNode.ele != item) {
currNode = currNode.next;
}
return currNode;
};
LList.prototype.insert = function (newEle,item) {
var newNode = new Node(newEle);
var current = this.find(item);
newNode.next = current.next;
current.next = newNode;
};
LList.prototype.display = function() {
var currNode = this.head;
while(!(currNode.next == null) && !(currNode.next.ele == "head")) {//这点有区别当前节点的后继不为空或者当前节点的后继元素不为头节点
console.log(currNode.next.ele);
currNode = currNode.next;
}
};
LList.prototype.findPrevious = function (item) {
var currNode = this.head;
while(!(currNode.next == null) && (currNode.next.ele != item )) {//当前节点的后继不为空或者后继节点不为所要查找的元素时
currNode = currNode.next;//修改后继链
}
return currNode;//找到时返回
};
LList.prototype.remove = function(item) {
var prevNode = this.findPrevious(item);//找到删除元素的前一个元素
if(!(prevNode.next == null)) {//待删除元素不为空
prevNode.next = prevNode.next.next;//待删除元素的前驱的后继修改为待删除元素的后继的后继
}
}; //当前链表中有多少个元素
LList.prototype.count = function(){
var node = this.head;
var i = 0;
while (!(node.next.ele == "head")){
node = node.next;
i++;
}
return i;
};
//向前移动n个节点
LList.prototype.advance = function(n){
while (n>0){
if(this.currentNode.next.ele == "head"){
this.currentNode = this.currentNode.next.next;
}else{
this.currentNode = this.currentNode.next;
}
n--;
}
};

下面是测试部分:(有点小兴奋哦~~)

        var per = new LList();
per.insert("1","head");
per.insert("2","1");
per.insert("3","2");
per.insert("4","3");
per.insert("5","4");
per.insert("6","5");
per.insert("7","6");
per.insert("8","7");
per.insert("9","8");
per.insert("10","9");
var num = 3;
while(per.count() >2 ) {//个数大于2,从三开始进行移动
per.advance(num);
per.remove(per.currentNode.ele);
per.display();
}

输出结果:

第一次:1 2 4 5 6 7 8 9 10

第二次:1 2 4 5 7 8 9 10

第三次:1 2 4 5 7 8 10

第四次:1 4 5 7 8 10

第五次:1 4 5 8 10

第六次:4 5 8 10

第七次:4 5 10

第八次:4 10

 

JavaScript--数据结构与算法之链表实现约瑟夫环的更多相关文章

  1. JavaScript 数据结构与算法3(链表)

    学习数据结构的 git 代码地址: https://gitee.com/zhangning187/js-data-structure-study 1.链表 本章学习如何实现和使用链表这种动态的数据结构 ...

  2. JavaScript数据结构与算法(六) 链表的实现

    // 链表存储有序的元素集合,但不同于数组,链表中的元素在内存中并不是连续放置的.每个 // 元素由一个存储元素本身的节点和一个指向下一个元素的引用(也称指针或链接)组成.下图展 // 示了一个链表的 ...

  3. Problem E: 用链表实现约瑟夫环

    Description 你听说过约瑟夫问题吗?问题大致如下:首先n个人围成一个圈,标记为1到n号.接着,从1号开始报数(从1开始),然后2号报数,然后3号...当有人报到到m时,这个人就要踢出比赛,然 ...

  4. C 单链表 实现约瑟夫环

    list.h #ifndef _List_H #define _List_H typedef int ElementType; struct Node; typedef struct Node *Pt ...

  5. 为什么我要放弃javaScript数据结构与算法(第五章)—— 链表

    这一章你将会学会如何实现和使用链表这种动态的数据结构,这意味着我们可以从中任意添加或移除项,它会按需进行扩张. 本章内容 链表数据结构 向链表添加元素 从链表移除元素 使用 LinkedList 类 ...

  6. JavaScript数据结构与算法-链表练习

    链表的实现 一. 单向链表 // Node类 function Node (element) { this.element = element; this.next = null; } // Link ...

  7. 重读《学习JavaScript数据结构与算法-第三版》- 第6章 链表(一)

    定场诗 伤情最是晚凉天,憔悴厮人不堪言: 邀酒摧肠三杯醉.寻香惊梦五更寒. 钗头凤斜卿有泪,荼蘼花了我无缘: 小楼寂寞新雨月.也难如钩也难圆. 前言 本章为重读<学习JavaScript数据结构 ...

  8. JavaScript 数据结构与算法之美 - 线性表(数组、栈、队列、链表)

    前言 基础知识就像是一座大楼的地基,它决定了我们的技术高度. 我们应该多掌握一些可移值的技术或者再过十几年应该都不会过时的技术,数据结构与算法就是其中之一. 栈.队列.链表.堆 是数据结构与算法中的基 ...

  9. 为什么我要放弃javaScript数据结构与算法(第九章)—— 图

    本章中,将学习另外一种非线性数据结构--图.这是学习的最后一种数据结构,后面将学习排序和搜索算法. 第九章 图 图的相关术语 图是网络结构的抽象模型.图是一组由边连接的节点(或顶点).学习图是重要的, ...

随机推荐

  1. JavaScript,ES5和ES6的区别

    什么是JavaScript JavaScript一种动态类型.弱类型.基于原型的客户端脚本语言,用来给HTML网页增加动态功能.(好吧,概念什么最讨厌了) 动态: 在运行时确定数据类型.变量使用之前不 ...

  2. 比起 Windows,怎样解读 Linux 的文件系统与目录结构?

    Linux 和 Windows 的文件系统有些不同,在学习使用 Linux 之前,若能够了解这些不同,会有助于后续学习. 本文先对 Windows 和 Linux 上面文件系统原理.组织概念进行区分, ...

  3. decision tree 决策树(一)

    一 决策树 原理:分类决策树模型是一种描述对实例进行分类的树形结构.决策树由结点(node)和有向边(directed edge)组成.结点有两种类型:内部结点(internal node)和叶结点( ...

  4. 用Python爬取影视网站,直接解析播放地址。

    记录时刻! 写这个爬虫主要是想让自己的爬虫实用,把脚本放到了服务器,成为可随时调用的接口. 思路算是没思路吧!把影视名带上去请求影视网站,然后解析出我们需要的播放地址. 我也把自己的接口分享出来.接口 ...

  5. 题解 P3521 【[POI2011]ROT-Tree Rotations】

    这道题采用权值线段树合并的解法. 首先讲一下解法中出现的两个概念:权值线段树与线段树合并. 所谓权值线段树,可以理解为维护的信息反过来的普通线段树,我个人认为值域线段树这个名字其实要准确一些. 举个例 ...

  6. POJ——T 1182 食物链

    http://poj.org/problem?id=1182 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 77012   ...

  7. FragmentActivity+FragmentTabHost+Fragement替代TabActibvity+TabHost+Activity

    自Android3.2之后,TabActibvity被弃用(Deprecated).取而代之的是FragmentActivity.由于Fragment比Activiy更灵活.消耗的资源更小.全然可以满 ...

  8. p2p項目夭折,有種蛋蛋的憂傷。。

      在高考完的暑假就在跟杰哥讨论怎样实现的校内p2p文件共享,就在今天.我们无奈的宣布差点儿夭折. 上图是測试图. 那时候的思路已经完好.就是:"学生上传共享文件到咱们工作室的server. ...

  9. Activity的launchMode和任务栈小结

    对Activity的launchMode的理解一直没有好好总结下,这两天系统总结下launchMode的使用方法: Activity的launchMode属性决定了Activity和应用程序当前任务栈 ...

  10. base64格式的图片数据如何转成图片

    base64格式的图片数据如何转成图片 一.总结 一句话总结:不仅要去掉前面的格式串,还需要base64_decode()解码才行. // $base_img是获取到前端传递的值 $base_img ...