JavaScript链表学习

本文介绍了一种使用JavaScript实现单向链表的方法,并对原始代码进行了改进,新增了获取指定索引节点、首节点及末节点的功能。通过示例展示了如何在HTML页面中使用此链表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天的工作中需要用到JavaScript的链表,于是我上网找了一些资料。发现了这篇博客:

http://www.cnblogs.com/snandy/archive/2011/10/14/2212491.html

里面有一个JavaScript脚本LinkedList-0.1.js,代码的地址在:

http://files.cnblogs.com/files/snandy/LinkedList-0.1.js

原作者Snandy已经对代码包括的函数做了说明,并给出了一个调用例子。

基本上这些内容已经满足我的需要,不过因为原代码的get函数返回的是数据而不是节点,不适于做链表的遍历,因此我在原代码的基础上做了一些改进。新增了三个函数getNode、getFirstNode、getLastNode,分别作为原get、getFirst、getLast的扩展。

改动后的代码LinkedList.js如下(改动的地方用注释标出)

/**
 * 原作者:snandy 2011
 * 修改人:Tsybius2014 2015年11月23日
 */
LinkedList = function(){
    
    function Node(data, next) {
        this.data = data || null;
        this.next = next || null;
    }
    Node.prototype = {
        getValue: function() {
            return this.data;
        },
        setValue: function(obj) {
            this.data = obj;
        },
        getNext: function() {
            return this.next;
        },
        setNext: function(node) {
            this.next = node;
        }
    };
    Node.prototype.constructor = Node;


    function nodeByIndex(index, head) {
        var node = head;
        var i = 0;
        if(index===0) {
            return node;
        }
        while(node.next) {
            if(i===index) {
                return node;
            }
            node = node.next && node.next;
            i++;
        }
        return node;
        
    }

    function nodeByData(data, list) {
        var prev = null,
            node = list.head;
        while(node.next) {
            if(node.data == data) {
                if(node==list.head) {
                    return {
                        prev: null,
                        curr: node
                    };
                }
                else {
                    return {
                        prev: prev,
                        curr: node
                    };
                }
            }
            prev = node;
            node = node.next;
        }
        if(node.data == data) {
            if(list.size() === 1) {
                return {
                    prev: null,
                    curr: node
                };
            }
            else {
                return {
                    prev: prev,
                    curr: node
                };
            }
        }
        return null;
    }

    function LinkedList() {
        this.head = null;
        this.tail = null;
        this.length = 0;
    }

    LinkedList.prototype = {
        add: function(index, obj) {
            if(obj === undefined || obj === null || typeof index != 'number') {
                throw new Error('add failed, invalid param');
            }
            if(index < 0) {
                index = this.length + index;
            }
            if(index<0 || index>this.length) {
                throw new Error('add failed, invalid index');
            }
            
            var newNode = new Node(obj);
            if(index==0) {
                if(this.head) {
                    newNode.setNext(this.head);
                    this.head = newNode;
                }
                else {
                    this.head = this.tail = newNode;
                }
            }
            else {
                var node = nodeByIndex(index-1, this.head),
                    next = node.next;
                node.setNext(newNode);
                newNode.setNext(next);
            }
            this.length++;
            
        },
        //获取指定索引的节点(新加的代码)
        getNode: function(index) {
                    if(typeof index !== 'number') {
                throw new Error('get failed, invalid param');
            }
            if(index < 0) {
                index = this.length + index;
            }
            if(this.isEmpty() || index<0 || index>=this.length) {
                throw new Error('Index: ' + index + ', Size: ' + this.length);
            }
            
            var node = nodeByIndex(index, this.head);
            
            return node;
        },
        get: function(index) {
            return this.getNode(index).data;
        },
        //获取首个节点(新加的代码)
        getFirstNode: function() {
            return this.getNode(0);
        },
        getFirst: function() {
            return this.get(0);
        },
        //获取最后一个节点(新加的代码)
        getLastNode: function() {
            return this.getNode(this.length-1);
        },
        getLast: function() {
            return this.get(this.length-1);
        },
        set: function(index, obj) {
            if(index < 0) {
                index = this.length + index;
            }
            if(this.isEmpty() || index<0 || index>=this.length) {
                throw new Error('Index: ' + index + ', Size: ' + this.length);
            }
            
            var node = nodeByIndex(index, this.head);
            
            node.data = obj;
            
        },
        size: function() {
            return this.length;
        },
        clear: function() {
            this.head.next = null;
            this.head = null;
        },
        remove: function(obj) {
            var nodes = nodeByData(obj, this);
            
            if(nodes === null) {
                throw new Error('remove failed, the node does not exist');
            }
            
            var curr = nodes.curr,
                prev = nodes.prev;
            
            if(prev === null) {
                this.head = curr.next;
                curr.next = null;
                curr = null;
            }
            else {
                prev.setNext(curr.next);
                curr.next = null;
                curr = null;
            }
            this.length--;
        },
        isEmpty: function() {
            return this.head === null;
        },
        addLast: function(obj) {
            this.add(this.length, obj);
        },
        addFirst: function(obj) {
            this.add(0, obj);
        },
        contains: function(obj) {
            var node = this.head;
            if(this.isEmpty()) {
                return false;
            }
            while(node.next) {
                if(node.data == obj) {
                    return true;
                }
                node = node.next;
            }
            if(node.data == obj) {
                return true;
            }
            return false;
        },
        toString: function() {
            var str = '',
                node = this.head;
                
            if(this.isEmpty()) {
                return '[]';
            }
            str = '[' + node.data;
            while(node.next) {
                node = node.next;
                str += ',' + node.data;
            }
            str += ']';
            
            return str;
        }

    };

    LinkedList.prototype.constructor = LinkedList;
    return LinkedList;
    
}();

我另建立了一个html文件,取名为test.html,用于测试这段JavaScript,代码如下:

<!DOCTYPE HTML>
<HTML>
    <HEAD>
        <TITLE>单向链表</TITLE>
        <script src="LinkedList.js"></script>
        <script>

            document.write("创建链表<br/>");
            var list = new LinkedList();

            document.write("添加元素 one/two/three/four <br/>");
            list.addLast('元素【one】');
            list.addLast('元素【two】');
            list.addLast('元素【three】');
            list.addLast('元素【four】');

            document.write("链表内元素个数:" + list.size() + "<br/>");

            document.write("输出链表内全部元素:");
            document.write(list);
            document.write("<br/>");

            document.write("遍历链表内全部元素1:");
            for (var i = 0; i < list.size(); i++)
            {
                document.write(list.get(i));
                if (i < list.size() - 1) {
                    document.write(",");
                } else {
                    document.write(".");
                }
            }
            document.write("<br/>");

            document.write("遍历链表内全部元素2:");
            var node = list.getFirstNode();
            while (node != null)
            {
                document.write(node.getValue());
                node = node.getNext();
                if (node != null) {
                    document.write(",");
                } else {
                    document.write(".");
                }
            }
            document.write("<br/>");
            
            document.write("测试完毕");

        </script>
    </HEAD>
    <BODY>
    </BODY>
</HTML>

用Chrome浏览器测试后,效果如下:

230955_kr7o_1425762.png

END

转载于:https://my.oschina.net/Tsybius2014/blog/534480

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值