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
概念:链表存储有序的元素集合,但不同于数组,链表中的元素在内存中并不是连续放置的。每个 元素由一个存储元素本身的节点和一个指向下一个元素的引用(也称指针或链接)组成。
概念
与数组的区别:相对于传统的数组,链表的一个好处在于,添加或移除元素的时候不需要移动其他元素。数组缺点:(在大多数语言中)数组的大小是固定的,从数组的起点或中间插入或移除项的成本很高,因为需要移动元素(尽管我们已经学过的JavaScript的array类方法可以帮 我们做这些事,但背后的情况同样是这样)。 然而,链表需要使用指针,因此实现链表时需要额外注意。数组的另一个细节是可以直接访问任何位置的任何元素,而要想访问链表中间的一个元素,需要从起点(表头)开始迭代列表直到找到 所需的元素。
与数组的区别
function LinkedList() { let Node = function(element){ this.element = element; this.next = null; }; let length = 0; let head = null; this.append = function(element){ let node = new Node(element), current; //向链表尾部追加元素 if (head === null){ // 列表中第一个节点 (场景1:列表为空,添加的是第一个元素) head = node; } else { current = head; //(场景2:列表不为空,向其追加元素。) while(current.next){ //循环列表,直到找到最后一项 current = current.next; } current.next = node;//找到最后一项,将其next赋为node,建立链接 } length++; //更新列表的长度 }; //在任意位置插入元素 this.insert = function(position, element){ if (position >= 0 && position <= length){ //检查越界值 let node = new Node(element), current = head, previous, index = 0; if (position === 0){ //在第一个位置添加(场景1:需要在列表的起点添加一个元素,也就是第一个位置。) node.next = current; head = node; } else { //(场景2:在列表中间或尾部添加一个元素) while (index++ < position){ //不断地循环,直到找到要插入的位置 previous = current; current = current.next; } node.next = current; //插入元素 previous.next = node; } length++; //更新列表的长度 return true; } else { return false; } }; //从链表中移除元素 this.removeAt = function(position){ if (position > -1 && position < length){//检查越界值 let current = head, previous, index = 0; if (position === 0){ //移除第一项 head = current.next; } else { while (index++ < position){ //不断地循环,直到找到要移除目标的位置 previous = current; current = current.next; } previous.next = current.next; //将previous与current的下一项链接起来:跳过current,从而移除它 } length--; //更新列表的长度 return current.element; } else { return null; } }; this.remove = function(element){ let index = this.indexOf(element); return this.removeAt(index); }; this.indexOf = function(element){ //indexOf方法接收一个元素的值,如果在列表中找到 它,就返回元素的位置,否则返回-1。 let current = head, index = 0; while (current) { if (element === current.element) { return index; } index++; current = current.next; } return -1; }; this.isEmpty = function() { return length === 0; }; this.size = function() { return length; }; this.getHead = function(){ return head; }; this.toString = function(){ //toString方法会把LinkedList对象转换成一个字符串 let current = head, string = ''; while (current) { string += current.element + (current.next ? ', ' : ''); current = current.next; } return string; }; this.print = function(){ console.log(this.toString()); }; }
双向链表和普通链表的区别:在链表中, 一个节点只有链向下一个节点的链接,而在双向链表中,链接是双向的:一个链向下一个元素, 另一个链向前一个元素。双向链表提供了两种迭代列表的方法:从头到尾,或者反过来。我们也可以访问一个特定节 点的下一个或前一个元素。在单向链表中,如果迭代列表时错过了要找的元素,就需要回到列表 起点,重新开始迭代。这是双向链表的一个优点。
双向链表和普通链表的区别
function DoublyLinkedList() { let Node = function(element){ this.element = element; this.next = null; this.prev = null; //新增的 }; let length = 0; let head = null; let tail = null; //新增的 用来保存对列表最后一 项的引用的tail属性 this.append = function(element){ let node = new Node(element), current; if (head === null){ //在第一个位置添加 head = node; tail = node; //NEW } else { //attach to the tail node //NEW tail.next = node; node.prev = tail; tail = node; } length++; //update size of list }; this.insert = function(position, element){ if (position >= 0 && position <= length){ //检查越界值 let 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) { //最后一项 //新增的 current = tail; //current变量将引用最后一个元素 current.next = node; node.prev = current; tail = node; } else { while (index++ < position){ //迭代 列表,直到到达要找的位置 previous = current; current = current.next; } 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){//检查越界值 let current = head, previous, index = 0; if (position === 0){ //移除第一项 head = current.next; // {1} //如果只有一项,更新tail //新增的 if (length === 1){ tail = null; } else { head.prev = null; } } else if (position === length-1){ //最后一项 //新增的 current = tail; // {4} 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; } }; this.remove = function(element){ let index = this.indexOf(element); return this.removeAt(index); }; this.indexOf = function(element){ let current = head, index = -1; if (element == current.element){ return 0; } index++; while(current.next){ if (element == current.element){ return index; } current = current.next; index++; } if (element == current.element){ return index; } return -1; }; this.isEmpty = function() { return length === 0; }; this. size = function() { return length; }; this.toString = function(){ let current = head, s = current ? current.element : ''; while(current && current.next){ current = current.next; s += ', ' + current.element; } return s; }; this.inverseToString = function() { let current = tail, s = current ? current.element : ''; while(current && current.prev){ current = current.prev; s += ', ' + current.element; } return s; }; this.print = function(){ console.log(this.toString()); }; this.printInverse = function(){ console.log(this.inverseToString()); }; this.getHead = function(){ return head; }; this.getTail = function(){ return tail; } }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
链表
概念
:链表存储有序的元素集合,但不同于数组,链表中的元素在内存中并不是连续放置的。每个 元素由一个存储元素本身的节点和一个指向下一个元素的引用(也称指针或链接)组成。与数组的区别
:相对于传统的数组,链表的一个好处在于,添加或移除元素的时候不需要移动其他元素。数组缺点:(在大多数语言中)数组的大小是固定的,从数组的起点或中间插入或移除项的成本很高,因为需要移动元素(尽管我们已经学过的JavaScript的array类方法可以帮 我们做这些事,但背后的情况同样是这样)。然而,链表需要使用指针,因此实现链表时需要额外注意。数组的另一个细节是可以直接访问任何位置的任何元素,而要想访问链表中间的一个元素,需要从起点(表头)开始迭代列表直到找到 所需的元素。
创建链表
双向链表
双向链表和普通链表的区别
:在链表中, 一个节点只有链向下一个节点的链接,而在双向链表中,链接是双向的:一个链向下一个元素, 另一个链向前一个元素。双向链表提供了两种迭代列表的方法:从头到尾,或者反过来。我们也可以访问一个特定节 点的下一个或前一个元素。在单向链表中,如果迭代列表时错过了要找的元素,就需要回到列表 起点,重新开始迭代。这是双向链表的一个优点。The text was updated successfully, but these errors were encountered: