1.单向链表
什么是链表呢?
- - 链表类似于火车: 有一个火车头, 火车头会连接一个节点, 节点上有乘客, 并且这个节点会连接下一个节点, 以此类推.
- - 链表的火车结构:
- 链表的数据结构:
创建链表类
// 封装一个LNode类, 用于保存每个节点信息
class Lnode {
constructor(data) {
this.data = data;
this.next = null
}
}
//封装链表类
class LinkList {
constructor() {
this.head = null;
this.len = 0;
}
//1.向列表尾部添加一个新的项
append(ele) {
//创建新节点
let newnode = new Lnode(ele);
if (this.head == null) {
this.head = newnode
} else {
let current = this.head;
while (current.next) {
current = current.next
}
current.next = newnode;
}
this.len++
}
//2.向列表的特定位置插入一个新的项
insert(poistion, ele) {
if (poistion < 0 || poistion > this.len || !Number.isInteger(poistion)) return false;
let newnode = new Lnode(ele);
let index = 0;
let current = this.head;
if (poistion == 0) {
if (this.head == null) {
this.head = newnode;
} else {
newnode.next = this.head;
this.head = newnode;
}
this.len++
} else if (poistion == this.len) {
this.append(ele)
} else {
while (index < poistion - 1) {
current = current.next;
index++
}
newnode.next = current.next;
current.next = newnode;
this.len++
}
return true
}
//3.移除指定位置的元素
removeAt(poistion) {
if (poistion < 0 || poistion > this.len - 1 || !Number.isInteger(poistion)) return false;
let index = 0;
let current = this.head;
if (poistion == 0) {
this.head = this.head.next
} else {
while (index < poistion - 1) {
current = current.next;
index++
}
current.next = current.next.next;
}
this.len--
return current.data
}
//4.查找元素的位置
indexOf(ele){
let index = 0;
let current = this.head;
while (current) {
if(current.data==ele){
return index
}
index++;
current=current.next;
}
return -1
}
//5.remove(ele) 移除指定的元素
remove(ele){
let index = this.indexOf(ele);
this.removeAt(index)
}
// 6.toString()
toString(){
let index = 0;
let current = this.head;
let res='';
while (current) {
res+=','+current.data;
current=current.next;
index++
}
return res.slice(1)
}
// 7.判断栈中的元素是否为空
isEmpty() {
return this.len == 0
}
// 8.获取栈中元素的个数
size() {
return this.len
}
// 9.获取第一个节点
getFirst() {
return this.head.data
}
}
测试
测试append方法
// 1.创建链表
var list = new LinkedList()
// 2.追加元素
list.append(15)
list.append(10)
list.append(20)
// 3.打印链表的结果
alert(list)//15 10 20
测试insert的方式插入数据:
// 4.测试insert方法
list.insert(0, 100)
list.insert(4, 200)
list.insert(2, 300)
alert(list) // 100,15,300,10,20,200
测试removeAt方法
// 5.测试removeAt方法
list.removeAt(0)
list.removeAt(1)
list.removeAt(3)
alert(list) // 15, 10, 20
indexOf方法测试
// 6.测试indexOf方法
alert(list.indexOf(15)) // 0
alert(list.indexOf(10)) // 1
alert(list.indexOf(20)) // 2
alert(list.indexOf(100)) // -1
测试remove方法
// 7.测试remove方法
list.remove(15)
alert(list) // 10,20
2.双向链表
- 双向连接的图解:
创建链表类
class CNode {
constructor(data) {
this.prev = null;
this.data = data;
this.next = null;
}
}
class DoubleLinkList {
constructor() {
this.head = null;
this.tail = null;
this.len = 0;
}
// 1.向列表尾部添加一个新的项
append(ele) {
let newnode = new CNode(ele);
if (this.len == 0) {
//空链表
this.head = newnode;
this.tail = newnode;
} else {
newnode.prev = this.tail;
this.tail.next = newnode;
this.tail = newnode;
}
this.len++
}
// 2.insert方法:向指定位置插入元素
insert(postion, ele) {
if (postion < 0 || postion > this.len || !Number.isInteger(postion)) return false
let newnode = new CNode(ele);
if (postion == 0) {
if (this.len == 0) {
this.head = newnode;
this.tail = newnode;
} else {
newnode.next = this.head;
this.head.prev = newnode;
this.head = newnode;
}
this.len++
}else if(postion == this.len){
this.append(ele)
}else{
let current = this.head,index=0;
while(index< postion-1){
current =current.next;
index++
}
// 新节点练上去
newnode.prev = current;
newnode.next = current.next;
current.next = newnode;
newnode.next.prev = newnode;
this.len++
}
}
// 3.removeAt() 移除指定位置的元素
removeAt(position){
if (position < 0 || position > this.len-1 || !Number.isInteger(position)) return false
if(position == 0){
this.head = this.head.next;
this.head.prev = null
}else if(position == this.len-1){
this.tail = this.tail.prev;
this.tail.next = null
}else{
let current = this.head,index= 0;
while(index < position-1){
current = current.next;
index++;
}
current.next = current.next.next;
current.next.prev = current
}
this.len--
}
// 4.indexOf(ele) 查找元素的位置
indexOf(ele) {
let current = this.head,
index = 0;
while (index < this.len) {
if (current.data == ele) {
return index
} else {
current = current.next;
index++
}
}
return -1
}
// 5.remove(ele) 移除指定的元素
remove(ele) {
let in1 = this.indexOf(ele);
this.removeAt(in1)
}
// 正向遍历
forwardString(){
let current = this.head,index = 0,res = "";
while(current){
res+= '-' + current.data;
current = current.next;
index++
}
return res.slice(1)
}
// 反向遍历
reverseString(){
let current = this.tail,index = this.len-1,res = "";
while(current){
res+= '-' + current.data;
current = current.prev;
index--
}
return res.slice(1)
}
// 判断栈中的元素是否为空
isEmpty() {
return this.len == 0
}
// 获取栈中元素的个数
size() {
return this.len
}
// 获取第一个元素
getHead() {
return this.head.data
}
// 获取最后一个元素
getTail() {
return this.tail.data
}
}
双向链表的测试请读者自己尝试,和单向链表类似。