【JS 算法基础 】 单链表操作-反转链表

单链表—反转链表


  • 例题:

    链表:1->2->3->4->5->null 反转后:5->4->3->2->1->null

一、反转单链表逻辑分析
/*  
链表反转后:
	原链表头结点指向 null ,原链表尾结点 n 指向原链表第 n-1 个结点,
		原链表第 n-1 个结点指向原链表第 n-2 个结点,
		以此类推,原链表第二个结点指向原链表第一个结点。
		
            1 -> 2 -> 3 -> 4 -> 5 -> null
            5 -> 4 -> 3 -> 2 -> 1 -> null

	实现方法:
        1. 迭代法
        2. 递归法
*/

// 提前创建一个链表

// 1. 定义 node 结点
const node = (val=null,next=null) => {
    return {
        value:val,
        next:next
    }
}

// 2. 定义链表
var node4 = node('5'),
    node3 = node('4',node4), 
    node2 = node('3',node3), 
    node1 = node('2',node2),
    head  = node('1',node1);

// 遍历输出链表
function printList(head){
    var headNode = head , list =[] ;
    while(headNode){
        list.push(headNode)
        headNode = headNode.next;
    }
    console.log(list);
}
console.log("原始链表数据:")
printList(head);

二、迭代法实现链表反转
/*

    1. 迭代法(前置条件: 链表不为一个元素,且结点不为空;)

        从第一个节点开始修改,直到结束 , 通过 while 循环遍历,将此次遍历结点指向上一个节点,若为头结点则指向 null。

*/
function reverseList(head){

    // 链表为 null 或 只有一个节点
    if(!head || !head.next){return head}
    
    var temporaryHead = head;                               // 获取头结点
    var reverseNewListHead = null;                          // 用于存储链表翻转之后的新的头结点 && 作为遍时链表的头结点
    while(temporaryHead){
        
        // 1. 临时存储原始链表的下一个结点(因为下面操作会操作 temporaryHead.next 的值)
        var next = temporaryHead.next;                      
        //console.log("1.next:",next)

        // 2. 更新当前结点的下一个结点为新链表的头结点
        temporaryHead.next = reverseNewListHead;               
        //console.log("2.temporaryHead.next:",temporaryHead.next)

        // 3. 更新当前结点为新链表的头结点
        reverseNewListHead = temporaryHead;       
        //console.log("3.reverseNewListHead:",reverseNewListHead)            

        // 4. 重新获取原始链表要更新的结点
        temporaryHead = next;              
        //console.log("4.temporaryHead:",temporaryHead ? temporaryHead : null)                
    }
    return reverseNewListHead;
}
console.log("翻转链表数据(迭代法):")
printList( reverseList(head))

  • 迭代法代码运行分析
// 迭代法
// Runing:
// while(temporaryHead)
	/*

		var next = temporaryHead.next;
		↓
		→ node1 -> node2 -> node3 -> node4 -> null

		temporaryHead.next = reverseNewListHead;
		↓
		→ null -> head -> node1 -> node2 -> node3

		reverseNewListHead = temporaryHead;
		↓
		→ head -> node1 -> node2 -> node3 -> node4

		temporaryHead = next;        
		↓
		→ node1 -> node2 -> node3 -> node4 -> null

	*/

三、递归法实现链表反转
/*
    2. 递归法(递归边界: 链表不为一个元素,且结点不为空;)

        直接递归至链表最后一个节点,从末尾向前开始逻辑操作。
*/
function iteratorList(head){
    // 判断链表是否为空或者是否只有一个元素 设置递归边界
    if( !head || !head.next ) return head;
    
    // 直接跑到末尾
    var next = head.next ;
    var reverseNewListHead = reverseList(next);          
   
    // 在没有到达最后一个结点之前,不会开始逻辑操作
    next.next = head;
    head.next = null;
    console.log("head.next",head.next)
    
	return reverseNewListHead;
}
console.log("翻转链表数据(递归法):")
iteratorList(head);
printList(node4);
  • 递归法代码运行分析:
// 递归法
// Running:
	/*
		递归至末尾:
		
			next = head.next;
               var reverseNewListHead = reverseList(next);          

			next:
				node1 -> node2 -> node3 -> node4
			
			开始逻辑操作:
				1. next.next = head;
					next = node4 时 , head = node3
						node4.next = node3
                       next = node3 时 , head = node2
						node3.next = node3
					next = node2 时 , head = node1
						node2.next = node3
					next = node1 时 , head = head
						node1.next = head
				2. head.next = null;
					主要功能: 原始列表 head 的 next 为 null
	*/

TIp:通过迭代法翻转链表所进行的操作的是原链表

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值