剑指offer——合并两个排序的链表——对象、引用和赋值初接触

题目描述:输入两个单调递增的链表,输出两个链表合成后的链表,当然,我们需要合成后的链表满足单调不减规则。

先公布结果:

 /*
public class ListNode {
int val;
ListNode next = null; ListNode(int val) {
this.val = val;
}
}*/ public class Solution {
public ListNode Merge(ListNode list1,ListNode list2) {
if (list1 == null) {//首先判断两个链表是否为空,若为空,则无需判断
return list2;
}
if (list2 == null) {
return list1;
}
ListNode head = new ListNode(-1);//构建最终链表
ListNode cur = head;//构建当前操作节点的链表
while (list1 != null && list2 != null) {
if (list1.val < list2.val) {
cur.next = list1;
list1 = list1.next;
} else {
cur.next = list2;
list2 = list2.next;
}
cur = cur.next;
}
while (list1 != null) {
cur.next = list1;
list1 = list1.next;
}
while (list2 != null) {
cur.next = list2;
list2 = list2.next;
}
return head.next;
}
}

此处,自己本来的编程思路是和上述程序类似的,即非递归操作,但是没有采用head链表,只是采用了cur链表,结果最终输出的时候总是只输出最后部分的节点。

查阅相关内容才没明白,此处涉及到Java中的引用问题,其和赋值操作类似,但是引用是和对象互相关联又相互独立的存在。因为引用可以指向不同的对象,不同的引用也可以指向统一个对象,不管哪个引用操纵对象,对象的内容都会发生改变,并且只有一份。

参考:https://blog.csdn.net/yz930618/article/details/76278997/

将其内容搬运过来:

首先,我们便于说明和理解,首先定义一个简单的类:

 public class Yinyong {
private int a;
private int b;
public void setA(int a) {
this.a = a;
}
public void setB(int b) {
this.b = b;
}
}

之后对该类进行操作,观察其值的变化:

 public class YinyongTest {
public static void main(String[] args) {
Yinyong yy1 = new Yinyong();
yy1.setA(1);
yy1.setB(2);
System.out.println(yy1);
Yinyong yy2 = yy1;
yy2.setA(-1);
System.out.println(yy1);
System.out.println(yy2);
}
}

最后发现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. 对象和引用在存储空间上也是独立的,它们存储在不同的地方,对象一般存储在堆中,引用存储在速度更快的堆栈中。

若非引用情况,则单一的参数传递不会导致原值的变化,而引用的参数传递,则需要看实际操作中是否改变了引用的指向,若未改变指向,则利用该引用操作对象时,原对象的值也变化,否则不变化。

 public class Solu {
//基本参数传递
public static void fun1(int m) {
m = 100;
}
//参数为对象,不改变引用的值
public static void fun2(StringBuffer s) {
s.append("fun2");
}
//参数为对象,改变应用的值
public static void fun3(StringBuffer s) {
s = new StringBuffer("fun3");
} public static void main(String[] args) {
int i = 1;
Solu s1 = new Solu();
System.out.println(i);//
StringBuffer ss = new StringBuffer("main");
System.out.println(ss.toString());//main
fun2(ss);
System.out.println(ss.toString());//mainfun2
fun3(ss);
System.out.println(ss.toString());//mainfun2
}
}

此处算是对引用和简单的赋值有了初步了解。

对于我们的题目,因为链表中式中存的是对象的引用,为此,我们需要一个head链表来进行最后结果存储,而采用一个cur链表来不断改变当前节点指向,并由此来得出排序后的链表。

上一篇:使用ServletContext读取properties配置文件


下一篇:AJAX方式调用百度天气