JavaScript 实现列表(List)数据结构详解

作者:青柠

时间:2026-10-23

浏览:660

本文详细讲解如何在 JavaScript 中实现列表(List)数据结构。通过封装数组,实现了 append、find、remove、insert、clear 等核心方法,并引入了 pos 属性支持 front、next、prev 等位置遍历操作。文章提供了完整的代码示例,帮助前端开发者深入理解线性表的基本原理与具体实现细节。

文章目录

本文通过具体实例,深入解析 JavaScript 中列表(List)算法与数据结构的实现方式,旨在为读者提供实用的参考代码与技术解析。

前言

在前端开发领域,开发者往往较少直接处理底层算法,更多精力集中在交互逻辑上。因此,部分前端工程师认为无需掌握数据结构与算法也能胜任工作。然而,算法的概念十分宽泛,任何代码都是对问题的解决方案,是对解决问题策略的系统化描述。随着互联网产品的日益复杂以及基础库的迭代升级,仅靠简单的选择器、链接和事件已无法满足需求,坚实的数据结构与算法基础成为驾驭复杂产品的前提。因此,前端工程师重视算法与数据结构的学习,对职业长远发展具有显著助益。算法学习是一个需要不断摸索、实践与总结的过程,本文旨在通过 JavaScript 实现常见算法与数据结构,起到抛砖引玉的作用。


列表(List)

列表是计算机科学中一种基础且常见的数据结构。在现实生活中,购物清单、待办事项等均属于列表的范畴。从定义上看,列表是由一组有序数据构成的集合,其中的每个数据项被称为元素。在 JavaScript 中,列表的元素类型可以是任意数据类型,且理论上没有数量限制(实际受限于程序运行内存)。列表通常包含若干属性与方法,例如获取元素总数、定位当前元素位置、向末尾追加元素、删除特定元素以及清空列表等。接下来,我们将抽象出列表的数据类型定义,并使用 JavaScript 数组来具体实现这一数据结构。

前言 列表的数据类型定义

列表类


/*定义List类*/
 function List () {
  this.listSize = 0;  //初始化元素个数为0
  this.pos = 0;    //初始化位置为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.contains = contains; //判断给定值是否在列表中
}

随后,我们将逐步实现列表所具备的各项功能方法。

首先,我们需要支持元素的添加操作,因此从编写 append 方法开始。

append:向列表中添加一个元素


//该方法给列表的最后一个位置添加一个新的元素,待插入成功后,更新列表中的元素个数

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

完成元素添加功能后,我们继续实现查找功能,即 find 方法。

find:查找列表中的某一个元素


//该方法通过循环查找给定元素是否在列表中,如果存在返回元素的位置,否则返回 -1

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

既然支持插入,自然也需要支持删除操作。我们通过 remove 方法来移除列表中的指定元素。

remove:删除列表中的某一元素


//该方法通过使用find()方法返回元素的位置对 dataStore 数组进行截取,如果删除成功,返回 true , 并将 listSize 的值减1,更新列表长度,否则返回 false

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

为了获取列表中元素的总数量,我们需要构建 length 方法。

length:返回列表中总的元素个数


//该方法直接将 listSize 返回即可

function length(){
  return this.listSize;
}

若需直观展示列表中的元素内容,可以使用 toString 方法。

toString:显示列表的元素


//该方法直接返回了列表数组,显示出当前列表内容

function toString(){
  return this.dataStore;
}

目前,列表已具备基础功能,我们可以进行初步测试。


//构造列表对象
var fruits = new List();
//添加三个元素
fruits.append('Apple');
fruits.append('Grape');
fruits.append('Banana');

//打印列表
console.log( fruits.toString() )   // ["Apple", "Grape", "Banana"]
//查看列表长度
console.log( fruits.length() )    // 3
//查找 Banana 的位置
console.log( fruits.find('Banana') ) // 2
//删除 Grape 
fruits.remove('Grape');
console.log( fruits.toString() )   // ["Apple", "Banana"]

假设我们删除了 Grape 元素,若希望将其重新插入到原有位置,则需要使用 insert 方法。

insert:向列表某个位置添加一个元素


//该方法需要传入两个参数,第一个参数表示待插入的元素,第二个参数表示待插入元素的前一个元素,用于确定插入元素的位置,并调用 splice 方法更改列表数组,插入成功后更新 listSize 并返回 true , 否则返回 false;
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;
}

