javascript LinkedList:

function Node(elem, prev, next) {
this.elem = elem;
this.prev = prev ? prev : null;
this.next = next ? prev : null;
} function LinkedList() {
this.length = 0;
this.head = null; var that = this;
if (arguments.length > 0) {
var a = arguments[0];
if (a instanceof Array) {
a.forEach(function(elem) {
that.push(elem);
});
}
}
} LinkedList.prototype.push = function(elem) {
var newNode = new Node(elem); if (this.length === 0) {
this.head = newNode;
this.head.prev = newNode;
this.head.next = newNode;
} else {
newNode.next = this.head;
newNode.prev = this.head.prev;
this.head.prev.next = newNode; // !!! CAUTION !!!
this.head.prev = newNode;
}
++this.length;
return this.length;
}; // alias for push
LinkedList.prototype.append = function(elem) {
return this.push(elem);
}; LinkedList.prototype.unshift = function(elem) {
var newNode = new Node(elem); if (this.length === 0) {
this.head = newNode;
this.head.prev = newNode;
this.head.next = newNode;
} else {
newNode.next = this.head;
newNode.prev = this.head.prev;
this.head.prev.next = newNode; // !!! CAUTION !!!
this.head.prev = newNode;
}
this.head = newNode;
++this.length;
return this.length;
}; LinkedList.prototype.shift = function() {
if (this.length === 0) {
return null;
}
var head = this.head,
node = new Node(head.elem); head.next.prev = head.prev;
head.prev.next = head.next;
delete(head); this.head = head.next;
--this.length; return node.elem;
}; LinkedList.prototype.pop = function() {
if (this.length === 0) {
return null;
}
var tail = this.head.prev,
node = new Node(tail.elem); tail.prev.next = tail.next;
tail.next.prev = tail.prev; delete(tail);
--this.length; return node.elem;
}; LinkedList.prototype._get = function(index) {
if (index < 0 || index >= this.length) {
throw new DOMException("LinkedList index out of bounds!");
}
if (index===0) {
return this.head;
}
var pivot = Math.round(this.length / 2);
var p = null, i;
if (index <= pivot) {
p = this.head; // head => tail
for (i = 0; i < index; i++) {
p = p.next;
}
} else {
p = this.head.prev; // tail => head
for (i = this.length - 1; i > index; i--) {
p = p.prev;
}
}
return p;
}; LinkedList.prototype._delete = function(node) {
var retNode = new Node(node.elem); node.prev.next = node.next;
node.next.prev = node.prev; var p = node.next;
if (node===this.head) {
this.head = p;
}
node = null; this.length--;
return {
p: 0 <this.length ? p : null,
v: retNode.elem
}
}; LinkedList.prototype._insertBefore = function(node, elem) {
var newNode = new Node(elem);
newNode.next = node;
newNode.prev = node.prev;
node.prev.next = newNode;
node.prev = newNode;
++this.length;
return newNode;
}; LinkedList.prototype.get = function(index) {
var p = this._get(index);
return p.elem;
}; LinkedList.prototype.splice = function(start,deleteCount,items) {
var p = this._get(start), o, list = new LinkedList();
while (deleteCount--) {
o = this._delete(p);
p = o.p;
list.push(o.v);
if (null===p) {break;}
}
var that = this;
if (typeof items !== "undefined") {
var i = 0;
if (items instanceof Array) {
for (i = 0; i < items.length; i++) {
p = that._insertBefore(p, items[i]);
}
} else if (items instanceof LinkedList) {
for (i = 0; i < items.length; i++) {
p = that._insertBefore(p, items.get(i));
}
} else {
that._insertBefore(p, items);
}
}
return list;
}; LinkedList.prototype.forEach = function(callback) {
var p = this.head,
index = 0;
do {
callback(p.elem, index);
p = p.next;
index++;
} while (p != this.head);
return this;
}; LinkedList.prototype.map = function(callback) {
var newList = new this.__proto__.constructor();
this.forEach(function(elem) {
newList.push(callback(elem));
});
return newList;
}; LinkedList.prototype.reduce = function(callback, initValue) {
if (this === null) {
throw new TypeError('LinkedList.prototype.reduce ' +
'called on null or undefined');
}
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
var acc = initValue,
p = this.head;
do {
acc = callback(acc, p.elem);
p = p.next;
} while (p != this.head); return acc;
}; LinkedList.prototype.join = function(sep) {
var s = "";
if (this.length === 0) {
return s;
}
if (this.length === 1) {
return this.head.elem;
}
var p = this.head;
do {
s += p.elem.toString() + sep;
p = p.next;
} while (p != this.head.prev);
s += p.elem.toString();
return s;
}; LinkedList.prototype.toString = function() {
return '[' + this.join(',') + ']';
}; LinkedList.prototype.insertBeforeIndex = function(index, elem) {
if (index === 0) {
this.unshift(elem);
return this.length;
}
if (index >this.length) {
throw new DOMException('index out of bounds');
}
if (index === this.length) {
this.append(elem);
return this.length;
}
var node = new Node(elem);
if (index === this.length-1) {
var tail = this.head.prev;
node.next = tail;
node.prev = tail.prev;
tail.prev.next = node;
tail.prev = node;
} else {
var p = this._get(index); node.next = p;
node.prev = p.prev;
p.prev.next = node;
p.next.prev = node;
}
++this.length; return this.length;
};

  

  

