单向循环链表:
图解:
创建空链表:
class LinkList{
constructor(){
this.head=null
this.length=0
}
创建节点元素:
class Cnode{
constructor(data){
this.data=data
this.next=null
}
}
对链表进行操作(在链表中添加方法):
1.向链表最后添加元素 append(ele)
append(ele){
let newnode=new Cnode(ele)
if(this.head==null){
// 空链表
this.head=newnode
newnode.next=this.head
}else{
// 非空链表
// 需要找到最后一个节点
// 最后一个节点.next指向头结点
let current=this.head
while(current.next!=this.head){
// 继续向后查找
current=current.next
}
// 找到了,current表示最后一个节点
current.next=newnode
newnode.next=this.head
}
}
图解:
1.this.length=0
2.this.length!=0
2.向链表中的特定位置插入一个新的节点 insert(position,ele)
insert(position,ele){
// 位置是否合法
// Number.isInteger():用来判断给定的参数是否为整数
if(position<0||position>this.length||!Number.isInteger(position)){
return false
}
// 创建一个新节点
let newnode=new Conde(ele)
let current=this.head
let index=0
// 2.1在头部位置插入
if(position==0){
if(this.length==0){
// 如果头部指向空,那么就让头部指向新的节点
this.head=newnode
newnode.next=this.head
}else{
while(current.next!=this.head){
current=current.next;
}
newnode.next=this.head
current.next=newnode
this.head=newnode
}
}else if(position==this.length){
this.append(ele)
}else{
while(index<position-1){
current=current.next
index++
}
newnode.next=current.next
current.next=newnode
}
this.length++
}
3.从链表的特定位置移除一项 removeAt(position)
removeAt(position) {
if (position < 0 || position > this.length - 1 || !Number.isInteger(position)){
return false
}
let current = this.head,
index = 0;
if (position == 0) {
if (this.len == 1) {
this.head = null;
} else {
while (current.next != this.head) {
current = current.next;
}
this.head = this.head.next;
current.next = this.head;
}
} else {
while (index < position - 1) {
current = current.next;
index++;
}
current.next = current.next.next
}
this.length--
}
图解:
1.position=0
2.position=this.length-1
3.0<position&&position<this.length-1
4.返回元素在链表中的索引,如果链表中没有该元素则返回-1. 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){
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()
toString(){
let current=this.head,index=0,res="";
while(index<this.length){
// 将current指向的节点的数据连接为字符串
res+="-"+current.data;
current=current.next ;
index++
}
// 利用字符串的slice(start,end)方法, 提取字符串的片断,并在新的字符串中返回被提取的部分。
return res.slice(1)
}
完整的代码:
<script>
class Cnode {
constructor(data) {
this.data = data
this.next = null
}
}
class LinkList {
constructor() {
this.head = null
this.length = 0
}
// 1.append() 向链表最后添加元素
append(ele) {
let newnode = new Cnode(ele)
if (this.head == null) {
// 空链表
this.head = newnode
newnode.next = this.head
} else {
// 非空链表
// 需要找到最后一个节点
// 最后一个节点.next指向头结点
let current = this.head
while (current.next != this.head) {
// 继续向后查找
current = current.next
}
// 找到了,current表示最后一个节点
current.next = newnode
newnode.next = this.head
}
this.length++
}
// 2.insert(指定位置,插入的元素)
insert(position, ele) {
// 位置是否合法
// Number.isInteger():用来判断给定的参数是否为整数
if (position < 0 || position > this.length || !Number.isInteger(position)) {
return false
}
// 创建一个新节点
let newnode = new Conde(ele)
let current = this.head
let index = 0
// 2.1在头部位置插入
if (position == 0) {
if (this.length == 0) {
// 如果头部指向空,那么就让头部指向新的节点
this.head = newnode
newnode.next = this.head
} else {
while (current.next != this.head) {
current = current.next;
}
newnode.next = this.head
current.next = newnode
this.head = newnode
}
} else if (position == this.length) {
this.append(ele)
} else {
while (index < position - 1) {
current = current.next
index++
}
newnode.next = current.next
current.next = newnode
}
this.length++
}
// 3.removeAt(position) 移除指定位置的元素
removeAt(position) {
if (position < 0 || position > this.length - 1 || !Number.isInteger(position)){
return false
}
let current = this.head,
index = 0;
if (position == 0) {
if (this.len == 1) {
this.head = null;
} else {
while (current.next != this.head) {
current = current.next;
}
this.head = this.head.next;
current.next = this.head;
}
} else {
while (index < position - 1) {
current = current.next;
index++;
}
current.next = current.next.next
}
this.length--
}
// 4.indexOf(ele) 查找指定元素的位置,存在返回index,不存在返回-1
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){
this.removeAt(this.indexOf(ele))
}
// 6.将链表中的数据连接为字符串
toString() {
let current = this.head, index = 0, res = "";
while (index < this.length) {
// 将current指向的节点的数据连接为字符串
res += "-" + current.data;
current = current.next;
index++
}
// 利用字符串的slice(start,end)方法, 提取字符串的片断,并在新的字符串中返回被提取的部分。
return res.slice(1)
}
// 7.isEmpty():如果链表中不包含任何元素,返回true,如果链表长度大于0,则返回false。
isEmpty(){
if(this.length==0){
return true
}else{
return false
}
}
// 8.size():返回链表包含的元素个数。与数组的length属性类似。
size(){
return this.length
}
}
// 测试代码:
let list = new LinkList();
list.append(4)
for (let i = 0; i < 4; i++) {
list.append(i)
}
list.removeAt(2)
console.log(list)
console.log(list.toString())
</script>