单链表逆序掌握这两种思路就够了!!!

本文介绍了单链表逆序的两种思路,包括改变节点next指针的方法和不改变头节点及初始节点的策略,强调了避免环的产生以及理解指针顺序的重要性。

阅读本篇文章大约花费您4~5分钟!


      链表是非常重要的一种数据结构,插入和删除的效率都是O(1),但是查找的效率比较低是O(n)。在单链表中,经常会遇到逆序单链表的题目,虽然听起来很简单,但是要想完整无误的写出代码,还是有很多细节要注意的。

     今天给大家介绍两个思路来分析这个问题。

     首先我们要知道单链表逆序的本质就是将节点的next指针指向它的前一个节点;并且完成逆序操作,至少要知道三个节点才可以。这是我们继续分析的基石。

     假设有一个单链表(节点数为4个),三个节点的引用分别为p1,p2,p3;

思路一

     思路一的思想是知道三个节点,核心操作为p2.next=p1,然后三个节点依次向后移动,结束后再修改头指针head。

     结束的条件是p2==null。

     我们可以用图示的形式看一下这个过程:

     结束后再将头的next指向p1即可。

     这种方法有一个问题,也体现在图中,在头两个节点间存在了环,因此遍历时可能出现死循环,在代码中应该将第一个节点的next置为null。

/*单链表节点类*/
public class SinglyNode<T> {
	protected T data;
	protected SinglyNode<T> next;
	
	public SinglyNode() {
		this(null,null);
	}
	
	public SinglyNode(T data) {
		this(data,null);
	}
	
	public SinglyNode(T data,SinglyNode<T> next) {
		this.data=data;
		this.next=next;
	}
	
	@Override
	public String toString() {
		return data.toString();
	}
}
/*单链表逆序*/
public SinglyList reverse(SinglyList<T> list) {
        //保证只有>=2个节点时才做逆序操作    
	if(list.head.next==null||list.head.next.next==null) {
		return list;
	}

	SinglyNode<T> p1=list.head.next;
	SinglyNode<T> p2=list.head.next.next;
	SinglyNode<T> p3=null;

	while(p2!=null) {  //结束条件
		p3=p2.next;
		p2.next=p1;
                //放在出现环,可以这样写是因为环只可能出现在第一个和第二个节点之间
		if(p1==list.head.next) {
			p1.next=null;
		}

		p1=p2;
		p2=p3;
	}
	list.head.next=p1;
	return list;
}

 

思路二

     第二个思路和第一个思路的不同之处在于不改变head和p1的引用,每次都直接将p2插入到head之后,也不会出现环,实现的原理如下图:

这种方法的指针的指向比第一种稍微复杂一点,但是不会出现上面的环,并且head和p1都不会改变,只需要改变p2,p3即可。

这种方法需要注意指针的操作顺序。

代码如下:

/*单链表逆序*/
public SinglyList reverse(SinglyList<T> list) {
        //保证只有>=2个节点时才会做逆序操作
	if(list.head.next==null||list.head.next.next==null) {
		return list;
	}

	SinglyNode<T> p1=list.head.next;
	SinglyNode<T> p2=list.head.next.next;
	SinglyNode<T> p3=null;

	while(p2!=null) {  //结束条件一样
		p3=p2.next;   //注意每条语句的顺序
		p1.next=p3;
		p2.next=list.head.next;
		list.head.next=p2;
		p2=p3;
	}
	return list;
}

      以上就是单链表的逆序的思路,归根到底要记住逆序的本质,以及要充分理解指针指向的顺序和含义。

      希望大家面对单链表逆序的问题都能够顺序快速正确的解决!

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值