数据结构的链表和自定义容器类
1<什么是数据结构
计算机对存储的一种安排
1常见的数据结构
1.1常见数据结构
![img](file:///C:\Users\ljl\AppData\Local\Temp\ksohtml6668\wps1.jpg)
2 数据存储方式
变量:一个存储空间,
数据类型限定了存储空间,储存的数据类型,比如:int 不能装string
数组: 连续的存储空间 int[] arr={ 11,22,33}
长度固定的, length=3,
数据类型限制了储存的空间,并且储存的值的个数和类型都是固定的,
思考:又没有一种东西,可以储存不同的数据类型.储存不同的值
自定义容器:
1.1 自定义类存储
定义容器类目标希望可以存储,任意多个元素;任意类型的数据
1.2再java的角度,怎么设计
1.3提示:
Integer类 里面有个int value 变量存储值,
String类 里面有个 char[] value 字符数组变量存储值.
1.4步骤:
①自定义一个容器类,比如(IntArray类);
②先做到可以存储多个int值,内部字段使用int数组;
③类里面 创建了一个int数组
④当int数组填满之后,创建一个新的数组;并且把老的数组值拷贝到新的数组里面(实现自动扩容);
- 自定义类已经设计好了,那用户在操作的时候,怎么使用?也就是怎么存值,怎么取值?
提供了一个add方法,调用一次add方法就向容器里面添加一个元素
package cn.tx_dom;
import java.util.Arrays;
public class Int_Add {
public static void main(String[] args) {
IntArr_d intArr1 = new IntArr_d();
intArr1.add("今天我");
intArr1.add(20 + "岁");
intArr1.add("就可以");
intArr1.add("任意数据类型");
System.out.println(intArr1);
System.out.println(intArr1.size); //打印长度
System.out.println(intArr1.getIndexByElement("就可以"));
}
}
class IntArr_d { //定义一个容器类
Object[] arr; // 定义一个任意值字段
int size; //定义一个可以表示索引的字段
public IntArr_d() { //初始化长度
this(2);
}
public IntArr_d(int length) { //有参的构造方法,
arr = new Object[length]; //定义arr的长度
}
void add(Object w) { //传入任意类型的数据
if (size == arr.length) { //判断索引和长度是否相等
Object[] newarr = new Object[size + 10];
System.arraycopy(arr, 0, newarr, 0, arr.length); //合并数组
arr = newarr; //重新赋值给新数组
}
arr[size++] = w; //每传入一个数据,对应的索引+1
}
@Override
public String toString() { //覆写toString,期望测试打印的是具体的值,不是地址
Object[] newarr = new Object[size];
System.arraycopy(arr, 0, newarr, 0, size);
return Arrays.toString(newarr);
}
开可以设计方法对容器里面的东西进行改变,
比如增删查改
设计一个查找的方法
/*查找指定元素第一次出现的索引
根据元素查索引
public int getIndexByElement(Object obj){ }
*/
public int getIndexByElement(Object obj) {
for (int w = 0; w < size; w++) {
if (obj.equals(arr[w])) { //判断传入的参数是否和arr中索引对应的值相等
return w; //返回值
}
}
return -1; //表示不存在,-1没有特殊意思,就普通一个返回值
}
}
数据结构-(基于链表)
1.1. 链表引入
- 什么是链表结构
![img](file:///C:\Users\ljl\AppData\Local\Temp\ksohtml6668\wps2.jpg)
- 对于变量直接赋值使用; 对于数组,通过下标使用; 对于自定义容器类的操作,我们通过添加add方法,进行使用.它的原理是内部使用数组来存储实现,但是用户并不关心内部怎么实现.
![img](file:///C:\Users\ljl\AppData\Local\Temp\ksohtml6668\wps3.jpg)
- 目前已经使用变量,数组,还有自定义容器类存放数据;
-
变量:存储一个值;
-
数组:存储多个值;
-
自定义容器类: 在类中封装一个数组;
- 需求:----->设计一个容器类,采用链表结构:内部实现替换数组用变量
![img](file:///C:\Users\ljl\AppData\Local\Temp\ksohtml6668\wps4.jpg)
问题: 怎样把 多个变量链接起来,还能够存储任意数据类型?
分析:
①从存储任意数据类型来看,目前所有类中只有Object可以满足
②但是Object只能存一个对象的地址,无法满足链接下一个对象
结论:目前已知类型不能满足:怎么办?
①现在自定义一个类Node(相当于口袋),类里面定义两个字段,
② 一个Object类型存放值,一个Node类型字段,存放下一个Node对象地址.
分为三部走:
创建一个Node类
一个容器类:
一个测试类:
lass Node1 {
Object date; //任意的数据
Node next;
Node1(Object obj) { //创建Node的一个传参的构造方法传参
this.date =obj ; //将数据放入date容器
}
看懂下图,理解temp.next 和里面next锁表达的东西.
看代码:Node类
class Node {
Object date; //任意的数据
Node next;
Node(Object obj) { //创建Node的一个传参的构造方法
this.date = obj;
}
}
容器类:
class Link1 {
Node first;
void add1(Object obj) {
Node node = new Node(obj);
if (first == null) {
first = node;
} else {
Node temp = first;
while (temp.next != null) { //循环判断temp.;next是否为null
temp = temp.next; //将地址给temp
}
temp.next = node; //将值赋给null的节点对象
}
}
@Override
public String toString() {
Node temp = first; //节点初始化
StringBuilder sb = new StringBuilder("["); //字符序列
while (temp != null) { //判断temp是否为null
if (temp.next != null) { //判断temp指像的地址是否为null
sb.append(temp.date).append(",");
} else {
sb.append(temp.date).append("]");
}
temp = temp.next;
}
return sb.toString(); //返回sb,
}
}
测试类:
package cn.tx_dom;
public class Link_1 {
public static void main(String[] args) {
Link1 link1 = new Link1();
link1.add1("是否我");
link1.add1("李时珍");
link1.add1("的一无所有");
System.out.println(link1);
}
}