链表是由一组不必相连的内存结构,按特定的顺序链接在一起的抽象数据类型。链表存储有序的元素集合,链表中的元素在内存中并不是连续放置的。每个元素有一个存储元素本身的节点和一个指向下一个元素的指针组成。
(链表又分为单向链表、双向链表、循环链表)
(单项链表)如下图:
链表的每个节点都有一个指针来指向下一个节点。而要访问链表中的某一个元素,可以从起点(表头)开始迭代链表直接找到需要的元素。
利用JavaScript实现链表如下:
1.创建一个LinkedList, 里面包含了一些链表的方法;
2.创建Node类用于创建节点,Node类有element属性,next属性,分别对应每个节点的值以及指向下一个元素的指针;
3.定义append方法用于在链表尾部直接加入一个节点:
1)创建一个节点(创建node对象), 声明一个current变量用作表示当前的节点;
2)当头结点(表头)为空时,直接让加入的节点为头节点,
若头结点不为空,把头结点head赋值给current,迭代current的next指针,当current的next指针指向不为空时,
令current变为下一个节点。若current的next指针为空时,令current的next指针指向加入的节点node;
3)令链表的长度增加。
4.定义insert方法用于在链表中的特定位置添加节点:
1)insert方法里有两个参数, position和element, 分别表示链表节点的位置和添加的节点值;
2)判断position是否会小于零并且不超过与链表的长度,若不符合要求则返回false;
3)若符合要求则创建一个节点,声明一个current变量用作表示当前的节点,pervious表示当前节点的上一个节点,index表示位置。
4)若插入的位置为0,则令节点node的next指针指向current(已赋值head,即头结点),令头结点为节点node;
5)若插入的位置不为0,则自增index,迭代,若index自增后小与position,则让pervious为当前的current节点,令current变为current.next指向的下一个节点。
若index自增后不小于position则令node节点的next指针指向current,pervious的next指针指向node;
6)令链表长度增加,返回true。
(其实插入只是想要插入的位置的两个节点的指针,然后插入再连接)
5.定义removeAt方法用于删除特定位置的节点:
1)检查越界值,若越界则返回null,若不越界,则声明current并赋值为头结点head,pervious为当前节点的上一个节点,index为位置;
2)若position为0时,令头结点head为current(头结点head).next指向的下一个节点。
3)若position不为0,则自增index,迭代,若index自增后小于position,则让pervious为当前的current节点,令current变为current.next指向的下一个节点。
4)若index自增后不小于position时,令pervious的next指针指向current的next指针指向的节点。
5)令链表长度减少。
6.定义indexOf方法用于返回需查询节点的位置:
1)声明current用作表示当前位置的节点并赋值head节点,声明index表示位置并赋值为1;
2)迭代current,当current为空时返回-1;
3)若current不为空,则判断需查询的节点的值与当前节点的值是都匹配,若匹配,则返回位置index;
4)index自增,令current为current的next指针指向的下一个节点。
定义remove方法用于直接删除想删除的节点:
1)查询该节点的位置;
2)利用removeAt方法删除改节点。
7.定义getHead方法用于返回头结点;
定义isEmpty方法用于判断链表是否为空;
定义size方法用于返回链表长度。
8.定义toString方法用于输出链表,同样是迭代;
定义print方法用于打印链表。
(双向链表)如下图:
双向链表即每个节点都有两个指针,一个用于指向上一个节点,一个用于指向下一个节点
利用JavaScript实现双向链表(类似单向链表,不详讲):
参考 《学习JavaScript 数据结构与算法》