现在,我们将 Grape 元素重新插入到其原始位置;


fruits.insert( 'Grape' , 'Apple' );
console.log( fruits.toString() )    // ["Apple", "Grape", "Banana"]

至此,Grape 已成功插入到指定位置。

如果列表中的所有元素已被处理完毕,我们需要清空列表,此时 clear 方法便派上用场。

clear:清空列表


//该方法使用 delete 操作符删除 dataStore 数组 , 接着创建新的数组,并将其 listSize 和 pos 初始化设为 1 。

function clear(){
  delete this.dataStore;
  this.dataStore = [];
  this.listSize = this.pos = 0;
}

我们可以尝试执行该操作。


fruits.clear();
console.log( fruits.toString() );   // []

操作成功!

前文提到列表中存在 pos 属性,用于表示当前列表的遍历位置。接下来,我们将基于该属性扩展功能,使用户能够自由控制列表的遍历位置。

front:将列表的位置移到第一个位置上


//该方法只要将 pos 置为 0 即可

function front(){
  this.pos = 0 ;
}

end:将列表的位置移到最后一个位置上


//同上,该方法只要将 pos 置为列表长度减 1 即可,因为数组下标从 0 开始嘛

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

prev:将当前位置前移一位


//只要将 pos 的位置减 1 即可,但要主要不能越界

function prev(){
  if( this.pos > 0 ){
    this.pos --;
  }else{
    console.log('您当前已在首位');
  }
}

next:将当前位置后移一位


//同理,只要将 pos 的位置加 1 即可,但要主要不能越界

function next(){
  if( this.pos < this.listSize - 1 ){
    ++this.pos;
  }else{
    console.log('您当前已在末尾');
  }
}

moveTo:将当前位置移动到指定位置


//直接改变 pos 的值即可,注意输入的合法性

function moveTo( position ){
  if( position < 0 || position > (this.listSize - 1) ){
    console.log('请输入正确的位置');
  }else{
    this.pos = position;
  }
}

既然可以自由移动列表位置,我们还需要知道当前位置的具体索引及该位置的元素值。因此,我们需要实现 currPos 和 getElement 两个方法,分别用于返回当前遍历位置索引和该位置的元素。

currPos:返回列表的当前位置


//只需将 pos 直接返回即可

function currPos(){
  return this.pos;
}

getElement:返回当前位置的元素


//直接取对应的元素就好

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

接下来进行测试。首先将列表恢复至清空前的状态,并额外添加若干元素。


//再添加几个
fruits.append('Pear');
fruits.append('Orange');
fruits.append('Strawberry');
console.log( fruits.toString() );  // ["Apple", "Grape", "Banana", "Pear", "Orange", "Strawberry"]

//我们先看当前的位置和元素
console.log( fruits.currPos() );   // 0
console.log( fruits.getElement() ); // Apple

//我们尝试改变一下
fruits.moveTo( 2 );
fruits.next();
console.log( fruits.currPos() );   // 3
console.log( fruits.getElement() ); // Pear
fruits.end();
fruits.prev();
console.log( fruits.currPos() );   // 4
console.log( fruits.getElement() ); // Orange

至此,列表的核心功能已基本完善。最后,我们需要判断指定元素是否存在于列表中,这通过 contains 方法实现。

contains:判断给定值是否在列表中


//我们直接利用利用 indexOf() 或者采用跟为高级的 ES6 中的 includes 方法来判断

//ES5
function contains( element ){
  if( this.dataStore.indexOf( element ) > -1 ) return true;
  else return false;
}

//ES6

function contains( element ){
  return this.dataStore.includes( element );
}

( ps:对 ES6 不太熟悉的同学,也可以参考本站https://www.jb51.net/article/138409.htm )

编写完成后,进行功能测试。


console.log(fruits.contains('Banana'));     // true
console.log(fruits.contains('Watermelon'));   // false

功能实现完毕!我们利用 JavaScript 成功构建了一个列表数据结构。后续可根据实际需求进行扩展,建议读者发散思维,多动手实践,共同进步。

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.jb51.net/code/HtmlJsRun测试上述代码运行效果。

更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《JavaScript数学运算用法总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript数组操作技巧总结》、《JavaScript排序算法总结》、《JavaScript遍历算法与技巧总结》、《JavaScript查找算法技巧总结》及《JavaScript错误与调试技巧总结》

希望本文所述对大家JavaScript程序设计有所帮助。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章