【发布时间】:2014-04-02 05:38:56
【问题描述】:
这个 LinkedList 函数使用一种非常狡猾的方法来避免客户端代码需要了解链接节点。每个列表创建一个唯一的字符串,用于将属性插入到添加到列表中的对象中。有谁知道更好的方法来做到这一点?我应该提一下,在恒定时间内移除对象是一项要求。
这确实意味着客户端代码看起来像:
var myList = new LinkedList()
var a = new Something()
var b = new SomethingElse()
myList.addTail(a)
myList.addTail(b)
myList.remove(a)
myList.remove(b)
这很好并且可读,但是将属性插入对象(可能与现有属性冲突)是不稳定的,至少可以说(尽管它可以被记录并且属性名称前缀可以传递给 LinkedList构造函数)。
这是链表代码:
var LinkedList = (function() {
var id = 0
var Node = function(obj, p, n) {
this.item = obj
this.prev = p
this.next = n
}
var list = function() {
this.length = 0
this.nodeName = '_' + id++ + 'lnn'
this.root = new Node(null)
this.root.next = this.root
this.root.prev = this.root
}
list.prototype = {
insertBefore : function(obj, item) {
var node = new Node(item, obj.prev, obj)
obj.prev.next = node
obj.prev = node
item[this.nodeName] = node
++this.length
},
insertAfter : function(obj, item) {
var node = new Node(item, obj, obj.next)
obj.next.prev = node
obj.next = node
item[this.nodeName] = node
++this.length
},
addTail : function(item) {
this.insertBefore(this.root, item)
},
addHead : function(item) {
this.insertAfter(this.root, item)
},
remove : function(item) {
var node = item[this.nodeName]
node.prev.next = node.next
node.next.prev = node.prev
delete node.item[this.nodeName]
--this.length
},
popHead : function() {
if(this.length > 0) {
var node = this.root.next
node.prev.next = node.next
node.next.prev = node.prev
delete node.item[this.nodeName]
--this.length
return node.item
}
return null
},
popTail : function() {
if(this.length > 0) {
var node = this.root.prev
node.prev.next = node.next
node.next.prev = node.prev
delete node.item[this.nodeName]
--this.length
return node.item
}
return null
},
forEach : function(callback, context) {
var node = this.root.next
var index = 0
while(node !== this.root) {
var next = node.next
if(callback.call(context, node.item, index) === false) {
return false
}
node = next
++index
}
return true
},
removeIf : function(callback, context) {
var node = this.root.next
while(node !== this.root) {
var next = node.next
if(callback.call(context, node.item) === true) {
node.prev.next = next
node.next.prev = node.prev
delete node.item[this.nodeName]
--this.length
}
node = next
}
},
toString : function() {
var s = this.length.toString()
var sep = ':<'
this.forEach(function(i, index) {
s += sep + i.toString()
sep = ','
})
return s + '>'
}
}
return list
})()
【问题讨论】:
-
这就是你想要的吗?
-
不完全——我需要不断地删除任意元素,我认为你不会给我。
-
这不是普通链表的工作方式。应该包括在问题中
-
啊,好点,为清楚起见进行了编辑
-
在问题描述中仍然不清楚具体问题是什么,也没有在示例代码中。循环/双向链表通常仍然没有固定时间删除或任意元素 - 只有您有迭代器的元素......请不要在人们将工作代码示例输入到您的原始问题后更改问题。
标签: javascript linked-list doubly-linked-list