Javascript数据结构算法之链表(约瑟夫环)

本文介绍JavaScript实现链表的基本方法,并通过一个具体的约瑟夫环问题演示了链表的应用。文章详细展示了如何使用JavaScript创建链表,以及如何通过链表解决实际问题。

在很多编程语言中,数组的长度是固定的;在数组中添加和删除元素很麻烦。而Javascript数组并不存在上述问题,因为Javascript中,数组被实现为对象,而且拥有自己的一系列方法,例如push(),shift(),splice()。然而,Javascript中,数组的主要问题也是被实现成对象导致的效率低下。

链表是由一组节点组成,每个节点除了包括一个数据,还包括使用一个对象的引用指向它的后继。指向另一个节点的引用叫做。链表最前面有一个特殊的节点,叫做头节点。链表最后的节点指向一个null节点。遍历链表,就是跟着链,从链表的首元素走到尾元素。

  • 链表的JS实现
  • 解决实际问题

链表的JS实现

链表包含两个类。Node类用来表示节点。LList类提供了插入节点,删除节点,查找节点,显示链表元素等辅助方法。

//llist.js
//Node对象定义
function Node(element){
    this.element = element;
    this.next = null;
}
//LList对象定义
function LList(){
    this.head = new Node("head");
    this.find = find;
    this.insert = insert;
    this.remove = remove;
    this.findPrevious = findPrevious;
    this.display = display;
}

function find(item){
    var currNode = this.head;
    while(currNode.element != item)
    {
        currNode = currNode.next;
    }
    return currNode;
}

function insert(element, item){
    var newNode = new Node(element);
    var current = this.find(item);
    newNode.next = current.next;
    current.next = newNode;
}

function findPrevious(item){
    var current = this.head;
    while(current.next.element != item && current.next != null)
    {
        current = current.next;
    }
    return current;
}

function remove(item){
    var prevNode = this.findPrevious(item);
    if(prevNode.next != null)
        prevNode.next = prevNode.next.next;
}

function display(){
    var str = "";
    var current = this.head;
    while(current.next != null)
    {
        str += current.next.element + "\n";
        current = current.next;
    }
    return str;
}
//实例化一个链表
var oneLList = new LList();

链表的实际应用

问题描述:传说在公元1 世纪的犹太战争中,犹太历史学家弗拉维奥·约瑟夫斯和他的40 个同胞被罗马士兵包围。犹太士兵决定宁可自杀也不做俘虏,于是商量出了一个自杀方案。他们围成一个圈,从一个人开始,数到第三个人时将第三个人杀死,然后再数,直到杀光所有人。约瑟夫和另外一个人决定不参加这个疯狂的游戏,他们快速地计算出了两个位置,站在那里得以幸存。请问哪两个位置?

(一)网页展示

这里写图片描述

(二)html代码

<!DOCTYPE html>
<html>
<head>
    <title>Linked List</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script src="circlelinklist.js" type="text/javascript"></script>
</head>
<style>
div {
    width: 60%;
    margin: 30px auto;
    padding: 10px;
    border: 1px solid #333;
}
</style>
<body>
    <div>
        <h2>约瑟夫环</h2>
        <input type="button" value="新建数组:" onclick="waitKilled()" />
        <textarea id="waiting_people"></textarea>
        <input type="button" value="杀人顺序:" onclick="getKilled()" />
        <textarea id="dying_people"></textarea>
    </div>
</body>
</html>

(三)Javascript方法

循环链表和单向链表相似,节点类型都是一样的。唯一的区别是,在创建循环链表时,让其头节点指向本身:head.next = head。这样便形成了循环链表。

//circleList.js
//直接构建1-41编号的循环链表,无需定义插入和删除操作。
function Node(element){
    this.element = element;
    this.next = null;
}

function LList(num){
    var head = new Node(1);
    var p = head;
    for(var i=2; i<=num; i++)
    {
        var temp = new Node(i);
        p.next = temp;
        p = temp;
    }
    p.next = head;
    return head;
}

var cirLinkList = new LList(41);

function getKilled(){
    var current = cirLinkList;
    var str = "";
    while(current.next.element != current.element)
    {
        for(var i=1; i<3; i++)
        {
            var temp = current;
            current = current.next;     
        }
        //删除节点的本质即改变其前一个元素的后继
        temp.next = current.next;
        str += current.element + " ";
        current = temp.next;
    }
    str += current.element;
    //将杀人顺序显示在网页上
    var dresult = document.getElementById("dying_people");
    dresult.innerHTML = str;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值