在数据结构中要存储多个元素,除了数组另一个就是链表,不同于数组的是,链表不需要连续的内存空间,不必在创建时就确定大小,链表大小可以无限延伸,在插入和删除数据时,效率会高很多,但是链表在访问任何一个位置的数据时都需要从头开始访问,在查找方面效率会比较低。
链表的每个元素有一个储存元素本身的节点和一个指向下一个元素的引用组成。
对单向链表进行封装:
function LinkedList() {
//内部类:节点类,一个节点要包含数据和指向下一个节点的引用
function Node(data) {
this.data = data;
this.next = null;
}
//头结点
this.head = null;
this.length = 0;
//1:在列表尾部添加一个元素
LinkedList.prototype.append = function (ele) {
// 1.创建一个新节点
let newNode = new Node(ele);
// 2.判断是否添加的是第一个节点
if (this.length === 0) { //2.1是第一个节点
this.head = newNode;
} else { //2.2不是第一个节点
//找出最后一个节点
let current = this.head;
while (current.next) {
current = current.next;
}
//2.2.1在最后一个节点后面添加一个新节点
current.next = newNode;
}
//3.链表长度加一
this.length += 1;
};
//2.向列表指定位置插入一个新的项
LinkedList.prototype.insert = function (position, data) {
//对position进行越界判断
if (position < 0 || position > this.length) {
return false;
}
let newNode = new Node(data);
if (position === 0) {
newNode.next = this.head;
this.head = newNode;
}else{
let index = 0;
let previous = null;
let current = this.head;
while(index < position){
previous = current;
current = current.next;
index ++;
}
newNode.next = current;
previous.next = newNode;
}
this.length += 1;
};
//3.获取对应位置的值
LinkedList.prototype.get = function(position){
//对position进行越界判断,当position等于length时为空
if (position < 0 || position > this.length-1) {
return false;
}
// 获取对应的数据
let current = this.head;
let index = 0;
while(index < position){
current = current.next;
index ++;
}
return current.data;
};
//4.返回元素在列表中的索引,如果没有该元素则返回-1
LinkedList.prototype.indexof = function (data) {
//定义变量
let index = 0;
let current = this.head;
while (current){
if(current.data === data){
return index;
}
current = current.next;
index += 1;
}
return -1;
};
//5.修改某个位置的元素
LinkedList.prototype.upData = function (newData,position) {
if(position < 0 || position > this.length - 1){
return false;
}
//定义变量
let index = 0;
let current = this.head;
while (index < position){
current = current.next;
index += 1;
}
current.data = newData;
// return true; //修改成功
};
//6.从列表指定位置移除一项,根据位置
LinkedList.prototype.removeAt = function (position) {
if(position < 0 || position > this.length - 1){
return false;
}
if(position === 0){
this.head = this.head.next;
}else{
let current = this.head;
let previous = null;
let index = 0;
while (index < position){
previous = current;
current = current.next;
index ++;
}
previous.next = current.next;
}
this.length -= 1;
};
//7.从列表中移除一项,根据数据
LinkedList.prototype.remove = function(data){
//先通过indexof获取下标,再将这个数删除
this.removeAt( this.indexof(data));
};
//8.判断链表是否为空
LinkedList.prototype.isEmpty = function () {
return this.length === 0;
};
//9.返回链表的长度
LinkedList.prototype.size = function () {
return this.length;
};
//10.tostring()方法
LinkedList.prototype.toString = function () {
let resultString = '';
let current = this.head;
while (current) { //判断链表中是否有元素,循环获得链表中的每一个元素
resultString += current.data + ' ';
current = current.next;
}
return resultString;
}
}