1.简介
其实在大学的时候就已经学过数据结构了,不过当时是C语言版的,如今有时间就又重新复习一遍,补一下基础,这次打算用js实现,知识点都是相同的,只不过是实现方式不同而已。
栈和队列相对比较简单,用js的Array对象的push,pop,shift,unshift就可以模拟,也是最常用的数据结构,比如要存储多个元素,用数组就十分方便。但是数组的大小是固定的,从数组的中间插入或删除一条元素的代价比较高,需要移动元素,尽管js的Array的splice就可以简单实现,但背后的实现原理还是一样的。
链表存储有序的元素的集合,它不同于数组,链表中的元素在内存中并不是连续放置的。每个元素由一个存储元素本身的节点和一个指针指向下一个元素的引用组成。
了解了链表的基本结构后,那么就开始用代码实现下吧。
function Node(data){ this.data = data; this.next = null; } function LinkedList(){ this.length = 0; this.head = null; } LinkedList.prototype = { constructor:'LinkedList', //向末尾追加一个元素 append:function(element){}, //向指定位置插入一个元素 insert:function(postion,element){}, //指定位置删除一个元素 removeAt:function(postion){}, //删除指定的节点 remove:function(element){}, //返回元素在链表中的位置 indexOf:function(element){}, //链表是否为空 isEmpty:function(){}, getLength:function(){} }
2.追加一个节点
向LinkedList对象尾部添加一个元素时,可能有两种情景:列表为空,添加的是第一个元素,或者列表不为空,向其追加元素。
append:function(element){ var node = new Node(element), current; if(this.head == null){ this.head = node; }else{ current = this.head; while(current.next){ current = current.next; } current.next = node; } this.length++; }
结果如下:
现在我们可以成功创建一个链表啦。
2.链表的删除操作
删除操作也有两种情况:头结点和非头结点。我们要实现两种remove方法:第一种从特定位置移除,第二种指定元素移除。
下面是根据给定位置移除一个元素的方法实现:
removeAt:function(postion){ //边界检查 if(postion>=0 && postion<=this.length){ var current = this.head, index = 0, //用于保存前一个节点 previous; if(postion == 0){ this.head = current.next; }else{ //否则循环找到指定位置 while(index++ < postion){ previous = current; current = current.next; } previous.next = current.next; } this.length--; return current.data; }else{ return null; } }
3.插入操作
代码具体实现如下,应该很好理解.
insert:function(postion,element){ //越界判断 if(postion>=0 && postion<=this.length){ var node = new Node(element), current = this.head, index = 0, //用于保存前一个节点 previous; //在头部之前插入 if(postion == 0){ node.next = current; this.head = node; }else{ while(index++<postion){ previous = current; current = current.next; } node.next = current; previous.next = node; } this.length++; return true; }else{ return false; } }
4.其他实现方法
isEmpty(),getSize(),toString()等等实现就比较简单了
5.约瑟夫环问题实现
约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N=6,M=5,被杀掉的顺序是:5,4,6,2,3,1。
var Josephus = { init:function(){ this.suicideNum = 3; //第几个自杀 this.createCircle(); this.suicide(); }, createCircle:function(){ this.linkedList = new LinkedList(); for(var i = 0;i<10;i++){ this.linkedList.append(i+1); } this.linkedList.setCircle(); }, suicide:function(){ var current = this.linkedList.head, previous = current; for(var i = 0;i<this.linkedList.length;i++){ //最后剩下两个人 if(i == this.suicideNum-1 && this.linkedList.length>2){ previous.next = current.next; console.log("第 "+current.data + " 自杀"); current = current.next; --this.linkedList.length; i = -1; }else{ previous = current;c current = current.next; } } this.linkedList.toString(); } }
单链表的操作就简单介绍到这里,后面还有双链表稍微复杂一点