JS— 链表中倒数第K个节点和反转链表
(一)创建链表
这里创建一个简单的1>2>3>4>5>6的链表
let node1 = new Node(1);
let node2 = new Node(2);
let node3 = new Node(3);
let node4 = new Node(4);
let node5 = new Node(5);
let node6 = new Node(6);
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
node5.next = node6;
(二)打印链表
/**打印链表 */
function print(node) {
let LList = [];
let curNode = node;
LList.push(curNode.val);
while (curNode.next) {
LList.push(curNode.next.val);
curNode = curNode.next;
}
console.log(LList);
}
print(node1); 输出的结果为:
(三) 求链表中倒数第K个节点
function FindKthToTail(head, k) {
if (!head || k <= 0) { //首先进行安全判断,防止输入有误;
return null;
}
let node = head; //实际节点
let kNode = head; //控制节点
for (let i = 1; i < k; i++) { //实际节点要比控制节点往前K个距离
if (kNode.next) {
kNode = kNode.next;
}
else {
return null;
}
}
while (kNode.next) { //当控制节点到达尾节点时,实际节点刚好是链表中倒数第k个节点
kNode = kNode.next;
node = node.next;
}
return node;
}
console.log(FindKthToTail(node1,2));
(四)反转链表
1、通过修改值来反转链表
//修改值
function ReverseList(pHead) {
if (pHead == null) { //安全判断
return null;
}
let node = pHead;
let arr = [];
while (node) { //此次遍历是为了将链表中的值按顺序存进一个数组
arr.push(node.val);
node = node.next;
}
node = pHead;
while (node) { //此次遍历是为了将链表中的值进行反转
node.val = arr.pop();
node = node.next;
}
return pHead;
}
2、通过修改节点指向来反转链表(递归解法)
B>C的结构,用递归的思想,我们只关注一个节点,因为其他节点已经处理完成或者处理此个节点后就会处理。
当获取到一个B节点时,假设该节点后面的所有节点已经反转完毕,只需要将C的指向改为指向B即可,所以该解法的最重要的就是:
B.next.next = B;
/**修改节点指向(递归) */
function ReverseList(pHead)
{
if (!pHead){
return null;
}
let newNode = doReverse(pHead);
pHead.next = null;
return newNode;
}
function doReverse(node){
let newHead = node;
if (node.next){
newHead = doReverse(node.next);
node.next.next = node; //反转指向
}
else{
newHead = node;
}
return newHead; //确保返回的节点都是最后一个节点,即反转后的头节点
}
3、通过修改节点指向来反转链表(非递归解法)
/**通过修改节点指向来反转链表(非递归解法) */
function ReverseList(pHead) {
if (pHead == null) { //安全判断
return null;
}
let up = null; //上一个
let down = null;
while (pHead) {
down = pHead.next; //用来保存下一个节点
pHead.next = up; //重建链表
up = pHead;
pHead = down;
}
return up;
}