// Array like

 1 // test
2 var list = new LinkedList();
3
4 for (var i = 1; i < 10; i++) {
5 list.push(i);
6 }
7 for (i = 0; i < list.length; i++) {
8 console.log(list.get(i)); // 1,2,3,4,5,6,7,8,9
9 }
10
11 // list.forEach(function(elem) {console.log(elem);});
12 var newList = list.map(function(elem) {
13 return elem - 1;
14 });
15 console.log(newList.toString()); // 0,1,2,3,4,5,6,7,8
16 newList.shift();
17 console.log(newList.toString()); // 1,2,3,4,5,6,7,8
18
19 var oList = new LinkedList();
20 oList.push({ x: 2 });
21 oList.push({ x: 2 });
22 oList.push({ x: 3 });
23
24 var mul = oList.reduce(function(a, c) {
25 return a * c.x;
26 }, 1);
27 console.log(mul); // 12

map,reduce

// test 2

var a = [3, 12, 17, 16, 73, 32, 61, 46, 52, 49, 6, 5];
var list = new LinkedList(a);
console.log(list.toString());
console.log('array: ' + a.length + ' list: ' + list.length); list.insertBeforeIndex(0, 99);
console.log(list.toString()); list.insertBeforeIndex(3, 99);
console.log(list.toString()); list.insertBeforeIndex(list.length, 100);
console.log(list.toString()); list.insertBeforeIndex(list.length-1, 98);
console.log(list.toString()); console.log(list.length);

insertBeforeIndex

// test splice

function getTopN(a, n) {

    function _getMaxElem(a) {
if (a.length === 0)
throw "empty array"; if (a.length === 1)
return { index: 0, value: a[0] }; var max = a.get(0), index = 0, c;
for (var i = 0; i < a.length; i++) {
c = a.get(i);
if (c > max) {
max = c;
index = i;
}
}
return {
index: index,
value: max
}
} var o = {}, b = [];
while (n--) {
o = _getMaxElem(a);
b.push(o.value);
a.splice(o.index, 1);
} return b;
} /**
* 5 largest elements: [73,61,52,49,46]
* -------------sorted------------------
* [ 73, 61, 52, 49, 46, 32, 17, 16, 12, 6, 5, 3 ]
*/
var a = [3, 12, 17, 16, 73, 32, 61, 46, 52, 49, 6, 5];
var list = new LinkedList(a);
var top5 = getTopN(list, 5);
console.log('5 largest elements: [' + top5.toString() + ']');
console.log('-------------sorted------------------');
console.log(a.sort(function(a, b) { return b - a; }));

  

