单链表反转方法的简单总结

方法一:递归反转法

首先要确定递归的终止条件

是当前节点为空(这里是为了处理空链表的情况)或者当前节点的下一个节点为空

即:head == null || head.next == null

对于递归函数内部而言,其每次返回的cur其实都是最后一个节点,同时在内部还完成了当前节点与下一个的节点的反向,下面以图示的5节点链表为例来展示详细的执行过程

public ListNode reverseListNode(ListNode head) {
	if(head==null || head.next==null) {
		return head;
	}
	ListNode cur = reverseListNode(head.next);
	head.next.next = head;
	head.next = null;
	return cur;
}
  • 时间复杂度:O(n)  空间复杂度:O(n)

方法二:双(三)指针法(迭代法)

双(三)指针法是迭代法中的一种,它的主要思想是分别定义两(三)个指针,一个指针pre最初是指向 null 的,另一个指针 cur 指向 head,然后不断遍历 cur。每次迭代到 cur,都将 cur 的 next 指向 pre,然后 pre 和 cur 前进一位。当cur为空时,结束迭代,此时pre就是最后一个节点,返回即可。(此处三指针就是加上一个next指针指向cur的下一个节点,三指针和双指针的方法类似,两种方法精髓是相同的,所以放在一起写了)下面以节点1和节点2的双指针反转过程为例来展示详细的执行过程

public ListNode reverseListNode(ListNode head) {
    ListNode pre = null;
    ListNode cur = head;
    while (cur != null) {
        ListNode temp = cur.next;
        cur.next = pre;
        pre = cur;
        cur = temp;
    }
    return pre;
}

时间复杂度:O(n)  空间复杂度:O(1)

方法三:头插法(迭代法)

头插法的主要思想是重新建一个新头节点,然后对原链表进行遍历,在遍历过程中把每个节点当作头节点插入到新建链表中。最后,新建的链表就是反转后的链表,注意返回时要返回新建节点的下一个节点。

下面以节点1和节点2的反转过程为例来展示详细的执行过程

public ListNode reverseListNode(ListNode head) {
    ListNode dump = new ListNode(-1);
    ListNode cur = head;
    while(cur != null){
        ListNode next = cur.next;
        cur.next = dump.next;
        dump.next = cur;
        cur = next;
    }
    return dump.next;
}

时间复杂度:O(n)  空间复杂度:O(1)

方法四:就地逆置反转法(迭代法)

就地逆置反转法和头插法的实现思想相似,它们的区别在于头插法是通过建立一个新链表实现的,而就地逆置法则是直接对原链表做修改,从而实现将原链表反转。在就地逆置反转法中需要借助两个指针实现,下面以节点2和节点3的反转过程为例来展示详细的执行过程

public ListNode reverseListNode(ListNode head) {
    if(head == null)
        return head;
    ListNode dump = new ListNode(-1);
    dump.next = head;
    ListNode pre = dump.next;
    ListNode cur = pre.next;
    while(cur != null){
        pre.next = cur.next;
        cur.next = dump.next;
        dump.next = cur;
        cur = pre.next;
    }
    return dump.next;
}

时间复杂度:O(n)  空间复杂度:O(1)

方法五:栈实现反转

除了上述的几种方式外,还可以利用栈的先进后出的思想来实现单链表的反转,首先对链表进行遍历并将各个节点入栈,当节点出栈的时候就是逆序的了。(需要注意在出栈的时候要消除每个节点的next指向。)

public ListNode reverseListNode(ListNode head) {
    if(head == null)
        return head;
    Stack<ListNode> stack = new Stack();
    ListNode temp = head;
    while(temp != null){
        stack.push(temp);
        temp = temp.next;
    }
    ListNode dump = stack.pop();
    ListNode cur = dump;
    while(!stack.isEmpty()){
        ListNode node = stack.pop();
        node.next = null;
        cur.next = node;
        cur = node;
    }
    return dump;
}

时间复杂度:O(n)  空间复杂度:O(n)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值