用JavaScript创建一个简单地列表类,并且实现对列表中的元素进行增删改查的操作。
1.列表的抽象数据类型定义
类型名 | 备注 |
---|---|
ListSize(属性) | 列表的元素个数 |
pos(属性) | 列表的当前位置 |
Length(属性) | 返回列表中元素的个数 |
clear(方法) | 清空列表中的所有元素 |
toString(方法) | 返回列表的字符串形式 |
getElement(方法) | 返回当前位置的元素 |
insert(方法) | 在现有的元素后插入新元素 |
append(方法) | 在列表的末尾添加新元素 |
remove(方法) | 在列表中删除元素 |
front(方法) | 将列表的当前位置设移动到第一个元素 |
end(方法) | 将列表的当前位置移动到最后一个元素 |
prev(方法) | 将当前位置后移一位 |
next(方法) | 将当前位置前移一位 |
currPos(方法) | 返回列表的当前位置 |
moveTo(方法) | 将当前位置移动到指定位置 |
2.实现列表类
2.1.先实现一个List类,定义构造函数。
function List(){
this.listSize=0;
this.pos = 0;
this.dataStore=[]; //初始化一个空数组来保存列表元素
this.clear=clear;
this.find=find;
this.toString=toString;
this.insert=insert;
this.append=append;
this.remove=remove;
this.front=front;
this.end=end;
this.prev=prev;
this.next=next;
this.length=length;
this.currPos=currPos;
this.moveTo=moveTo;
this.getElement=getElement;
this.length=length;
this.contains=contains;
}
2.2. append:给列表添加元素
function append(element){
this.dataStore[this.listSize++] = element;
}
每添加一个新元素,listSize加1。
2.3. remove:从列表中删除元素
首先,要在列表中找到需要删除的元素,然后再删除它,并且要调整底层元素的数组对象填充到删除后留下的空白位置。先从查找方法find()开始。
function fint(element){
for(var i = 0;i<this.dataStore.length;i++){
if(this.dataStore[i] == element){
return i;
}
}
return -1;
}
即使用find()方法在数组中查找需要的元素,若查找到,返回该元素在数组中的位置i,如若找不到,返回-1;再使用remove()方法利用find()方法的返回值对数组dataStore进行截取。数组改变后,数组长度变量listSize的值会减少1。如果元素删除成功,返回true,否则返回false。
function remove(element){
var foundAt = this.find(element);
if(foundAt > -1){
this.dataStore.splice(foundAt,1);
this.listSize--;
return true;
}
return false;
}
注:splice() 方法可删除从 index 处开始的零个或多个元素,并且用参数列表中声明的一个或多个值来替换那些被删除的元素。
2.4. length:列表中有多少个元素
length()方法返回列表中元素的个数:
function length(){
return this.listSize;
}
2.5. toString:显示列表中的元素
function toString(){
return this.dataStore;
}
严格来说,该方法返回的是一个数组,而不是字符串,但它的目的是为了显示列表的当前状态,因此返回一个数组就足够了。
2.6. insert:向列表中插入一个元素
我们需要先知道insert()方法将元素插入到什么位置,现在我们假设插入是指插入到某个元素之后,即我们的insert()方法需要两个参数,插入的元素,和插入位置的前一个元素。
function insert(element,after){
var insertPos = this.find(after);
if(insertPos>-1){
this.dataStore.splice(insertPos+1,0,element);
this.listSize++;
return true;
}
return false;
}
可以看出,先使用find()方法找到插入的位置,找到该位置后,使用splice()方法将新元素插入到该位置之后,数组长度变量listSize加1,插入成功返回ture,否则返回false。
2.7. clear:清空列表中所有的元素
function clear(){
delete this.dataStore;
this.dataStore = [];
this.listSize = this.pos = 0;
}
2.8. contains:判断给定值是否在列表中
function contains(element){
for(var i = 0;i < this.dataStore.length;i++){
if(this.dataStore[i] == element){
return true;
}
}
return false;
}
2.9. 遍历列表
这一组方法允许用户在列表上自由移动,最后一个方法getElement()返回列表的当前元素:
function front(){
this.pos = 0;
}
function end(){
this.pos = this.listSize - 1;
}
function prev(){
if(this.pos > 0){
this.pos--;
}
}
function next(){
if(this.pos < this.listSize - 1){
this.pos++;
}
}
function currPos(){
return this.pos;
}
function moveTo(position){
this.pos = position;
}
function getElement(){
return this.dataStore[this.pos];
}
创建一个由姓名组成的列表,来展示这些方法:
var names = new List();
names.append("张三");
names.append("李四");
names.append("王二");
names.append("钱五");
names.append("赵六");
现在移动到列表的第一个元素并且显示它:
names.front();
print(names.getElement());//显示"张三"
接下来向前移动一个单位并且显示它:
names.next();
print(names.getElement());//显示"李四"
现在,先向前移动两次,然后向后移动一次,显示当前元素:
names.next();
names.next();
names.prev();
print(names.getElement());//显示"王二"
3.使用迭代器访问列表
使用迭代器,我们不需要关心数据的内部存储方式,以实现对列表的遍历。前面提到的方法find(),end(),prev(),next()和currPos()就实现了clist类的一个迭代器。
迭代器的一些优点:
- 访问列表元素时不需要关心底层的数据存储结构
- 当为列表添加一个元素时,索引的位置就不对了,此时只需要更新列表,不需要更新迭代器
- 可以用不同类型的数据存储方式实现clist类,迭代器为访问列表中的元素提供了一种同意的方式
例如:
for(names.front();names.currPos()<nameslength();names.next()){
print(names.getElement());
}
从for循环的开始,将列表的当前位置设置为第一个元素。只要currPos的值小于列表的长度,就一直循环下去,并且每一次循环都调用next()方法将当前位置向前移动一位。
同样,也可以从后向前遍历列表:
for(names.end();names.currPos()>=0;names.prev()){
print(names.getElement());
}
循环是从最后一个元素开始,当当前位置大于或等于零时,调用prev()方法后移一位。
迭代器只是用于在列表上随意移动,不能和任何为列表增加或删除的方法一起使用。
用JavaScript描述数据结构与算法——列表章结束,下一篇总结使用JavaScript对栈的操作