今天拿到了清华大学出版的《数据结构(C语言版)》,琢磨着通过学习算法的方式来提升自己的书写javascript的能力。不管怎么说,先开始吧,就算不能帮助掌握javascript,我想对算法的理解也是有帮助的。
另:昨天的目录结构还是错的。。。
链表
1. 定义
线性表(linear_list)是最常用且最简单的一种数据结构。一个线性表是n个数据元素的有限序列。今天先学习的是线性链表。线性表的链式结构的特点是用一组任意的存储单元存储线性表的数据元素(可以是连续的也可以是不连续的)。因此,为了表示每个数据元素 ai 与其直接后继元素 ai+1 之间的逻辑关系,对数据元素 ai 来说,除了存储其本身的信息之外,还需存储一个指示其直接后继的信息(即直接后继的存储位置)。这两部分信息组成数据元素 ai 的存储映像,称为结点(node)。它包括两个域:其中存储数据元素信息的域称为数据域;存储直接后继存储位置的被称为指针域。指针域中存储的信息称作指针或链。n个节点( ai ( 1≤i≤ n )的存储映像)链结成一个链表,即为线性表
(a1,a2,a3...an)
的链式存储结构。又由于此链表的每个结点中只包含一个指针域,所以又称线性链表链表或单链表。
2. 线性表的顺序表示和实现
线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素。如下图
//以下是javascript实现线性表的代码
首先是要先实现结点
function Node(element){
this.element = element;
this.next = null;
},//实现节点,next指的是直接后继元素的存储地址
然后构造一个链表并且给出头结点
function List(){
this.element = new Node("head");//头结点
}
接下来实现链表的增删查改
List.prototype = {
//查找结点
searchNode:function(item){
var curNode = this.head;//头结点
//在没有查找到item之前就一直让curNode指向下一个结点
while(curNode !== item){
curNode = curNode.next;
}
return curNode;
},
//查找节点的前驱节点
searchPreNode:function(item){
var curNode = this.head;//头结点
//前驱结点与普通结点的区别在于1:要多判断一次下一个节点是否是最后的结点
//2:判断的是下一个节点的element属性是否等于item
while(!(curNode.next == null) && curNode.next.element !== item){
curNode = curNode.next;
}
retrun curNode;
},
//插入结点
insert:function(newElement,item){
//建立一个新结点,将newElement放进去
var newNode = new Node(newElement);
//找到需要插入的位置
var current = this.searchNode(item);
//一波令人智熄的操作实现插入...
//实际原理是:先将新结点的next指向一开始原本指向的“下一个结点”,然后再将原来结点的next指向新结点
newNode.next = current.next;
current.next = newNode;
},
//删除结点
delete:function(item){
//首先找到要删除结点前驱节点
var preNode = this.searchPreNode(item);
//如果前驱节点的指向不为空,则将其设置为指向将要删除结点的next指向的位置
//实际删除操作可以理解为前驱结点直接指向后继结点,这样就实现了删除操作
if(!(preNode.next === null)){
preNode.next = preNode.next.next;
}
},
//修改结点
update:function(item,newIteme){
//修改结点不用注释
var element = this.searchNode(item);
element.element = newItem;
},
}//链表的增删查改方法