一、要想自己封装链表得先知道链表的特点:
链表的每个元素有一个存储元素本身的节点和一个指向下一个节点的引用(有些语言是指针);
链表一般有head、length等属性,一个指向头节点,一个表示链表节点的个数;
链表无法通过下标直接访问元素,需要从head指向的头节点开始一个一个的访问,直到找到对应的元素;
二、这里我实现了:
增:
- append,向链尾添加节点
-
insert,向特定位置插入新节点
删:
- remove_identical,链表去重
- removeAt,指定位置删除节点
- remove,从列表中移除指定节点
改:
- update,修改某个位置的节点
查:
- get,获取对应位置的元素
- indexOf,返回队应元素的索引,没有则返回-1,有多个以数组形式返回
其他:
- isEmpty,是否为空
- size,包含元素个数
- toString,重写tosTring()方法
三、难的点就说一下链表去重吧:
先把每个节点的数据放到数组里面
然后我们可以把链表去重转换为数组去重,这个简单吧,遍历啊,set啊都是可以实现的
dataArr = Array.from(new Set(dataArr));
然后更新head和length,再重新构造链表即可
四、源码
function LinKedList() {
// 内部的类:节点类
function Node(data, next = null) {
this.data = data;
this.next = next;
}
// 属性
this.head = null;
this.length = 0;
// 方法1:append
LinKedList.prototype.append = function (data) {
//1.创建
let newNode = new Node(data);
// 2.判断是否是添加的第一个节点
if (!this.length) {
this.head = newNode;
} else {
// 查找都是从head开始
let current = this.head;
//3.末尾的node
while (current.next) {
current = current.next;
}
// 4.添加:最后节点的next指向最新的节点
current.next = newNode;
}
//5.length++
this.length++;
};
// 方法2:tostring
LinKedList.prototype.toString = function () {
let Values = [];
let current = this.head;
//将data放入values
while (current) {
Values.push(current.data);
current = current.next;
}
// 返回数据,用string也行,这里用数组包裹
return Values;
};
// 方法3:insert
LinKedList.prototype.insert = function (position, element) {
// 在插入之前做边界判断
if (position < 0 && position > this.length) return false;
// 根据data创建node
let newNode = new Node(element);
// 判断是否插入的是第一个
if (!position) {
newNode.next = this.head.next;
this.head = newNode;
} else {
//包含了position==this.length这种情况
let index = 0;
let current = this.head;
let previous = null;
// 拿到当前的和以前的
while (index++ < position) {
previous = current;
current = current.next;
}
// 连接节点
newNode.next = current;
previous.next = newNode;
}
// length++
this.length++;
return true;
};
// 方法4:get
LinKedList.prototype.get = function (position) {
// 是位置都来一个边界判断
if (position < 0 && position >= this.length) return null;
let index = 0;
let current = this.head;
while (index++ < position) {
current = current.next;
}
return current.data;
};
// 方法5:indexOf
LinKedList.prototype.indexOf = function (element) {
let index = 0;
let current = this.head;
let indexArr = [];
while (current) {
let data = current.data;
if (data == element) {
indexArr.push(index);
}
current = current.next;
index++;
}
if (!indexArr.length) return -1;
return indexArr;
};
// 方法6:update
LinKedList.prototype.update = function (position, element) {
if (position < 0 && position >= this.length) return false;
let index = 0;
let current = this.head;
while (index++ < position) {
current = current.next;
}
current.data = element;
return true;
};
// 方法7:removeAt
LinKedList.prototype.removeAt = function (position) {
// 边界
if (position < 0 && position >= this.length) return false;
let index = 0;
let current = this.head;
let previous = null;
// 0?
if (!position) {
this.head = current.next;
current.next = null;
return true;
}
while (index++ < position) {
previous = current;
current = current.next;
}
previous.next = current.next;
current.next = null;
this.length--;
return true;
};
// 方法8:remove_identical
LinKedList.prototype.remove_identical = function () {
let current = this.head;
let dataArr = [];
while (current) {
let data = current.data;
dataArr.push(data);
current = current.next;
}
current = this.head;
// 将链表去重转换为数组去重
dataArr = Array.from(new Set(dataArr));
// 重新构造链表
this.head = null;
this.length = 0;
for (let i = 0; i < dataArr.length; i++) {
this.append(dataArr[i]);
}
return true;
};
// 方法9:remove
LinKedList.prototype.remove = function (element) {
let current = this.head;
let previous = null;
// 0?
if (element == current.data) {
this.head = current.next;
current.next = null;
this.index--;
return true;
}
while (current) {
if (element == current.data) {
previous.next = current.next;
current.next = null;
this.index--;
return true;
}
previous = current;
current = current.next;
}
// 没有该元素,返回false
return false;
};
// 方法10:isEmpty()
LinKedList.prototype.isEmpty = function () {
if (!this.length) return true;
return false;
};
// 方法11:size
LinKedList.prototype.size = function () {
return this.length;
};
}