引入
最近学习数据结构与算法,在编写链表反转算法时遇到一个问题。
最初我写的算法是这样的
/**
* 反转链表 优化
*
* @param head 被反转链表的头结点
* @return 思路:
* 1.先定义一个节点reverseHead = new Node();
* 2.从头到尾遍历原来的链表,每遍历一个节点,就将其取出,并放在新的链表reverseHead的最前端
* 3.原来的链表的head.next =reverseHead.next
*/
public Node reverse(Node head) {
Node reverseHead = new Node();
Node temp = head.next;
Node cur = new Node;
while(true){
if(temp != null){
cur = temp;
cur.next=reverseHead.next;
reverseHead.next= cur;
}
if(temp==null){
break;
}
temp = temp.next;
}
head.next = reverseHead.next;
return head;
}
大概看一下感觉没问题,实际却有大问题!
深浅拷贝
浅拷贝
只存在于引用数据类型,直接举例说明
package linkedlist;
/**
* @author Watching
* * @date 2022/10/25
* * Describe:
*/
public class Person {
String name;
int age;
//构造器
Person(String name,int age){
this.age = age;
this.name= name;
}
Person(){}
//getter setter
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public static void main(String[] args) {
Person p1 = new Person("watching",21);
Person p2 = new Person();
//令p2 = p1
p2 = p1;
//修改p2信息
p2.setName("watchingDz");
p2.setAge(30);
//输出p1 p2的信息
System.out.println("p1.name:"+p1.name); //结果:p1.name:watchingDz
System.out.println("p1.age:"+p1.age); //结果:p1.age:30
}
}
可以看到我们修改了p2的属性,但是p1的却改了。
原因:p2=p1并不是创建一个新的person对象,而是令p2指向了p1的内存地址。所以修改了p2的成员变量时,就修改了p2指向的内存地址中的成员变量。而同样指向这片地址的p1的内容也被修改了。
深拷贝
区别于浅拷贝,深拷贝是开辟一个新的内存空间,修改新的内存空间中的值不会影响原来的内存空间中的值。
两个对象的内存地址是不一样的
java深拷贝的方式
1.构造器方式(在需要很多对象时不适用,创建很多对象会浪费资源
2.重写clone方法
3.Apache Commons Long序列化
4.Gson序列化
5.Jackson序列化
回到开头的算法
/**
* 反转链表 优化
*
* @param head 被反转链表的头结点
* @return 思路:
* 1.先定义一个节点reverseHead = new Node();
* 2.从头到尾遍历原来的链表,每遍历一个节点,就将其取出,并放在新的链表reverseHead的最前端
* 3.原来的链表的head.next =reverseHead.next
*/
public Node reverse(Node head) {
Node reverseHead = new Node();
Node temp = head.next;
Node cur = null;
while(true){
if(temp != null){
cur = new Node(temp.number,temp.name,temp.nickName);//使用构造器的方式避免浅拷贝
cur.next=reverseHead.next;
reverseHead.next= cur;
}
if(temp==null){
break;
}
temp = temp.next;
}
head.next = reverseHead.next;
return head;
}