数据结构(三)
1顺序表的浅拷贝
- 当成员变量是基本数据类型时,浅拷贝能够实现对象的复制功能
- 当成员变量是引用数据类型时,浅拷贝只是复制了数组引用或对象引用(即指向同一个地址),并没有实现对象复制功能
2.顺序表的深拷贝
当一个类包含数组或对象等引用类型的成员变量时,该类声明的拷贝构造方法,不仅要复制对象的所有基本数据类型成员变量值,还要为引用类型变量申请存储空间,并复制其中所有的元素/对象
注:回顾Java语言类的继承和多态原则
-
子类继承原则:子类不能继承父类的构造方法,但能够调用父类的无参构造方法,只能继承除了构造方法之外的成员变量和成员方法,包括析构方法
–隐藏:子类重新定义父类的成员变量
–覆盖:子类重新定义与父类的参数列表相同的成员方法
–重载:子类重新定义与父类的参数列表不同的成员方法
–子类的实例成员变量可使用“super调用”访问被隐藏的父类成员变量和成员方法 -
多态原则:覆盖表现为父类和子类之间的多态性;父类对象可以引用子类实例对象
3.线性表的链式存储
- 线性表的链式存储结构:用若干地址分散的存储单元存储数据元素,逻辑上相邻的数据元素在物理位置上不一定相邻
- 结点(Node):存储一个数据元素的存储单元
–数据域:存储数据元素
–地址域:存储前驱或后继的元素地址
–线性链表:采用链式存储结构的线性表
–头指针:记住线性表第一个元素a0的结点地址
–单链表:每个结点只有一个地址域
4.单链表的基本操作
- 遍历操作
Node<T>p=head;
while(p!=null){
System.out.print(p.data.toString()+" ");
p=p.next;
}
- 插入操作
– 空表插入:(head==null)
head=new Node(x,null);
– 头插入:(head!=null)
Nodep=new Node(x,null);
p.next=head;
head=p;
或:
head=new Node(x,head);
– 中间插入
Nodep=new Node(x,null);
p.next=front.next;
front.next=p;
或:
front.next=new Node(x,front.next);
– 尾插入
front.next==null;
例子练习:单链表逆转(头结点不变,指针域指向最后一个元素,第一个元素的指针域指空)
package List;
public class SinglyList_reverse<T> {
//构造反序单链表,由values数组提供元素,返回值类型前声明类型参数T
//采用头插入,单链表元素次序与数组元素次序相反
public static <T>SinglyList<T>createReverse(T[]values){
SinglyList<T> singlylist=new SinglyList<T>();
Node<T>head=(Node<T>)singlylist.head;
for(int i=values.length-1;i>=0;i--) {
singlylist.insert(0,values[i]);
}
return singlylist;
}
public static <T>void reverse(SinglyList<T>list){ //将list单链表逆转
Node<T>head=(Node<T>) list.head;
Node<T>front=null;//p的前驱
Node<T>p=head.next;//当前结点
Node<T>succ=p.next;//p的后继
while(succ!=null) { //succ为null说明succ位于尾结点
p.next=front;
front=p;
p=succ;
succ=succ.next;
}
p.next=front;
front=p;
head.next=front;
}
public static void main(String[]args) {
String[]values= {"A","B","C","D","E","F"};
SinglyList<String>list=createReverse(values);
System.out.print("list="+list.toString());
reverse(list);
System.out.print(",逆转后"+list.toString());
}
}