什么是循环链表
循环链表本质是一种特殊的单链表。循环链表和单链表之间唯一的区别在于,最后一个元素指向下一个元素的指针(tail.next)不是引用 undefined,而是指向第一个元素(head)
单链表是什么,如何封装
详见:
https://blog.csdn.net/weixin_60629460/article/details/135864084
循环链表的封装
方法与单链表类似
import Node from "./Node.mjs";
class CircularLinkedList {
//记录链表的长度
#length = 0
//指向链表头的指针
#head = null
//链尾添加一个结点
push(data) {
//创建一个结点
const node = new Node(data)
if (this.#head === null/*链表为空时*/) {
//把node作为链头
this.#head = node
} else/*链表不为空*/ {
//先找到最后一个结点
let last = this.getNodeAt(this.size() - 1)
//插入node
last.next = node
}
//node指会head形成环状
node.next = this.#head
//链表长度增加
this.#length++
}
//找到指定位置的结点
getNodeAt(index) {
if (index >= 0 && index < this.#length) {
let node = this.#head
for (let i = 0; i < index; i++) {
node = node.next
}
return node
}
return
}
size(){
return this.#length
}
//在指定位置添加指定数据
insert(data,index){
//判断index是否存在
if(index >= 0 && index <= this.#length){
//创建新的node
const node = new Node(data)
let current = this.#head
if(index === 0/*在链表头插入数据*/){
if(this.#head === null/*链表为空时*/){
//node结点作为新的链表头
this.#head = node
//闭环
node.next = this.#head
}else/*链表不为空时*/{
//用临时变量开辟一个空间用于插入node,暂时指向head
let temp = this.#head
//把node添加在head前
node.next = temp
//先找到最后一个结点
let last = this.getNodeAt(this.size() - 1)
//再node作为新的链表头
this.#head = node
//最后一个结点指向链头
last.next = this.#head
}
}else/*链表中插入*/{
//先找到需要插入位置的上一结点
const previous = this.getNodeAt(index - 1)
//插入node(将node与插入位置后面的结点连接上)
node.next = previous.next
//将插入位置的前一个结点连接上node
previous.next = node
}
this.#length++
return true
}
return false
}
removeAt(index){
//先判断index是否存在
if(index >= 0 && index < this.#length){
//用临时变量保护将被删除的结点(暂时指向head)
let current = this.#head
if(index === 0/*在链表头删除*/){
if(this.#length === 1/*链表只有一个结点*/){
//head赋为null
this.#head = null
}else/*链表有多个结点*/{
//找出最后一个结点
let last = this.getNodeAt(this.size() - 1)
//空出原来的头结点
this.#head = this.#head.next
//闭环
last.next = this.#head
}
}else/*链表中插入*/{
//找到上一结点
const previous = this.getNodeAt(index - 1)
//保护要被删除的结点
current = previous.next
//将链表重新连接上
previous.next = current.next
}
this.#length--
return current.data
}
return
}
clear(){
this.#head = null
this.#length = 0
}
indexOf(data){
let current = this.#head
for(let i = 0; i < this.#length; i++){
if(JSON.stringify(data) === JSON.stringify(current.data)){
return i
}
current = current.next
}
return -1
}
remove(data){
const index = this.indexOf(data)
return this.removeAt(index)
}
getHead(){
return this.#head
}
toString(){
let string = ''
let current = this.#head
while(current){
string += current.data + (current.data?',':'')
current = current.next
}
return string
}
isEmpty(){
return this.size() === 0
}
}
export default CircularLinkedList