javascript LinkedList js 双向循环链表 Circular Linked List的更多相关文章

  1. 双向链表、双向循环链表的JS实现

    关于链表简介.单链表.单向循环链表.JS中的使用以及扩充方法:  单链表.循环链表的JS实现 关于四种链表的完整封装: https://github.com/zhuwq585/Data-Structu ...

  2. C语言通用双向循环链表操作函数集

    说明 相比Linux内核链表宿主结构可有多个链表结构的优点,本函数集侧重封装性和易用性,而灵活性和效率有所降低.     可基于该函数集方便地构造栈或队列集.     本函数集暂未考虑并发保护. 一  ...

  3. 1.Go语言copy函数、sort排序、双向链表、list操作和双向循环链表

    1.1.copy函数 通过copy函数可以把一个切片内容复制到另一个切片中 (1)把长切片拷贝到短切片中 package main import "fmt" func main() ...

  4. 1.Go-copy函数、sort排序、双向链表、list操作和双向循环链表

    1.1.copy函数 通过copy函数可以把一个切片内容复制到另一个切片中 (1)把长切片拷贝到短切片中 ? 1 2 3 4 5 6 7 8 9 10 11 12 package main   imp ...

  5. Vue.js双向绑定的实现原理和模板引擎实现原理(##########################################)

    Vue.js双向绑定的实现原理 解析 神奇的 Object.defineProperty 这个方法了不起啊..vue.js和avalon.js 都是通过它实现双向绑定的..而且Object.obser ...

  6. 双向循环链表(C语言描述)(四)

    下面以一个电子英汉词典程序(以下简称电子词典)为例,应用双向循环链表.分离数据结构,可以使逻辑代码独立于数据结构操作代码,程序结构更清晰,代码更简洁:电子词典的增.删.查.改操作分别对应于链表的插入. ...

  7. 双向循环链表(C语言描述)(一)

    双向循环链表是链表的一种,它的每个节点也包含数据域和指针域.为了方便程序维护,可以单独为数据域定义一种数据类型,这里以整型为例: typedef int LinkedListData; 双向循环链表( ...

  8. "《算法导论》之‘线性表’":双向循环链表

    本文双链表介绍部分参考自博文数组.单链表和双链表介绍 以及 双向链表的C/C++/Java实现. 1 双链表介绍 双向链表(双链表)是链表的一种.和单链表一样,双链表也是由节点组成,它的每个数据结点中 ...

  9. Angular JS - 3 - Angular JS 双向数据绑定

    一 .数据绑定 1. 数据绑定: 数据从一个地方A转移(传递)到另一个地方B, 而且这个操作由框架来完成2. 双向数据绑定: 数据可以从View(视图层)流向Model(模型,也就是数据), 也可以从 ...

随机推荐

  1. Angular Module 共享模块使用 父模块使用多个子模块

      Component.module.ts import {BrowserModule} from '@angular/platform-browser'; import {LocationStrat ...

  2. C++11 shared_ptr智能指针(超级详细)

    在实际的 C++ 开发中,我们经常会遇到诸如程序运行中突然崩溃.程序运行所用内存越来越多最终不得不重启等问题,这些问题往往都是内存资源管理不当造成的.比如: 有些内存资源已经被释放,但指向它的指针并没 ...

  3. Java事件模型

    1 import javax.swing.*; 2 import java.awt.event.*; 3 public class TestSourceListener { 4 5 public st ...

  4. Struts2常见问题

    时间:2017-1-14 21:29 1.配置Struts2过滤器之后无法正常访问Servlet    自己手动配置过滤器,参数为要访问的Servlet

  5. py2neo学习记录

    py2neo 通用 # -*- coding: UTF-8 -*- from py2neo import Graph, Node, Relationship, walk, NodeMatcher, R ...

  6. 12-SpringCloud GateWay

    GateWay和Zuul说明 Zuul开发人员窝里斗,实属明日黄花 重点关注Gate Way GateWay是什么 上一代zuul 1.x官网 Gateway官网 概述 Cloud全家桶中有个很重要的 ...

  7. vmware 配置不同网段双网卡。

    一.前言 需求:由于LVS演练需要,需要配置两张linux OS网卡,而且是不同网段. 准备: 物理机:单网卡 VMware:centos 6.8 二.配置 第一步:新建虚拟机VMware,cento ...

  8. linux系统下查看svn服务是否启动,重启及设置开机重启

    Linux系统中svn服务是否启动,重启及设置开机启动   安装完svn服务器后虽然好用但是因为经常重启Linux服务器,每次重启完就要去手动启动svn服务器,很是麻烦,于是在网上找了一些方法后,自己 ...

  9. AbpVnext使用分布式IDistributedCache Redis缓存(自定义扩展方法)

    AbpVnext使用分布式IDistributedCache缓存from Redis(带自定义扩展方法) 我的依赖包的主要版本以及Redis依赖如下 1:添加依赖 <PackageReferen ...

  10. vue系统总结2

    注册组件 组件其他补充 组件数据存放 父子组件通信 父级向子级传递信息 子级向父级传递信息 插槽slot 1.1什么是组件化 1.2 注册组件的基本步骤 创建组件构造器 注册组件 使用组件 <d ...