JS 算法与数据结构之列表

JS 如何创建一个简单的列表类?以下将描述如何实现该抽象数据类型(ADT)

一、 什么是列表

列表是一组有序的数据,每个列表中的数据项称为元素
在 JS 中,列表的元素可以是任意数据类型,且列表保存多少元素没有事先限定
要设计列表的抽象数据类型,我们需要列出列表的属性及方法:

1、列表的属性

属性名 作用
listSize 列表的元素个数
pos 列表的当前位置
length 返回列表中元素的个数

2、列表的方法

方法名 作用
clear 清空列表中的所有元素
toString 返回列表的字符串形式
getElement 返回当前位置的元素
insert 在现有元素后插入新元素
append 在列表的末尾添加新元素
remove 从列表中删除元素
front 将列表的当前位置移动到第一个元素
end 将列表的当前位置移动到最后一个元素
prev 将当前位置后移一位
next 将当前位置前移一位
hasNext 判断后一位
hasPrev 判断前一位
currPos 返回列表的当前位置
moveTo 将当前位置移动到指定位置

二、列表的实现

我们先从定义构造函数开始实现

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
  this.hasPrev
  this.length = length
  this.currPos = currPos
  this.moveTo = moveTo
  this.getElement = getElement
  this.contains = contains
}

1、append 方法

给列表添加元素

function append(element) {
  this.dataStore[this.listSize++] = element
}

当新元素就位后,变量 listSize 加 1

2、find 方法

在列表中查找某一元素

function find(element) {
  for (var i = 0; i < this.dataStore.length; ++i) {
    if (this.dataStore[i] == element) {
      return i
    }
  }
  return -1
}

3、remove 方法

从列表中删除元素

function remove(element) {
  var foundAt = this.find(element)
  if (foundAt > -1) {
    this.dataStore.splice(foundAt, 1)
    --this.listSize
    return true
  }
  return false
}

remove() 方法中使用 find() 方法返回的位置对数组 dataStore 进行截取,数组改变后,将变量 listSize 的值减 1
如果元素删除成功,返回 true,否则返回 false

4、length 方法

返回列表中元素个数

function length() {
  return this.listSize
}

5、toString 方法

显示列表中的元素

function toString() {
  return this.dataStore
}

下面对以上形成的类进行一个简短的测试

var names = new List()

names.append('a')
names.append('b')
names.append('c')
console.log(names.toString()) // ["a", "b", "c"]

names.remove('b')
console.log(names.toString()) // ["a", "c"]

6、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
}

insert() 方法中使用 find() 方法,寻找传入的 after 参数在列表中的位置,然后使用 splice() 方法将新元素插入该位置,再将变量 listSize 加 1 并返回 true

7、clear 方法

清空列表中所有的元素

function clear() {
  delete this.dataStore
  this.dataStore.length = 0
  this.listSize = this.pos = 0
}

clear() 方法使用 delete 操作符删除数组 dataStore,接着在下一行创建一个空数组,最后一行将 listSizepos 的值设为 1,表明这是一个新的空列表

8、contains 方法

判断给定值是否在列表中

function contains(element) {
  for (var i = 0; i < this.dataStore.length; i++) {
    if (this.dataStore[i] == element) {
      return true
    }
  }
  return false
}

9、遍历列表方法

允许用户在列表上自由移动的方法集合

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
}

下面用一个例子来展示这些方法的使用:

1、首先创建一个列表:

var names = new List()

names.append('a')
names.append('b')
names.append('c')
names.append('d')
names.append('e')

2、现在移动到列表中的第一个元素并显示该元素:

names.front()
console.log(names.getElement()) // a

3、接下来往后移动一个单位并显示

names.next()
console.log(names.getElement()) // b

4、prev() 的使用

names.next()
names.next()
names.prev()
console.log(names.getElement()) // c
posted @ 2021-02-25 21:12  Leophen  阅读(376)  评论(0编辑  收藏  举报