`

js数据结构之LinkedList

阅读更多

Base.js,用于类的设计使用:

/*
	Base.js, version 1.1a
	Copyright 2006-2010, Dean Edwards
	License: http://www.opensource.org/licenses/mit-license.php
*/

var Base = function() {
	// dummy
};

Base.extend = function(_instance, _static) { // subclass
	var extend = Base.prototype.extend;
	
	// build the prototype
	Base._prototyping = true;
	var proto = new this;
	extend.call(proto, _instance);
  proto.base = function() {
    // call this method from any other method to invoke that method's ancestor
  };
	delete Base._prototyping;
	
	// create the wrapper for the constructor function
	//var constructor = proto.constructor.valueOf(); //-dean
	var constructor = proto.constructor;
	var klass = proto.constructor = function() {
		if (!Base._prototyping) {
			if (this._constructing || this.constructor == klass) { // instantiation
				this._constructing = true;
				constructor.apply(this, arguments);
				delete this._constructing;
			} else if (arguments[0] != null) { // casting
				return (arguments[0].extend || extend).call(arguments[0], proto);
			}
		}
	};
	
	// build the class interface
	klass.ancestor = this;
	klass.extend = this.extend;
	klass.forEach = this.forEach;
	klass.implement = this.implement;
	klass.prototype = proto;
	klass.toString = this.toString;
	klass.valueOf = function(type) {
		//return (type == "object") ? klass : constructor; //-dean
		return (type == "object") ? klass : constructor.valueOf();
	};
	extend.call(klass, _static);
	// class initialisation
	if (typeof klass.init == "function") klass.init();
	return klass;
};

Base.prototype = {	
	extend: function(source, value) {
		if (arguments.length > 1) { // extending with a name/value pair
			var ancestor = this[source];
			if (ancestor && (typeof value == "function") && // overriding a method?
				// the valueOf() comparison is to avoid circular references
				(!ancestor.valueOf || ancestor.valueOf() != value.valueOf()) &&
				/\bbase\b/.test(value)) {
				// get the underlying method
				var method = value.valueOf();
				// override
				value = function() {
					var previous = this.base || Base.prototype.base;
					this.base = ancestor;
					var returnValue = method.apply(this, arguments);
					this.base = previous;
					return returnValue;
				};
				// point to the underlying method
				value.valueOf = function(type) {
					return (type == "object") ? value : method;
				};
				value.toString = Base.toString;
			}
			this[source] = value;
		} else if (source) { // extending with an object literal
			var extend = Base.prototype.extend;
			// if this object has a customised extend method then use it
			if (!Base._prototyping && typeof this != "function") {
				extend = this.extend || extend;
			}
			var proto = {toSource: null};
			// do the "toString" and other methods manually
			var hidden = ["constructor", "toString", "valueOf"];
			// if we are prototyping then include the constructor
			var i = Base._prototyping ? 0 : 1;
			while (key = hidden[i++]) {
				if (source[key] != proto[key]) {
					extend.call(this, key, source[key]);

				}
			}
			// copy each of the source object's properties to this object
			for (var key in source) {
				if (!proto[key]) extend.call(this, key, source[key]);
			}
		}
		return this;
	}
};

// initialise
Base = Base.extend({
	constructor: function() {
		this.extend(arguments[0]);
	}
}, {
	ancestor: Object,
	version: "1.1",
	
	forEach: function(object, block, context) {
		for (var key in object) {
			if (this.prototype[key] === undefined) {
				block.call(context, object[key], key, object);
			}
		}
	},
		
	implement: function() {
		for (var i = 0; i < arguments.length; i++) {
			if (typeof arguments[i] == "function") {
				// if it's a function, call it
				arguments[i](this.prototype);
			} else {
				// add the interface using the extend method
				this.prototype.extend(arguments[i]);
			}
		}
		return this;
	},
	
	toString: function() {
		return String(this.valueOf());
	}
});

 

UtilPackage.js命名空间作用:

// JavaScript Document
var org = {};
org.forever = {};
org.forever.util = {};

 

LinkedList.js基于双向链表实现的列表结构,从java的LinkedList移植过来的,参照jdkapi:

 

// JavaScript Document
org.forever.util.DLNode =  Base.extend({
	constructor : function(element, next, previous){
		 this.element = element;
		 this.next = next;
		 this.previous = previous;
	}
});

org.forever.util.IndexOutOfBoundsException = Base.extend({
	constructor : function(s){
		this.message = s;
	},
	getMessage : function(){
		return this.message;
	}
});

org.forever.util.NoSuchElementException = Base.extend({
	constructor : function(s){
		this.message = s;
	},
	getMessage : function(){
		return this.message;
	}
});

org.forever.util.LinkedList = Base.extend({
	constructor : function(){
		this.size = 0;
		this.header = new org.forever.util.DLNode(null, null, null);
		this.header.next = this.header.previous = this.header;
	},
	getSize : function(){
		return this.size;
	},
	add : function(e){
		this.addBefore(e, this.header);
        return true;
	},
	addFirst : function(e){
		this.addBefore(e, this.header.next);
	},
	addLast : function(e){
		this.addBefore(e, this.header);
	},
	addBefore:function(e, entry){
		var newEntry = new org.forever.util.DLNode(e, entry, entry.previous);
		newEntry.previous.next = newEntry;
		newEntry.next.previous = newEntry;
		this.size++;
		return newEntry;
	},
	get : function(index){
		return this.entry(index).element;
	},
	indexOf : function(o){
		var index = 0;
        if (o==null) {
            for (var e = this.header.next; e != this.header; e = e.next) {
                if (e.element==null)
                    return index;
                index++;
            }
        } else {
            for (var e = this.header.next; e != this.header; e = e.next) {
                if (o == e.element)
                    return index;
                index++;
            }
        }
        return -1;
	},
	removeFirst : function(){
		return this.remove(this.header.next);
	},
	removeLast : function(){
		return remove(header.previous);
	},
	removeAt : function(index){
		return this.remove(this.entry(index));
	},
	remove : function(e){
		if (e == this.header)
	    throw new org.forever.util.NoSuchElementException('没有元素');
        var result = e.element;
		e.previous.next = e.next;
		e.next.previous = e.previous;
		e.next = e.previous = null;
		e.element = null;
		this.size--;
		return result;
	},
	lastIndexOf : function(o){
		var index = size;
        if (o==null) {
            for (var e = this.header.previous; e != this.header; e = e.previous) {
                index--;
                if (e.element==null)
                    return index;
            }
        } else {
            for (var e = this.header.previous; e != this.header; e = e.previous) {
                index--;
                if (o == e.element)
                    return index;
            }
        }
        return -1;
	},
	contains : function(o){
		return this.indexOf(o) != -1;
	},
	clear : function(){
		var e = this.header.next;
        while (e != this.header) {
            var next = e.next;
            e.next = e.previous = null;
            e.element = null;
            e = next;
        }
        this.header.next = this.header.previous = this.header;
        size = 0;
	},
	insert : function(index,element){
		this.addBefore(element, (index==this.size ? this.header : this.entry(index)));
	},
	entry : function(index){
		if (index < 0 || index >= this.size)
            throw new org.forever.util.IndexOutOfBoundsException("Index: "+index+
                                                ", Size: "+size);
        var e = this.header;
        if (index < (this.size >> 1)) {
            for (var i = 0; i <= index; i++)
                e = e.next;
        } else {
            for (var i = this.size; i > index; i--)
                e = e.previous;
        }
        return e;
	},
	toArray : function(){
		var result =[this.size];
        var i = 0;
        for (var e = this.header.next; e != this.header; e = e.next)
            result[i++] = e.element;
		return result;
	},
	set : function(index,e){
		var e = this.entry(index);
        var oldVal = e.element;
        e.element = element;
        return oldVal;
	}
});


 

举例:

	var list = new org.forever.util.LinkedList();
	list.add(1);
	list.add(2);
	list.add(3);
	list.add(2);
	list.add(4);
	var size = list.getSize();
	var elem = list.get(3);
	var index = list.lastIndexOf(2);
	var array = list.toArray();

 

分享到:
评论

相关推荐

    Js数据结构_js数据结构_js实现算法_asleephi9_源码

    总之,这个资源对于想要深入学习JavaScript数据结构和算法的开发者来说是一份宝贵的资料。通过学习和研究,你不仅可以掌握基础理论,还能提升代码质量和解决问题的能力。无论是前端工程师、全栈开发者还是对算法感...

    JavaScript 实现基础 LinkedList 功能

    JavaScript中的LinkedList是一种常见的数据结构,它允许我们在列表的任意位置高效地添加和删除元素。在JavaScript中实现LinkedList,我们需要理解其基本概念、操作以及如何用原生JavaScript对象来模拟链表结构。 ...

    js数据结构与算法.zip

    在JavaScript中,常见的数据结构包括数组(Array)、对象(Object)、链表(LinkedList)、栈(Stack)、队列(Queue)、哈希表(Hash Table)、集合(Set)、图(Graph)和树(Tree)等。理解这些数据结构的特性和...

    JavaScript数据结构之链表的实现

    在实际应用中,JavaScript开发者可以根据需求选择适合的数据结构。如果数据的增删操作频繁,且对顺序访问有较高要求,链表可能是一个不错的选择。相反,如果需要快速访问特定位置的元素,数组则更适合。在JavaScript...

    JavaScript数据结构之单链表和循环链表

    在深入了解JavaScript中的单链表和循环链表的实现之前,我们需要先了解数据结构的基本概念。数据结构是计算机存储、组织数据的方式,它有助于更高效地访问和修改数据。数据结构分为线性和非线性两大类,而链表属于非...

    JavaScript实现数据结构

    1. 数组(Array):JavaScript中的数组是最常用的数据结构之一,它可以存储多个元素,并通过索引来访问。数组可以用来实现简单的线性存储,如栈(LIFO,后进先出)或队列(FIFO,先进先出)。 2. 对象(Object):...

    数据结构-使用javascript讲解数据结构之链表.zip

    本资料包“数据结构-使用javascript讲解数据结构之链表.zip”将深入探讨链表的概念、实现以及其在JavaScript中的应用。 链表不同于数组,数组是连续的内存空间,而链表的元素在内存中是非连续存储的。每个元素称为...

    JS算法 数据结构 精华集.zip

    这个"JS算法 数据结构 精华集.zip"压缩包很可能包含了关于JavaScript编程中算法和数据结构的深度学习资源,如源代码、教程、练习题等,旨在帮助开发者提升这方面的能力。 首先,让我们深入探讨JavaScript中的数据...

    Java-C-JS数据结构与算法合集

    《Java-C-JS数据结构与算法合集》是针对编程领域的三大主流语言——Java、C和JavaScript,深入探讨数据结构与算法的宝贵资源。数据结构是计算机存储、组织数据的方式,而算法是解决问题的精确步骤,它们是软件开发的...

    javascript集合类 LinkedList代码实现

    JavaScript中的LinkedList是一种线性数据结构,它通过节点(Node)对象的形式存储数据,每个节点包含一个数据元素和指向下一个节点的引用。LinkedList提供了一种高效的方式进行插入和删除操作,因为这些操作通常只...

    JS数据结构与算法1

    JavaScript 数据结构与算法是编程领域中的基础,它们是构建高效程序和解决复杂问题的关键工具。在JavaScript中,我们经常使用的数据结构包括数组、栈、队列、链表等。 1. **数组**:数组是最基本的数据结构,它可以...

    为JavaScriptTypeScript语言精心策划的数据结构集合.zip

    此外,TypeScript还支持强类型的Map和Set,以及更符合数据结构概念的LinkedList、Queue、Stack等。 “mnemonist_master.zip”可能是包含一个名为“mnemonist”的库,它可能提供了许多常见数据结构的实现,如堆...

    JavaScript编写简化了许多常见的数据结构的例子

    数组是最基本的数据结构之一,用于存储一组有序的元素。在JavaScript中,数组支持索引访问和长度属性,可以容纳不同类型的元素。例如,你可以使用`push()`、`pop()`、`shift()`和`unshift()`方法来管理数组的元素。...

    数据结构和算法在JavaScript电子书中解释和实现.zip

    1. "dsa.js":这可能是主文件,包含了用JavaScript实现的各种数据结构和算法。 2. "data-structures"目录:可能包含了各种数据结构的实现,如Array、LinkedList、Stack、Queue、HashMap、Tree等。 3. "algorithms...

    数据结构与算法javascript学习代码实现.zip

    在编程领域,数据结构与算法是核心技术之一,尤其在JavaScript这样的多用途编程语言中,理解和掌握它们至关重要。"数据结构与算法javascript学习代码实现.zip"这个压缩包很可能包含了一系列用JavaScript实现的数据...

    JavaScript讲解了数据结构和算法.zip

    在JavaScript中,常见的数据结构有数组(Array)、链表(LinkedList)、栈(Stack)、队列(Queue)、哈希表(HashMap)、树(Tree)和图(Graph)等。 1. **数组**:JavaScript中的数组是最基础的数据结构,可以...

    java数据结构与算法+applet与源码

    例如,集合框架(java.util包)中就包含了多种数据结构的实现,如ArrayList、LinkedList、HashMap等,这些都是数据结构在Java中的具体体现。开发者可以通过研究这些类的源码来深入理解它们的工作原理。 Applet是...

    《数据结构Java版》习题解答.doc

    "《数据结构Java版》习题解答" 《数据结构Java版》习题解答是Java语言编程的数据结构实践指南,旨在帮助学生和开发人员更好地理解和掌握数据结构的基本概念和实现技术。本文档涵盖了数据结构的基础知识、线性表、...

    Javascript-LinkedList:使用javscript学习数据结构(单链接列表)并使用jest进行测试

    链表数据结构(Javascript) 此存储库包含有关使用javascript进行数据结构链接列表和使用jest进行测试的练习。 链表数据结构有三种类型(单链,双链和循环),但在此文档中,我们重点关注单链表。 在此仓库中,我将...

Global site tag (gtag.js) - Google Analytics