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:帝国反击战
飞越疯人院
指环王:护戒使者
盗梦空间
好家伙
星球大战
七武士
黑客帝国
阿甘正传
上帝之城

总结:列表是一种自然的数据组织方式。如果数据存储的顺序不重要,列表是一种非常好的数据结构。

posted @ 2016-09-22 18:25  雨天.  阅读(3010)  评论(0编辑  收藏  举报