【DS】C3--列表

201 阅读4分钟

C3--列表

1.列表的抽象数据类型定义

列表的抽象数据类型并未指明列表的存储结构,本章中的实现中,使用一个数组dataStore来存储元素。

  • 定义:列表是一组有序的数据。每个列表中的数据项称为元素。(在JavaScript中,列表中的元素可以是任意数据类型)
  • 属性:
    • 不包含任何元素的列表称为空列表。列表中包含元素的个数称为列表的length.
    • 在内部实现上,用一个变量listSize保存列表中元素的个数。
    • 列表拥有描述元素位置的属性。
      • 列表有前有后(front/end)。
      • pos列表的当前位置
  • 操作(方法):
    • append()在列表末尾添加新元素
    • insert()在一个给定元素后或者列表的起始位置插入新元素
    • remove()方法从列表中删除元素
    • clear()方法清空列表中的所有元素
    • toString()方法显示列表中所有元素
    • getElement()方法返回当前位置的元素
    • currPos()返回列表的当前位置。
    • next()方法可以从当前元素移动到下一个元素。(将当前位置前移一位)
    • prev()方法可以移动到当前元素的前一个元素。(将当前位置后移一位)
    • moveTo(n)方法直接移动到指定位置,这里的n表示要移动到第n个位置。
    • front()将列表的当前位置设移动到第一个元素
    • end()将列表的当前位置移动到最后一个元素
2.实现列表类

定义构造函数

function List(){
	this.listSize = 0;
	this.pos = 0;
	this.dataStore = [];//初始化一个空数组来保存列表元素
	this.clear = clear;
	this.find = find;
	this.toString = toString;
	this.insert = indsert;
	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;
}
//测试代码
var names = new List();
names.append("xyz");
print(names.toString());
  1. append:给列表添加元素
function append(element){
	this.dataStore[this.listSize++] = element;
}

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

  1. remove:从列表中删除元素

    使用查找元素的find()方法返回的值,用splice()方法对数组进行截取,并将数组长度减一

function remove(elemnet){
	var foundAt = this.find(elemnet);
	if(foundAt > -1){
		this.dataStore.splice(foundAt,1);
		--this,listSize;
		return true;
	}
	return false;
}
  1. find:在列表中查找某一元素
function find(element){
	for (var i =0;i<this.dataStore.length;++i){
		if(this.dataStore[i] == element){
			return i;
		}
	}
	return -1;
}
  1. length: 列表中有多少个元素

    function length(){
    	return this.listSize;
    }
    
  2. toString(): 显示列表中的元素(显示列表的当前状态)

    //该方法返回的是一个数组,而不是一个字符串
    function toString (){
    	return this.dataStore;
    }
    
  3. 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;
    }
    
  4. clear:清空列表中的所有的元素

    function clear(){
    	delete this.dataStore;
    	this.dataStore = [];
    	this.listSize = this.pos = 0;
    }
    
  5. contains:判断给定值是否在列表中

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

    ​ 允许用户在列表上自由移动

    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];
    }
    
    3.使用迭代器访问列表
    1. 优点(相较使用数组索引)
    • 访问列表元素时,不必关心底层的数据存储结构。

    • 当为列表添加一个元素时,索引的值就不对了,此时只用更新列表,而不用更新迭代器。

    • 可以用不同类型的数据存储方式实现cList类,迭代器为访问列表里的元素提供了一种统一的方式。

      //使用迭代器遍历列表
      for (names.front;names.currPos()<name.length();names.next()){
      	print(names.getElement());
      }
      //从后向前遍历列表
      for(names.end();names.currPos()>=0;names.prev()){
      	print(names.getElement());
      }
      

      迭代器只是用来在列表上随意移动,而不应该和任何为列表增加或删除元素的方法一起使用。

      4.一个基于列表的应用
      //读取films.txt文件的内容,将读进来的内容按照换行符分成了不同的行,然后保存到数组movies中。
      var movies = read(films.txt).split("\n");
      
      //封装:分割数组并删除每个数组元素末尾的空格。
      function createArr(file){
      	var arr = read(file).split("\n");
      	for (var i = 0 ;i < arr.length;++i){
      		arr[i] = arr[i].tirm();
      	}
      	return arr;
      }
      
      //将数组movies中的元素保存到一个列表中
      var movieList = new List();
      for (var i= 0;i<movies.length;++i){
      	movieList.append(movies[i]);
      }
      
      //显示影碟店里的现有的影碟清单
      function displayList(list){
      	for (list.front();list.currPos() <list.length;list.next()){
      		print(list.getElement());
      	}
      }
      
      //displayList()可以作用于原生的数据类型,比如由字符串组成的列表,但是他用不了自定义类型,比如对象。instanceof操作符判断该元素是否是Customer对象,如果是就使用,name和movie做索引。使得用户检出相应条目的值,否则返回该元素。
      function displayList(list){
      	for (list.front();list.currPos() <list.length;list.next()){
      		if(list.getElement() instanceof Customer){
      			print (list.getElement()['name']+","+list.getElement()['movie']);
      		}else{
      			print(list.getElement());
      		}
      	}
      	
      }
      
      //客户检出电影系统
      var customs = new List();
      function Customer(name,movie){
      	this.name = name;
      	this.movie = movie;
      }
      
      //允许客户检出电影,包含客户姓名和客户想要检出的电影
      function checkOut(name,movie,filmList,customerList){
      	if (movieList.contains(movie)){
      		var c = new Customer(name,movie);
      		customerList.append(c);
      		filmList.remove(movie);
      	}else{
      		print(movie +"is not available.")
      	}
      }