JavaScript数据结构-列表
当不需要在一个很长的序列中查找元素,或者对其进行排序,可以使用列表。如果数据结构非常复杂,就使用别的数据结构。
一个简单列表的例子:
1 /** 2 * 一个简单的列表 3 * @constructor 4 */ 5 var List = function () { 6 this.listSize = 0; 7 this.pos = 0; 8 this.dataSource = [];//初始化一个数组来保存列表元素 9 }; 10 List.prototype = (function () { 11 return { 12 clear: clear, 13 find: find, 14 toString: toString, 15 insert: insert, 16 append: append, 17 remove: remove, 18 front: front, 19 end: end, 20 prev: prev, 21 next: next, 22 hasNext: hasNext, 23 hasPrev: hasPrev, 24 length: length, 25 currPos: currPos, 26 moveTo: moveTo, 27 getElement: getElement 28 }; 29 /** 30 * 给列表最后添加元素的时候,列表元素个数+1 31 * @param element 32 */ 33 function append(element) { 34 this.listSize++; 35 this.dataSource.push(element); 36 } 37 38 /** 39 * @param element 如果传入的是对象,需要判断是否是对象以及两个对象是否相等 40 * @returns {number} 如果找到,返回位置,否则-1 41 */ 42 function find(element) { 43 for (var i = 0; i < this.dataSource.length; i++) { 44 if (this.dataSource[i] === element) { 45 return i; 46 } 47 } 48 return -1; 49 } 50 51 /** 52 * 返回列表元素的个数 53 * @returns {number} 54 */ 55 function length() { 56 return this.listSize; 57 } 58 59 /** 60 * 删除元素成功,元素个数-1 61 * @param element 62 * @returns {boolean} 63 */ 64 function remove(element) { 65 var removeIndex = this.find(element); 66 if (removeIndex !== -1) { 67 this.dataSource.splice(removeIndex, 1); 68 this.listSize--; 69 return true; 70 } 71 return false; 72 } 73 74 /** 75 * 返回要展示的列表 76 * @returns {string} 77 */ 78 function toString() { 79 return this.dataSource.toString(); 80 } 81 82 /** 83 * 插入某个元素 84 * @param element 要插入的元素 85 * @param afterElement 列表中的元素之后 86 * @returns {boolean} 87 */ 88 function insert(element, afterElement) { 89 var insertIndex = this.find(afterElement); 90 if (insertIndex !== -1) { 91 this.dataSource.splice(insertIndex + 1, 0, element); 92 this.listSize++; 93 return true; 94 } 95 return false; 96 } 97 98 /** 99 * 清空列表中的所有元素 100 */ 101 function clear() { 102 delete this.dataSource; 103 this.dataSource = []; 104 this.listSize = this.pos = 0; 105 } 106 107 /** 108 * 将列表的当前位置移动到第一个元素 109 */ 110 function front() { 111 this.pos = 0; 112 } 113 114 /** 115 * 将列表的当前位置移动到最后一个元素 116 */ 117 function end() { 118 this.pos = this.listSize - 1; 119 } 120 121 /** 122 * 返回当前位置的元素 123 * @returns {*} 124 */ 125 function getElement() { 126 return this.dataSource[this.pos]; 127 } 128 129 /** 130 * 将当前位置向前移动一位 131 */ 132 function prev() { 133 --this.pos; 134 } 135 136 /** 137 * 将当前位置向后移动一位 138 */ 139 function next() { 140 ++this.pos; 141 } 142 143 /** 144 * 返回列表的当前位置 145 * @returns {number|*} 146 */ 147 function currPos() { 148 return this.pos; 149 } 150 151 /** 152 * 移动到指定位置 153 * @param position 154 */ 155 function moveTo(position) { 156 this.pos = position; 157 } 158 159 /** 160 * 判断是否有后一位 161 * @returns {boolean} 162 */ 163 function hasNext() { 164 return this.pos < this.listSize; 165 } 166 167 /** 168 * 判断是否有前一位 169 * @returns {boolean} 170 */ 171 function hasPrev() { 172 return this.pos >= 0; 173 } 174 }());
下面是一个基于列表的简单应用:
假设有20部影碟,属于一个TXT文件:
我用nodejs来读取文件内容:
1 var fs = require('fs'); 2 var movies = createMovies('films.txt'); 3 /** 4 * 读取数据,返回数组 5 * @param file 6 * @returns {Array|*} 7 */ 8 function createMovies(file) { 9 var arr = fs.readFileSync(file, 'utf-8').split("\n"); 10 for (var i = 0; i < arr.length; i++) { 11 arr[i] = arr[i].trim(); 12 } 13 return arr; 14 }
然后初始化影碟列表
1 var movieList = new List(); 2 for (var i = 0; i < movies.length; i++) { 3 movieList.append(movies[i]); 4 }
然后定义用户列表和用户前来拿影碟行为
1 var customers = new List(); 2 /** 3 * 用户对象 4 * @param name 用户姓名 5 * @param movie 用户拿走的影碟 6 * @constructor 7 */ 8 var Customer = function (name, movie) { 9 this.name = name; 10 this.movie = movie; 11 }; 12 /** 13 * 用户拿走影碟 14 * @param name 用户的名字 15 * @param movie 影碟的名字 16 * @param movieList 所有影碟列表 17 * @param customerList 用户列表 18 */ 19 function checkOut(name, movie, movieList, customerList) { 20 if (movieList.find(movie) !== -1) { 21 var user = new Customer(name, movie); 22 customerList.append(user);//用户拿掉影碟,讲用户加入customerList 23 movieList.remove(movie);//从movieList中删除掉被拿掉的影碟 24 } else { 25 console.log('没有该电影'); 26 } 27 }
一切就绪之后测试一下之前的代码
1 var fs = require('fs'); 2 var movies = createMovies('films.txt'); 3 var movieList = new List(); 4 var customers = new List(); 5 for (var i = 0; i < movies.length; i++) { 6 movieList.append(movies[i]); 7 } 8 checkOut('Jane', '肖申克的救赎', movieList, customers); 9 displayList(customers); 10 console.log('分割线-----------------'); 11 displayList(movieList);
结果:
Jane,肖申克的救赎 分割线----------------- 教父 教父2 低俗小说 黄金三镖客 十二怒汉 辛德勒名单 黑暗骑士 指环王:王者归来 搏击俱乐部 星球大战5:帝国反击战 飞越疯人院 指环王:护戒使者 盗梦空间 好家伙 星球大战 七武士 黑客帝国 阿甘正传 上帝之城
总结:列表是一种自然的数据组织方式。如果数据存储的顺序不重要,列表是一种非常好的数据结构。