双向循环链表:
图解:
创建空链表:
class LinkList{
constructor(){
//头结点为空(头结点指向为空)
this.head=null
//尾结点为空(尾结点指向为空)
this.tail=null
//链表长度为0
this.length=0
}
}
创建节点元素:
class Dnode{
// 封装一个构造函数,用于保存元素、元素的上一个引用及元素的下一个引用
constructor(data){
// 指向上一个元素节点
this.prev=null
// 存放数据
this.data=data
// 指向下一个节点(引用)
this.next=null
}
}
对链表进行操作(在链表中添加方法):
1.向链表最后添加元素 append(ele)
append(ele) {
let newnode = new Node(ele);
if (this.length == 0) {
//空链表
this.head = newnode;
this.tail = newnode;
newnode.prev = this.tail;
newnode.next = this.head;
} else {
// 将新节点连接
newnode.prev = this.tail;
newnode.next = this.head;
// 断开原来的指向,重新指向新节点
this.tail.next = newnode;
this.head.prev = newnode;
this.tail = newnode;
}
this.length++
}
图解:
1.this.length=0
2.this.length!=0
2.向链表中的特定位置插入一个新的节点 insert(position,ele)
insert(position, ele) {
if (position < 0 || position > this.length || !Number.isInteger(position)) return
let newnode = new Node(ele);
if (position == 0) {
if (this.length == 0) {
//空链表
this.head = newnode;
this.tail = newnode;
newnode.prev = this.tail;
newnode.next = this.head;
} else {
newnode.prev = this.tail;
newnode.next = this.head;
this.head.prev = newnode
this.tail.next = newnode;
this.head = newnode;
}
this.length++
}else if(position == this.length){
this.append(ele)
}else{
let current = this.head,index = 0;
while(index< position-1){
current = current.next;
index++;
}
newnode.prev = current;
newnode.next = current.next;
current.next = newnode;
newnode.next.prev = newnode;
this.length++
}
}
3.从链表的特定位置移除一项 removeAt(position)
removeAt(position){
if (position < 0 || position > this.length-1 || !Number.isInteger(position)) return
if(position == 0){
if(this.length == 1){
this.head = null;
this.tail = null;
}else{
this.head = this.head.next;
this.tail.next = this.head;
this.head.prev = this.tail;
}
}else if(position == this.length-1){
this.tail = this.tail.prev;
this.tail.next = this.head;
this.head.prev = this.tail;
}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.length--
}
4.返回元素在链表中的索引,如果链表中没有该元素则返回-1. indexOf(ele)
indexOf(ele){
let current = this.head,index=0;
while(index < this.length){
if(current.data == ele){
return index
}else{
current = current.next;
index++
}
}
return -1
}
5.从链表中移除指定元素 remove(ele)
remove(ele){
this.removeAt(this.indexOf(ele))
}
6.如果链表中不包含任何元素,返回true,如果链表长度大于0,则返回false。 isEmpty()
isEmpty(){
if(this.length==0){
return true
}else{
return false
}
}
7.返回链表包含的元素个数。与数组的length属性类似。 size()
size(){
return this.length
}
8.由于链表项使用了node类,就需要重写继承自javaScript对象默认的toString方法,让其只输出元素的值 toString()
1.正向遍历:
toAfterString(){
let current= this.head,index=0,res ="";
while(index < this.length){
res+= "-" + current.data;
current = current.next;
index++;
}
return res.slice(1)
}
2.反向遍历:
toBeforeString(){
let current= this.tail,index=this.length-1,res ="";
while(index >= 0){
res+= "-" + current.data;
current = current.prev;
index--;
}
return res.slice(1)
}
完整的代码:
<script>
class Node {
constructor(data) {
this.prev = null;
this.data = data;
this.next = null;
}
}
class CycleDoubleLinkList {
constructor() {
this.head = null;
this.tail = null;
this.length = 0;
}
// 1.向链表最后添加元素
append(ele) {
let newnode = new Node(ele);
if (this.length == 0) {
//空链表
this.head = newnode;
this.tail = newnode;
newnode.prev = this.tail;
newnode.next = this.head;
} else {
// 将新节点连接
newnode.prev = this.tail;
newnode.next = this.head;
// 断开原来的指向,重新指向新节点
this.tail.next = newnode;
this.head.prev = newnode;
this.tail = newnode;
}
this.length++
}
// 2.向链表中的指定位置插入元素
insert(position, ele) {
if (position < 0 || position > this.length || !Number.isInteger(position)) return
let newnode = new Node(ele);
if (position == 0) {
if (this.length == 0) {
//空链表
this.head = newnode;
this.tail = newnode;
newnode.prev = this.tail;
newnode.next = this.head;
} else {
newnode.prev = this.tail;
newnode.next = this.head;
this.head.prev = newnode
this.tail.next = newnode;
this.head = newnode;
}
this.length++
}else if(position == this.length){
this.append(ele)
}else{
let current = this.head,index = 0;
while(index< position-1){
current = current.next;
index++;
}
newnode.prev = current;
newnode.next = current.next;
current.next = newnode;
newnode.next.prev = newnode;
this.length++
}
}
// 3.移除指定位置的元素
removeAt(position){
if (position < 0 || position > this.length-1 || !Number.isInteger(position)) return
if(position == 0){
if(this.length == 1){
this.head = null;
this.tail = null;
}else{
this.head = this.head.next;
this.tail.next = this.head;
this.head.prev = this.tail;
}
}else if(position == this.length-1){
this.tail = this.tail.prev;
this.tail.next = this.head;
this.head.prev = this.tail;
}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.length--
}
// 4.查找
// 4.查找指定元素
indexOf(ele){
let current = this.head,index=0;
while(index < this.length){
if(current.data == ele){
return index
}else{
current = current.next;
index++
}
}
return -1
}
// 5.移除指定元素
remove(ele){
this.removeAt(this.indexOf(ele))
}
toAfterString(){
let current= this.head,index=0,res ="";
while(index < this.length){
res+= "-" + current.data;
current = current.next;
index++;
}
return res.slice(1)
}
toBeforeString(){
let current= this.tail,index=this.length-1,res ="";
while(index >= 0){
res+= "-" + current.data;
current = current.prev;
index--;
}
return res.slice(1)
}
}
// 测试代码:
let list = new CycleDoubleLinkList();
for (let i = 0; i < 9; i++) {
list.append(i)
}
list.remove("hello")
list.remove(0)
list.remove(6)
list.remove(8)
console.log(list.toAfterString());
console.log(list.toBeforeString());
</script>