上一篇讲解分析了一下单向链表的反转实现。再看一下单向循环链表的反转。
(高清图地址: https://www.processon.com/view/link/6121c41363768958e5302f6e )
1,直观的看一下区别:
先直观的看一下【单向链表】和【单向循环链表】的区别
反转之后的指针(引用)指向:
2,实现策略:
2.1,从头节点开始遍历整个链表,直到找到尾节点。
循环尾节点的判断是【尾节点】等于【头节点】 ,之前单向非循环链表的尾节点判断是节点的next为null,注意区别。
2.2,每次遍历的时候,将相邻两个节点中,子节点的next指向前一个节点。
2.3,将当前头节点的next引用指针指向尾节点。
2.4,将头节点的指针(引用)this.head指向尾节点。
2.5,注意:特殊处理一下链表数据为空(this.head === null )和只有一个节点(this.head.next === this.head)的情况,或者用this.length来判断。
上图:
3,上代码
// 单向链表练习
class Node{
constructor(data){
this.data = data;
this.next = null;
}
}
/**
* 单向循环链表
*/
class CircularLinkTable{
constructor(){
this.head =null;
this.length = 0;
}
/**
* 往链表中添加数据
* @param {*} data
* @returns
*/
add(data){
const n = new Node(data);
if(this.head === null) {
this.head = n;
n.next = this.head;
this.length++;
return true;
}
// 找到尾节点
let pre = this.head;
while(pre.next !== this.head){
pre = pre.next;
}
if(pre.next === this.head){
n.next = this.head;
pre.next = n;
this.length++;
return true;
}else{
console.error(`add error, did not find tail node!!!`)
return false;
}
}
/**
* 反转链表
* @returns
*/
reverse(){
if(this.length<=1){
return;
}
let pre = this.head;
let current = pre.next;
// while循环 遍历整个链表,反转next指向到父节点,并找到尾节点
while(current.next !== this.head){
const next = current.next;
current.next = pre; // 反转next指向
// 准备进入下一次搜索,搜索下一个节点
pre = current;
current = next;
}
// 此时的current就是尾节点
current.next = pre;
// 修正头节点的指向,修正头节点next的指向
this.head.next = current;
this.head = current;
}
}
// 测试
function test(){
const lt = new CircularLinkTable();
lt.add("a");
lt.add("b");
lt.add("c");
lt.reverse();
console.log(lt);
}
test();
备注:上一篇单向链表的反转:https://blog.csdn.net/yangxinxiang84/article/details/119842446