数据结构:用JS实现链表
来源:互联网 发布:2017好玩的手游 知乎 编辑:程序博客网 时间:2024/06/15 06:38
链表特点:链表存储有序的元素集合,但不同于数组,链表中的元素在内存中并不是连续放置的。每个元素由一个存储元素本身的节点和一个指向下一个元素的引用(指针或链接)组成。
相对于传统的数组,链表的一个好处在于,添加或移除元素的时候不需要移动其他元素。然而,链表需要使用指针,因此实现链表时需要额外注意。数组的另一个细节是可以直接访问任何位置的元素,而想要访问链表中间的一个元素,需要从起点开始迭代链表直到找到所需元素。
创建链表
我们先搭建一个类的骨架
function LinkedList () { //辅助类 表示要加入链表的项 var Node = function (element) { this.element = element; this.next = null; //指向链表中下一个节点项的指针 }; var length = 0; var head = null; this.append = function (element) {}; //向链表尾部添加一个新的项 this.insert = function (position, element) {}; //向链表特定位置插入一个新的项 this.removeAt = function (position) {}; //从链表特定位置移除一项 this.remove = function (element) {}; //从链表中移除一项 this.indexOf = function (element) {}; //返回元素在链表中的索引,如果没有则返回-1 this.isEmpty = function () {}; //判断链表是否为空 this.size = function () {}; //返回链表包含元素个数 this.getHead = function () {}; //返回链表第一个元素 this.toString = function () {}; //只输出元素的值 this.print = function () {}; //打印元素的值}
下面,我们来一一实现他们
this.append = function (element) { var node = new Node(element), current; if (head === null) { //链表为空,添加到首部 head = node; }else { current = head; //循环链表,直到找到最后一项 while (current.next) { current = current.next; } //找到最后一项,将其next赋为node,建立连接 current.next = node; } length++;};
在普通链表中:链表最后一个节点的下一个元素始终是null。
this.removeAt = function (position) { //检查是否越界 if (position > -1 && position < length) { var current = head, previous, index = 0; if (position === 0) { //移除第一项 head = current.next; }else { while (index++ < position) { previous = current; current = current.next; } //将previous与current的下一项链接起来,跳过current,从而移除它 previous.next = current.next; } length--; return current.element; }else { return null; }};
this.insert = function (position, element) { //检查是否越界 if (position >= 0 && position <= length) { var node = new Node(element), current = head, previous, index = 0; if (position === 0) { //在第一个位置添加 node.next = current; head = node; }else { while (index++ < position) { previous = current; current = current.next; } //通过改变指针,将node链接在previous和current之间 node.next = current; previous.next = node; } length++; return true; }else { return false; }};
//只输出链表中元素this.toString = function () { var current = head, string = ""; while (current) { string += "," + current.element; current = current.next; } return string.slice(1);};
this.indexOf = function (element) { var current = head, index = 0; while (current) { if (current.element === element) { return index; } index++; current = current.next; } return -1;};
this.remove = function (element) { var index = this.indexOf(element); return this.removeAt(index);};
this.isEmpty = function () { return length === 0;};
this.size = function () { return length;};
//head是一个私有变量,当需要在类的实现外部循环访问链表时,就可以使用getHead方法获取类的第一个元素this.getHead = function () { return head;};
this.print = function () { console.log( this.toString() );};
接下来,我们在上面的基础上做点扩展
双向链表
一个链向下一个元素,另一个链向前一个元素。
function DoublyLinkedList () { var Node = function (element) { this.element = element; this.next = null; this.prev = null; //新 }; var length = 0; var head = null; var tail = null; //新 对最后一项的引用 //方法}
this.append = function (element) { var node = new Node(element), current; if (head === null) { //链表为空,添加到首部 head = node; tail = node; //新 }else { current = head; //循环链表,直到找到最后一项 while (current.next) { current = current.next; } //找到最后一项,将其next赋为node,建立连接 current.next = node; tail = node; //新 } length++;};
this.insert = function (position, element) { //检查是否越界 if (position >= 0 && position <= length) { var node = new Node(element), current = head, previous, index = 0; if (position === 0) { //在第一个位置添加 if (!head) { //新 head = node; tail = node; }else { node.next = current; current.prev = node; //新 head = node; } }else if (position === length) { //新 最后一项 //改变指针,再把node赋值给tail current = tail; current.next = node; node.prev = current; tail = node; }else { while (index++ < position) { previous = current; current = current.next; } //通过改变指针,将node链接在previous和current之间 node.next = current; previous.next = node; current.prev = node; //新 node.prev = previous; //新 } length++; return true; }else { return false; }};
this.removeAt = function (position) { //检查是否越界 if (position > -1 && position < length) { var current = head, previous, index = 0; if (position === 0) { //移除第一项 head = current.next; //新 如果只有一项,更新tail if (length === 1) { tail = null; }else { head.prev = null; } }else if(position === length - 1) { //新 最后一项 current = tail; tail = current.prev; tail.next = null; }else { while (index++ < position) { previous = current; current = current.next; } //将previous与current的下一项链接起来,跳过current,从而移除它 previous.next = current.next; current.next.prev = previous; //新 } length--; return current.element; }else { return null; }};
其它的方法和单向链表一样
扩展就到这里,有兴趣的朋友可以试试在此基础上再进行扩展
比如,循环链表:将链表最后一项的next指向head
在升级就是双向循环链表,感觉要被玩坏了~
阅读全文
0 0
- 数据结构:用JS实现链表
- 数据结构:用JS实现栈
- 数据结构:用JS实现队列
- 使用js对链表数据结构的实现
- JS的基本数据结构实现---线性表
- js数据结构之链表
- js数据结构之链表
- 数据结构-实现链表
- 数据结构链表实现
- 数据结构:线性表删除操作的php和js实现
- 数据结构:线性表删除操作的php和js实现
- 用数组实现js中的堆栈 或者队列数据结构
- Day-9 用js实现数据结构中的排序
- 数据结构:用JS模拟Set类的实现
- 链表数据结构的实现
- 数据结构实现静态链表
- 数据结构实现循环链表
- 数据结构链表STL实现
- codeforce-767A
- C++中容易忘记的知识点——vector和string(三)
- 博客两个有意思的特效
- halcon学习笔记——(6)单摄像机标定
- Material 组件 md-icon
- 数据结构:用JS实现链表
- SonarQube插件开发自定义规则(6)注意事项
- 【LibUIDK界面库系列文章】Web Browser控件避免闪烁
- halcon学习笔记——(7)HALCON标定后的二维测量
- 常用的Sql 函数
- Palindrome Number
- 51nod 1042 数字0-9的数量
- halcon学习笔记——(8)由标定板得到测量平面位姿
- [LeetCode] 17. Letter Combinations of a Phone Number