博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
javascript实现数据结构与算法系列:功能完整的线性链表
阅读量:4614 次
发布时间:2019-06-09

本文共 7433 字,大约阅读时间需要 24 分钟。

由于链表在空间的合理利用上和插入,删除时不需要移动等的有点,因此在很多场合下,它是线性表的首选存储结构。然而,它也存在着实现某些基本操作,如求线性表长度时不如顺序存储结构的缺点;另一方面,由于在链表中,结点之间的关系使用指针来表示,则数据元素在线性表中的“位序”的概念已淡化,而被数据元素在线性链表中的“位置”所代替。为此,从实际出发重新定义线性链表及其基本操作

 

结构图:

 

1 (function(module){  2   function List() {  3     this.head = null;  4     this.tail = null;  5   }  6   module.exports = List;  7   8   List.mergeList = function (a, b, compare) {  9     var ha = a.head; 10     var hb = b.head; 11     var pa = ha; 12     var pb = hb; 13     var c = new List(); 14     var q; 15     compare = compare || function (data1, data2) { 16       return data1 <= data2; 17     }; 18  19     while (pa && pb) { 20       var data1 = pa.data; 21       var data2 = pb.data; 22  23       if (!compare(data1, data2)) { 24         // delete head node 25         q = a.delFirst(); 26         // append the node to c linkedList 27         c.append(q); 28         pa = a.head; 29       } else { 30         q = b.delFirst(); 31         c.append(q); 32         pb = b.head; 33       } 34     } 35  36     if (pa) { 37       c.append(pa); 38     } else { 39       c.append(pb); 40     } 41  42     return c; 43   }; 44  45   List.prototype = { 46     makeNode: function(data, next){ 47       return { 48         data: data != null ?  data : null, 49         next: next || null 50       }; 51     }, 52     delFirst: function () { 53       var head = this.head; 54       this.head = this.head.next; 55       head.next = null; 56  57       if(this.head === null) this.tail = null; 58       return head; 59     }, 60     append: function (node) { 61       if (this.head !== null) { 62         this.tail.next = node; 63         this.tail = this.tail.next; 64       } else { 65         this.head = node; 66         this.tail = node; 67       } 68     }, 69     add: function (data) { 70       if (this.head === null) { 71         this.head = this.makeNode(data); 72         this.tail = this.head; 73       } else { 74         this.tail.next = this.makeNode(data); 75         this.tail = this.tail.next; 76       } 77  78       this.tail.data = data; 79     }, 80     'delete': function (data) { 81       var current = this.head; 82       var previous = this.head; 83       var elem; 84  85       while (current !== null) { 86         if (data === current.data) { 87           if (current === this.head) { 88             this.head = current.next; 89             elem =  current.data; 90             break; 91           } 92  93           if (current === this.tail) this.tail = previous; 94  95           previous.next = current.next; 96           elem =  current.data; 97           break; 98         } 99 100         previous = current;101         current = current.next;102       }103 104       if(this.head === null) this.tail = null;105 106       return elem ? elem : false;107     },108     insertAsFirst: function (data) {109       var temp = this.makeNode(data);110       temp.next = this.head;111       this.head = temp;112     },113     insertAfter: function (target, data) {114       var current = this.head;115       while (current !== null) {116         if (current.data === target) {117           var temp = this.makeNode(data);118           temp.next = current.next;119 120           if (current === this.tail) this.tail = temp;121 122           current.next = temp;123           return;124         }125 126         current = current.next;127       }128     },129     item: function (index) {130       var current = this.head;131 132       while (current !== null) {133         if (--index === 0) return current;134 135         current = current.next;136       }137 138       return null;139     },140     each: function (callback) {141       var current = this.head;142 143       while (current !== null) {144         callback(current);145         current = current.next;146       }147     },148     orderInsert: function(data, cmp){149       cmp = typeof cmp === 'function' ? cmp : function (a, b){150         if(a > b)151           return 1;152         else if(a === b)153           return 0;154         else155           return -1;156       };157       var previous = this.head;158       var current = this.head;159 160       if(current === null){161         this.head = this.tail = this.makeNode(data);162         return;163       }164 165       var me = this;166       while(current){167         var ret = cmp(data, current.data);168         // 如果插入元素大于当前元素,准备下次遍历169         if(ret > 0){170           previous = current;171           current = current.next;172 173           // 如果等于,直接插入到后面174         } else if(ret === 0){175           return insertBetween(data, previous, current);176 177           // 如果小于则插入到前节点和当前节点中178           // 因为已经是排序了,所以不需要多余判断了179         } else {180           if(this.head === previous && previous === current){181             return this.insertAsFirst(data);182           } else {183             return insertBetween(data, previous, current);184           }185         }186       }187 188       // 插入到最后一个结点189       previous.next = this.makeNode(data);190       this.tail = previous.next;191 192       function insertBetween(data, a, b){193         var temp = me.makeNode(data);194         temp.next = b;195         a.next = temp;196         return true;197       }198     }199   };200   /*201   var list = new List();202   list.add('b');203   list.insertAsFirst('a');204   list.insertAfter('b', 'c');205   console.log(list.item(2));206   console.log(JSON.stringify(list));207   list.each(function (node) {208     if (node.data === 'b') {209       console.log('get b in each');210     }211   });212   list['delete']('c');213   list['delete']('a');214   console.log(list);215 216   var list2 = new List();217   list2.add('c');218   list2.insertAsFirst('d');219   list2.insertAfter('d', 'b');220   console.log(JSON.stringify(list2));221 222   var list3 = List.mergeList(list, list2);223   console.log(list3);224   */225   /*226   var list = new List();227 228   list.orderInsert('e');229   list.orderInsert('b');230   list.orderInsert('c');231   list.orderInsert('a');232   list.orderInsert('d');233   list.orderInsert('f');234   */235 }(this.module || this));

 

以下是对应的单元测试代码:

1 describe('linkedList tests', function(){ 2  3   var list = new List(); 4  5   it('should find the second item', function(){ 6     list.add('b'); 7     expect(list.head.data).toBe('b'); 8     expect(list.tail.next).toBe(null); 9 10     list.insertAsFirst('a');11     expect(list.head.data).toBe('a');12     expect(list.head.next.data).toBe('b');13 14     list.insertAfter('b', 'c');15     expect(list.item(2).data).toBe('b');16     expect(list.tail.data).toBe('c');17   });18 19   it('should remove one item', function(){20     expect(list['delete']('c')).toBe(true);21     list['delete']('a');22     expect(list.head.data).toBe('b');23   });24 25   var list2 = new List();26 27   it('should match the json', function(){28     list2.add('c');29     list2.insertAsFirst('d');30     list2.insertAfter('d', 'b');31     expect(JSON.stringify(list2)).toBe('{"head":{"data":"d","next":{"data":"b","next":{"data":"c","next":null}}},"tail":{"data":"c","next":null}}');32   });33 34   it('should merge the lists', function(){35     var list3 = List.mergeList(list, list2);36     expect(list3.head.data).toBe('d');37     expect(list3.head.next.data).toBe('b');38     expect(list3.head.next.next.data).toBe('c');39     expect(list3.tail.data).toBe('b');40   });41 });

 

转载于:https://www.cnblogs.com/webFrontDev/p/3668187.html

你可能感兴趣的文章
证明一个数能被3整除,当且仅当它的各位数的和能被3整除
查看>>
2018秋寒假作业4—PTA编程总结1
查看>>
android自适应屏幕
查看>>
2019-北航面向对象-电梯作业总结
查看>>
SqlHelper
查看>>
初识算法、数据结构
查看>>
Luogu4069 SDOI2016 游戏 树链剖分、李超线段树
查看>>
Java的内部类真的那么难以理解?
查看>>
一文搞懂Java环境,轻松实现Hello World!
查看>>
hash实现锚点平滑滚动定位
查看>>
也谈智能手机游戏开发中的分辨率自适应问题
查看>>
【转】MYSQL数据库设计规范与原则
查看>>
《中国大历史》—— 读后总结
查看>>
回溯法算法框架
查看>>
残差学习【转载】
查看>>
0302 关于IT行业的就业感想
查看>>
3、流程语句相关练习
查看>>
30、git 使用
查看>>
iOS网络-02-数据解析(JSON与XML)
查看>>
python列表求和的几种等效电路
查看>>