双向链表和普通链表的区别在于,在链表中,一个节点只有链向下一个节点的链接,而在双向链表中,链接是双向的:一个链向下一个元素, 另一个链向前一个元素
与单向链表相比,双向链表有新增两点
- 节点新增 prev 指针
-
实现一个双向链表
function DoublyLinkedList() {let Node = function(element){this.element = element;this.next = null;this.prev = null; //NEW};let length = 0;let head = null;let tail = null; //NEWthis.append = function(element){let node = new Node(element),current;if (head === null){ //first node on listhead = node;tail = node; //NEW} else {//attach to the tail node //NEWtail.next = node;node.prev = tail;tail = node;}length++; //update size of list};this.insert = function(position, element){//check for out-of-bounds valuesif (position >= 0 && position <= length){let node = new Node(element),current = head,previous,index = 0;if (position === 0){ //add on first positionif (!head){ //NEWhead = node;tail = node;} else {node.next = current;current.prev = node; //NEW {1}head = node;}} else if (position === length) { //last item //NEWcurrent = tail; // {2}current.next = node;node.prev = current;tail = node;} else {while (index++ < position){ //{3}previous = current;current = current.next;}node.next = current;previous.next = node;current.prev = node; //NEWnode.prev = previous; //NEW}length++; //update size of listreturn true;} else {return false;}};this.removeAt = function(position){//check for out-of-bounds valuesif (position > -1 && position < length){let current = head,previous,index = 0;//removing first itemif (position === 0){head = current.next; // {1}//if there is only one item, then we update tail as well //NEWif (length === 1){ // {2}tail = null;} else {head.prev = null; // {3}}} else if (position === length-1){ //last item //NEWcurrent = tail; // {4}tail = current.prev;tail.next = null;} else {while (index++ < position){ // {5}previous = current;current = current.next;}//link previous with current's next - skip it to removeprevious.next = current.next; // {6}current.next.prev = previous; //NEW}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;//check first itemif (element == current.element){return 0;}index++;//check in the middle of the listwhile(current.next){if (element == current.element){return index;}current = current.next;index++;}//check last itemif (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;}}
