- 数据存储的底层原理
数据在底层存储的形式有两种分为数组形式的存储和链表存储的形式,这两种的区别是什么:数组存储在内存地址上必须是连续的;链表的存储形式在地址上不一定是连续的
-链表可以存储各种类型的数据,假设现在存储类型为一个类,对于链表中必须要有一个类似于指针的东西指向下一个链表节点的地址,每个链表节点中都有下一个节点的地址,而且每个节点中还需有存储本身的数据
public class Node {
public Object obj;//这个属性是类中用来存储数据的属性
public Node next;//类中有一个属性是可以指向下一个类的
public Node() {
}
public Node(Object obj) {
this.obj = obj;
}
}
- 对于链表的操作,增加 删除 长度计算,因此选择定义一个接口(因为对于链表的每个节点都有增删等操作,因此选择用类实现一个接口)
public interface Inode<E> {
public void add(E e);//增加节点
public void delet(E e);//删除节点
public int size(); //长度
}
- 定义一个类去实现这个接口
- 对于增加节点,首先对于链表来说因为定义的是每一个节点都是一个类,因此也会有类中需要定义一个类型位Node的属性,目的是指向下一个节点类,定义一个根节点和一个尾节点,根节点是链表的头,尾节点是链表的最后一个节点
其中下面代码中的为泛型,可以定义增加的数据类型。
public void add(E e) {
Node no = new Node(e);//新建一个类将需要保存的数据保存到类中去(需要增加的新类节点)
Node head = root.next;//head为根节点的下一个节点
if(head == null) { //如果根节点的下一个节点为空,则将新节点放在根节点的下一个节点中
root.next = no;
last = no; //因为新增加了一个节点因此尾节点需要向后移一位
size++; //链表的长度需要增加一位
}else{
last.next = no; //当链表中已经有了节点后,则每次增加新节点都是在尾节点后面增加
last = no;
size++;
}
- 删除节点
设计的是根据节点当中的值来进行删除,思路是遍历列表如果发现和需要删除的值相同的节点,则删掉该节点,同时上一个节点的next指向删除节点的next的值。
public void delet(E e) {
Node nn = root.next;//定义一个nn类用来遍历链表,寻找需要删除的节点
Node mm = root;//为nn的上一个节点
while(nn != null) {
//nn = root.next;
if(nn.obj == e) {
//root.next = nn.next;
mm.next = nn.next;//表示将节点已经删除
size--;//尺寸会减一
break;
}else {
nn = nn.next;
mm = mm.next;
}
}
}
- 返回链表长度,因为初始化链表长度为0,当进行增加删除操作之后,随之size也会进行相应变化
public int size() {
// TODO Auto-generated method stub
return size;
}
数组的长度是固定的,如果要进行改变则需要进行copy操作,意味着需要同样大小的存储空间进行操作,而且这些存储空间必须要是连续的,这样使得效率很低,链表没有固定的长度,可以进行增删改查等操作,而且对于内存不要求是连续的,这样也就不会有内存碎片化的出现!!!