JavaScript算法学废宝典--前置技能一--列表

列表的完整抽象数据类型定义

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.hasNext = hasNext; //判断后一位
  this.hasPrev = hasPrev; //判断前一位
  this.length = length; //返回列表中元素的个数
  this.currPos = currPos; //返回列表的当前位置
  this.moveTo = moveTo; //将当前位置移动到指定位置
  this.getElement = getElement; //返回当前位置的元素
  this.contains = contains; //判断给定值是否在列表中
}

下面实现几个对应的方法

//给列表添加元素
function append(element) {
  this.dataStore[this.listSize++] = element;
}
//在列表中查找某一元素
function find(element) {
  for (var i = 0; i < this.dataStore.length; i++) {
    if (this.dataStore[i] == element) {
      return i;
    }
  }
  return -1;
}
//从列表中删除元素
function remove(element) {
  var foundAt = this.find(element);
  if (foundAt > -1) {
    this.dataStore.splice(foundAt, 1);
    --this.listSize;
    return true;
  }
  return false;
}
//列表中有多少个元素
function length() {
  return this.listSize;
}
//显示列表中的元素
function toString() {
  return this.dataStore;
}
//清空列表中所有元素
function clear() {
  delete this.dataStore;
  this.dataStore.length = 0;
  this.listSize = this.pos = 0;
}
//向列表中插入一个元素
function insert(element, after) {
  var inserPos = this.find(after);
  if (inserPos > -1) {
    this.dataStore.splice(inserPos + 1, 0, element);
    ++this.listSize;
    return true;
  }
  return false;
}
//判断给定值是否在列表中
function contains(elemment) {
  for (let i = 0; i < dataStore.length; i++) {
    if (this.dataStore[i] == elemment) {
      return true;
    }
  }
  return false;
}
//遍历列表
function front() {
  this.pos = 0;
}

function end() {
  this.pos = this.listSize - 1;
}

function prev() {
  --this.pos;
}

function next() {
  if (this.pos < this.listSize) {
    ++this.pos;
  }
}

function currPos() {
  return this.pos;
}

function moveTo(position) {
  this.pos = position;
}

function getElement() {
  return this.dataStore[this.pos];
}

function hasNext(){
  return this.pos<this.listSize;
}
function hasPrev(){
  return this.pos >= 0;
}

试用一下这些方法:

var names = new List();
names.append('111');
names.append('222');
names.append('333');
console.log(names.toString());//['111', '222', '333']
names.remove("111");
console.log(names.toString());//['222', '333']
names.front();
console.log(names.getElement());//222
names.next();
console.log(names.getElement());//333
names.append('555');
names.append('666');
names.append('777');
names.next();
names.next();
names.prev();
console.log(names.getElement());

使用迭代器访问列表

和数组索引的方式相比,使用迭代器的优点:

  1. 访问列表元素时不必关心底层的数据存储结构
  2. 当为列表添加一个元素时,索引的值就不对了,此时只用更新列表,而不用更新迭代器。
  3. 可以用不同类型的数据存储方式实现clist类,迭代器为列表里的元素提供一种统一的方式。

使用迭代器遍历列表

for(names.front();names.hasNext();names.next()){
  console.log(names.getElement())
}

从后向前 遍历列表

for(names.end();names.hasPrev();names.prev()){
   console.log(names.getElement())
 }

写一个基于列表的应用

假设有一个文件films.txt,这里用movies表示文件内容:

   var movies = 
    `(1)电影名称一
    (2)电影名称二
    (3)电影名称三
    (4)电影名称四
    (5)电影名称五
    (6)电影名称六
    (7)电影名称七
    (8)电影名称八
    (9)电影名称九
    (10)电影名称十`;

从文件中读入数据生成数组

function creatArr(file){
  var arr = file.split("\n");
  for(var i = 0;i < arr.length;++i){
    arr[i] = arr[i].trim();
  }
  return arr;
}

将movies中的元素保存到一个列表中

var movieList = new List();
for(var i = 0;i < getMovies.length;++i){
  movieList.append(getMovies[i]);
}

显示列表清单
这里特意写成了可以用自定义类型的,比如我们将在下面定义Customer对象。可以区分数据类型

function displayList(list){
  for(list.front();list.currPos() < list.length();list.next()){
    if(list.getElement() instanceof Customer){
      console.log(list.getElement()["name"]+","+list.getElement()["movie"])
    }else{
      console.log(list.getElement());
    }
  }
}

创建一个新列表customers,用来保存在系统中检出电影的客户。

var customers = new List();

该列表包含Customer对象,该对象由用户的姓名和用户检出的电影组成。

function Customer(name,movie){
  this.name = name;
  this.movie = movie;
}

接下来创建一个允许客户检出电影的函数,该函数有两个参数:客户姓名和客户想要检出的电影。
如果该电影目前可以租赁,该方法会从影碟店的影碟清单里删除该元素,同时加入客户列表customers

function checkOut(name,movie,movieList,customerList){
  if(movieList.contains(movie)){
    var c = new Customer(name,movie);
    customerList.append(c);
    movieList.remove(movie);
  }else{
    console.log(movie + "is not available");
  }
}

接下来做一个简单的测试:

var getMovies = creatArr(movies);
var customers = new List();
//将movies中的元素保存到一个列表中
var movieList = new List();
for(var i = 0;i < getMovies.length;++i){
  movieList.append(getMovies[i]);
}
console.log("电影清单:");
displayList(movieList);
checkOut("张三","(1)电影名称一",movieList,customers);
console.log("租借客户清单:");
displayList(customers);

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值