链表——Java实现链表反转的两种方法

本文深入讲解链表数据结构,探讨两种链表反转方法:原地反转与头插法。通过Java代码实现,详细解析每种方法的工作原理及指针操作技巧。

前提

链表是多个不一定连续的内存块(节点),通过节点保存的后置指针或前置指针串联起来的一种数据结构;
链表不支持随机访问;
下面的反转链表没有特别提示的都是带头链表(引入了哨兵的链表),用java实现,节点类如下:

/**
 * @Author Haoqi
 * @Description 链表节点
 **/
Class Node{
	int data;
	Node next;
	/**
	 * 构造哨兵节点
	 **/
	public Node() {
        this.data = -1;
        this.next = null;
    }
	//其他构造方法
	//...
}

两种实现

原地反转

通过指针的变化,在链表自身进行反转,不会产生另外一个新链表;

public static Node reverseLinkList(Node head){
	if(head.next == null){
		return head;
	}
	Node prev = head.next;
	Node pcur = prev.next;
	while(pcur != null){
		prev.next = pcur.next;
		pcur.next = head.next;
		head.next = pcur;
		pcur = prev.next;
	}
	return head;
}
  • head节点是哨兵节点,不存数据只是,只是为了简化代码;
  • 第一个判断看链表是否为空链表,即除了哨兵没有其他数据节点;
  • 实现需要两个指针,一个前置指针 prev ,一个移动指针pcur;
  • 循环结束条件是移动指针为null;
  • 注意指针操作顺序防止指针丢失,这里可以逐步画图演示,辅助理解
  • pcur指针指向的是下次循环结束后的第一个数据节点 head.next = pcur;
  • 最后pcur向后移动,但每次循环开始结束prev一直是pcur的前置节点;
  • 时间复杂度O(n)

头插法反转

顾名思义,遍历旧链表,反复向新链表的第一个节点位置插入,产生的新链表就是旧链表的反转;

public static Node reverseLinkList(Node head){
	if(head.next == null){
		return head;
	}
	Node newHead = new Node();
	Node pcur = head.next;
    Node curNextTmp = null;
	while(pcur != null){
		curNextTmp = pcur.next;
		pcur.next = newHead.next;
		newHead.next = pcur;
		pcur = curNextTmp;
	}
	return newHead;
}
  • head节点是哨兵节点,不存数据只是,只是为了简化代码;
  • 第一个判断看链表是否为空链表,即除了哨兵没有其他数据节点;
  • 实现需要新建一个带头空链表newHead,一个移动指针pcur和一个缓存curNextTmp;
  • 循环结束条件是移动指针为null;
  • 每次循环,先将pcur的后续节点缓存起来,然后再向新链表第一个数据节点处插入pcur(头插),最后将pcur移到缓存的后续节点;
  • 时间复杂度为O(n)

熄灯

怎么写出正确的链表?画图理解记忆,再多默写几次就行。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小技工丨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值