题目描述:输入两个单调递增的链表,输出两个链表合成后的链表,当然,我们需要合成后的链表满足单调不减规则。
先公布结果:
1 /* 2 public class ListNode { 3 int val; 4 ListNode next = null; 5 6 ListNode(int val) { 7 this.val = val; 8 } 9 }*/11 public class Solution { 12 public ListNode Merge(ListNode list1,ListNode list2) { 13 if (list1 == null) {//首先判断两个链表是否为空,若为空,则无需判断 14 return list2; 15 } 16 if (list2 == null) { 17 return list1; 18 } 19 ListNode head = new ListNode(-1);//构建最终链表 20 ListNode cur = head;//构建当前操作节点的链表 21 while (list1 != null && list2 != null) { 22 if (list1.val < list2.val) { 23 cur.next = list1; 24 list1 = list1.next; 25 } else { 26 cur.next = list2; 27 list2 = list2.next; 28 } 29 cur = cur.next; 30 } 31 while (list1 != null) { 32 cur.next = list1; 33 list1 = list1.next; 34 } 35 while (list2 != null) { 36 cur.next = list2; 37 list2 = list2.next; 38 } 39 return head.next; 40 } 41 }
此处,自己本来的编程思路是和上述程序类似的,即非递归操作,但是没有采用head链表,只是采用了cur链表,结果最终输出的时候总是只输出最后部分的节点。
查阅相关内容才没明白,此处涉及到Java中的引用问题,其和赋值操作类似,但是引用是和对象互相关联又相互独立的存在。因为引用可以指向不同的对象,不同的引用也可以指向统一个对象,不管哪个引用操纵对象,对象的内容都会发生改变,并且只有一份。
参考:https://blog.csdn.net/yz930618/article/details/76278997/
将其内容搬运过来:
首先,我们便于说明和理解,首先定义一个简单的类:
1 public class Yinyong { 2 private int a; 3 private int b; 4 public void setA(int a) { 5 this.a = a; 6 } 7 public void setB(int b) { 8 this.b = b; 9 } 10 }
之后对该类进行操作,观察其值的变化:
1 public class YinyongTest { 2 public static void main(String[] args) { 3 Yinyong yy1 = new Yinyong(); 4 yy1.setA(1); 5 yy1.setB(2); 6 System.out.println(yy1); 7 Yinyong yy2 = yy1; 8 yy2.setA(-1); 9 System.out.println(yy1); 10 System.out.println(yy2); 11 } 12 }
最后发现yy1和yy2的值都为a = -1;b = 2;
为此,我们进行分析:为什么改变yy2,yy1也会变化呢?
对于Yinyong yy1 = new Yinyong();语句,该语句执行的创建一个对象,包含了四个步骤:
1. 右边的'new Yinyong',表示以Yinyong类为模板,在对空间中创建一个Yinyong类对象;
2. '()' 表示在对象创建后,会立马调用Yinyong类的构造函数,由于没有给参数,所以会调用默认的无参结构;
3. 左边的‘Yinyong yy1’ 创建了一个Yinyong类的引用变量,也就是用来指向Yinyong对象的对象引用。此处类似于指针。
4. ‘=’ 这个等号操作符表示使对象引用yy1指向刚创建的Yinyong对象。
该语句包含了两个实体:一个时对象引用变量,一个是对象本身。
而且:
1. 一个对象引用可以指向0个或1个对象
2. 一个对象可以有N个引用指向它。
Java对象和引用的彼此独立:
1. 引用是可以改变的,它可以指向别的对象
2. 对象和引用在存储空间上也是独立的,它们存储在不同的地方,对象一般存储在堆中,引用存储在速度更快的堆栈中。
若非引用情况,则单一的参数传递不会导致原值的变化,而引用的参数传递,则需要看实际操作中是否改变了引用的指向,若未改变指向,则利用该引用操作对象时,原对象的值也变化,否则不变化。
1 public class Solu { 2 //基本参数传递 3 public static void fun1(int m) { 4 m = 100; 5 } 6 //参数为对象,不改变引用的值 7 public static void fun2(StringBuffer s) { 8 s.append("fun2"); 9 } 10 //参数为对象,改变应用的值 11 public static void fun3(StringBuffer s) { 12 s = new StringBuffer("fun3"); 13 } 14 15 public static void main(String[] args) { 16 int i = 1; 17 Solu s1 = new Solu(); 18 System.out.println(i);//1 19 StringBuffer ss = new StringBuffer("main"); 20 System.out.println(ss.toString());//main 21 fun2(ss); 22 System.out.println(ss.toString());//mainfun2 23 fun3(ss); 24 System.out.println(ss.toString());//mainfun2 25 } 26 }
此处算是对引用和简单的赋值有了初步了解。
对于我们的题目,因为链表中式中存的是对象的引用,为此,我们需要一个head链表来进行最后结果存储,而采用一个cur链表来不断改变当前节点指向,并由此来得出排序后的链表。