We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
链表的数据结构如下:
单链表,由于标识出链表的起始节点却有点麻烦,随意大部分链表最前面有一个特殊的节点,叫做头节点,链表结构改造如下
链表插入或删除一个元素效率非常高,只需要修改相应元素上的指针就可以了.
下图展示了向链表插入一个 cookies 元素和删除一个 Bacon 元素
链表还有其他一些操作,但插入和删除元素最能说明链表为什么如此有用
设计一个链表包含两个类
Node 类包含两个属性:data 用来保存节点上的数据,next 用来保存指向下一个节点的链接。
var Node = function(data) { this.data = data; this.next = null; };
LinkList 类提供了插入节点/删除节点/显示列表元素的方法,以及一些辅助方法
function LList() { //链表只有一个属性,那就是使用一个 Node 对象来保存该链表的头节点 this.head = new Node("head"); this.find = find; //查找方法 this.insert = insert; //插入方法 this.remove = remove; //删除方法 this.display = display; //展示节点 }
链表只有一个属性head,那就是使用一个 Node 对象来保存该链表的头节点,head 节点的 next 属性被初始化为 null,当有新元素插入时,next 会指向新的元素
head
接下来实现一下链表的其他方法
find
next指向null
function find(item) { var currNode = this.head; //从起点开始迭代列表直到找到元素 while (!(currNode.next == null) && currNode.data != item) { currNode = currNode.next; } return currNode; }
2.insert方法,链表中插入一个节点。向链表中插入新节点时,需要明确指出要在哪个节点前面或后面插入。
insert
function insert(newElement, item) { var newNode = new Node(newElement); //找到需要插入节点的位置 var current = this.find(item); //把新节点的next指向(`current.next`这个是下一个节点) newNode.next = current.next; //然后再把current.next指向新的节点 current.next = newNode; }
3.remove方法,从链表中删除节点时,需要先找到待删除节点前面的节点.找到节点后,修改它的 next 属性,使其不再指向待删除节点,而是指向待删除节点的下一个节点.
remove
//找到待删除节点前面的节点 function findPrevious(item) { var currNode = this.head; while (!(currNode.next == null) && currNode.next.data != item) { currNode = currNode.next; } return currNode; } function remove(item) { //找到待删除节点前面的节点 var prevNode = findPrevious(item); if (!(prevNode.next == null)) { //把前一个的节点,指向要删除节点的下一个节点 prevNode.next = prevNode.next.next; } }
4.display方法,显示链表中的所有元素
display
function display() { var currNode = this.head; while (!(currNode.next == null)) { console.log(currNode.data); currNode = currNode.next; } }
用 ES6 的 class 整体上实现以下
class Node { constructor() { this.data = data; this.next = null; } } class LList { constructor() { this.head = new Node("head"); } find(item) { var currNode = this.head; //从起点开始迭代列表直到找到元素 while (!(currNode.next == null) && currNode.data != item) { currNode = currNode.next; } return currNode; } insert(newElement, item) { var newNode = new Node(newElement); //找到需要插入节点的位置 var current = this.find(item); //把新节点的next指向(`current.next`这个是下一个节点) newNode.next = current.next; //然后再把current.next指向新的节点 current.next = newNode; } findPrevious(item) { var currNode = this.head; while (!(currNode.next == null) && currNode.next.data != item) { currNode = currNode.next; } return currNode; } remove(item) { //找到待删除节点前面的节点 var prevNode = findPrevious(item); if (!(prevNode.next == null)) { //把前一个的节点,指向要删除节点的下一个节点 prevNode.next = prevNode.next.next; } } display() { var currNode = this.head; while (!(currNode.next == null)) { console.log(currNode.data); currNode = currNode.next; } } }
测试一下实现的方法
var cities = new LList(); cities.insert("kebi", "head"); cities.insert("yaoming", "kebi"); cities.insert("heyushuo", "yaoming"); cities.display(); //kebi yaoming heyushuo console.log("-----------"); cities.insert("aaa", "yaoming"); cities.display(); //kebi yaoming aaa heyushuo cities.remove("aaa"); console.log("-----------"); cities.display(); //kebi yaoming heyushuo
双向链表是在单链表的每个结点中,再设置一个指向其前驱结点的指针域。所以在双向链表中的结点都有两个指针域,一个指向直接后继,另一个指向直接前驱。
此时向链表插入一个节点需要更多的工作,我们需要指出该节点正确的前驱和后继。但是在从链表中删除节点时,效率提高了,不需要再查找待删除节点的前驱节点了。
循环链表和单向链表相似,节点类型都是一样的。将单链表中尾结点的指针由空指针指向头节点,就使整个单链表形成一个环,这种头尾相接的单链表就简称为循环链表。
双向链表和循环链表就不一一实现了,可以看《JavaScript 数据结构与算法》了解更多
参考 《JavaScript 数据结构与算法》参考
参考
《JavaScript 数据结构与算法》参考
The text was updated successfully, but these errors were encountered:
No branches or pull requests
链表和数组的区别
链表的数据结构如下:
单链表
单链表,由于标识出链表的起始节点却有点麻烦,随意大部分链表最前面有一个特殊的节点,叫做头节点,链表结构改造如下
链表插入或删除一个元素效率非常高,只需要修改相应元素上的指针就可以了.
下图展示了向链表插入一个 cookies 元素和删除一个 Bacon 元素
链表还有其他一些操作,但插入和删除元素最能说明链表为什么如此有用
实现一个单链表
设计一个链表包含两个类
Node 类包含两个属性:data 用来保存节点上的数据,next 用来保存指向下一个节点的链接。
LinkList 类提供了插入节点/删除节点/显示列表元素的方法,以及一些辅助方法
链表只有一个属性
head
,那就是使用一个 Node 对象来保存该链表的头节点,head 节点的 next 属性被初始化为 null,当有新元素插入时,next 会指向新的元素接下来实现一下链表的其他方法
find
方法(这里需要注意一点当查询到最后一个的时候next指向null
)2.
insert
方法,链表中插入一个节点。向链表中插入新节点时,需要明确指出要在哪个节点前面或后面插入。3.
remove
方法,从链表中删除节点时,需要先找到待删除节点前面的节点.找到节点后,修改它的 next 属性,使其不再指向待删除节点,而是指向待删除节点的下一个节点.4.
display
方法,显示链表中的所有元素用 ES6 的 class 整体上实现以下
测试一下实现的方法
双向链表
双向链表是在单链表的每个结点中,再设置一个指向其前驱结点的指针域。所以在双向链表中的结点都有两个指针域,一个指向直接后继,另一个指向直接前驱。
此时向链表插入一个节点需要更多的工作,我们需要指出该节点正确的前驱和后继。但是在从链表中删除节点时,效率提高了,不需要再查找待删除节点的前驱节点了。
循环链表
循环链表和单向链表相似,节点类型都是一样的。将单链表中尾结点的指针由空指针指向头节点,就使整个单链表形成一个环,这种头尾相接的单链表就简称为循环链表。
双向链表和循环链表就不一一实现了,可以看《JavaScript 数据结构与算法》了解更多
The text was updated successfully, but these errors were encountered: