单列表反转两种方式(第一种按照c语言实现,第二种方式java语言实现)

单链表的反转是常见的面试题目。本文总结了2种方法。

1 定义

单链表node的数据结构定义如下:

class ListNode {
    int val;
    ListNode next;
    ListNode(int x) {
        val = x;
        next = null;
    }
}

方法1:就地反转法

思路

把当前链表的下一个节点pCur插入到头结点dummy的下一个节点中,就地反转。

dummy->1->2->3->4->5的就地反转过程:

dummy->2->1->3->4->5
dummy->3->2->1->4->5
dummy->4>-3->2->1->5
dummy->5->4->3->2->1

解释

1初始状态
在这里插入图片描述

过程

pCur是需要反转的节点。

prev连接下一次需要反转的节点
反转节点pCur
纠正头结点dummy的指向
pCur指向下一次要反转的节点
伪代码

1 prev.next = pCur.next;
2 pCur.next = dummy.next;
3 dummy.next = pCur;
4 pCur = prev.next;

在这里插入图片描述

循环条件

pCur is not null

代码

// 1.就地反转法
    public ListNode reverseList1(ListNode head) {
        if (head == null)
            return head;
        ListNode dummy = new ListNode(-1);
        dummy.next = head;
        ListNode prev = dummy.next;
        ListNode pCur = prev.next;
        while (pCur != null) {
            prev.next = pCur.next;
            pCur.next = dummy.next;
            dummy.next = pCur;
            pCur = prev.next;
        }
        return dummy.next;
    }

总结

1个头结点,2个指针,4行代码
注意初始状态和结束状态,体会中间的图解过程。

方法2:新建链表,头节点插入法

3.1 思路
新建一个头结点,遍历原链表,把每个节点用头结点插入到新建链表中。最后,新建的链表就是反转后的链表。

解释

1 初始状态
在这里插入图片描述

过程

pCur是要插入到新链表的节点。

pNex是临时保存的pCur的next。

pNex保存下一次要插入的节点
把pCur插入到dummy中
纠正头结点dummy的指向
pCur指向下一次要插入的节点

伪代码

1 pNex = pCur.next
2 pCur.next = dummy.next
3 dummy.next = pCur
4 pCur = pNex  

在这里插入图片描述

循环条件

pCur is not null

具体代码:

// 2.新建链表,头节点插入法
   //列表反转
    public void reverse (Hero5 head)
    {
    	if (head.next==null||head.next.next==null) {//如果列表为空或者只有一个节点则无需反转
			return ;
		}
    	Hero5 cur = head.next;//当前节点
    	Hero5 nex =null;//备用节点,用来存放cur的下一个节点
    	Hero5 temp =new Hero5(0,"","");//创建一个空列表
    	while (cur!=null) {
			nex = cur.next;//定义nex指针使得cur移动
			cur.next = temp.next;//cur后一个指针始终在新列表顶端
			temp.next = cur;//每次将nex指针顶下去
			cur = nex;	//原来列表依次移动	
		}
    	head.next = temp.next;//原来列表头指针指向新列表头
    }

总结

1个头结点,2个指针(包含一个临时保存节点的pNex),4行代码
注意初始状态和结束状态,体会中间的图解过程。
在这里插入图片描述

方法3:利用栈(先进后出)

在这里插入图片描述

代码

//列表反转2,利用栈实现
    public void reverse2(Hero6 head)
    {
    	if (head.next==null||head.next.next==null) {//如果列表为空或者只有一个节点则无需反转
			return ;
		}
    	Stack<Hero6> stack = new Stack<Hero6>();
    	Hero6 cur = head.next;
    	while(cur!=null) {
    		stack.push(cur);//向栈依次压进数字
    		cur=cur.next;//依次移动
		}
    	while (stack.size()>0) {//如果栈里面大于0,就循环,依次输出
			System.out.println(stack.pop());	//出栈,pop方法,先进后出		
		}    	
    }
    ```
    
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值