单向链表
单向链表是一种线性表,实际上是由节点(Node)组成的,一个链表拥有不定数量的节点。其数据在内存中存储是不连续的,它存储的数据分散在内存中,每个结点只能也只有它能知道下一个结点的存储位置。由N各节点(Node)组成单向链表,每一个Node记录本Node的数据及下一个Node。向外暴露的只有一个头节点(Head),我们对链表的所有操作,都是直接或者间接地通过其头节点来进行的。
链表与数组的区别
数组的特点
- 在内存中,数组是一块连续的区域。
- 数组需要预留空间,在使用前要先申请占内存的大小,可能会浪费内存空间。
- 插入数据和删除数据效率低,插入数据时,这个位置后面的数据在内存中都要向后移。删除数据时,这个数据后面的数据都要往前移动。
- 随机读取效率很高。因为数组是连续的,知道每一个数据的内存地址,可以直接找到给地址的数据。
- 数组定义的空间不够时要重新定义数组。
链表的特点
- 在内存中可以存在任何地方,不要求连续。
- 每一个数据都保存了下一个数据的内存地址,通过这个地址找到下一个数据。
- 增加数据和删除数据很容易。只需要改变地址指向就行,不需要数据的移动。
- 查找数据时效率低,因为不具有随机访问性,所以访问某个位置的数据都要从第一个数据开始访问,然后根据第一个数据保存的下一个数据的地址找到第二个数据,以此类推。
- 不指定大小,扩展方便。链表大小不用定义,数据随意增删。
链表与数组的选择
多查询用数组,多增加删除用链表。
Java实现单链表代码如下:
class node{ //节点
int data; //数据
node next; //用来指向下一个地址 模仿指针
public node(){}
public node(int data){
this.data = data;
}
}
public class aa {
public static void main(String[] args) {
node head = null; //创建头节点
node t = null; //创建头节点
node n1 = new node(2); //创建其它节点并输入数据
//创建第一个节点时 next置空
n1.next = null;
node n2 = new node(4);
node n3 = new node(6);
List<node> list = new ArrayList();
list.add(n1);
list.add(n2);
list.add(n3);
int i ;
/*
//给链表中添加数据 尾插法
for( i = 0; i<list.size();i++){
if(head == null){
head= list.get(0);
}else{
list.get(i-1).next = list.get(i); //如果不是头节点则将上一个节点的next指向此节点地址
}
head = list.get(0); //将头节点指向第一个节点
}
*/
//给链表中添加数据 头插法
for( i = 0; i<list.size();i++){
if(head == null){
head = list.get(0); //把第一个节点赋值给头节点
}else{
list.get(i).next = list.get(i-1); //如果不是头节点则将此节点的next指向上一个节点地址
}
head = list.get(i); //把此节点的地址赋值给头节点
}
t = head; //从链表头部开始遍历
System.out.print("原始的数据:");
while (t!=null){ //如果头节点的next值不为空则输出头节点指向的地址数据
System.out.print(t.data);
t = t.next; //指向下一个节点
}
//增加节点
node n4 = new node(5);
t = head;
while (t!=null){ //如果头节点的next值不为空则输出头节点指向的地址数据
if(t.data<n4.data){ //如果第一个节点小于添加的节点,则把第一个节点添加到该节点的next
n4.next = t;
head = n4; //另该节点为开始节点
}
if(t == null || t.next.data < n4.data) { //如果该节点的下一个节点的值小于待插入数据时插入数据
n4.next = t.next; //把该节点的指向的下一个节点赋值给添加节点指向的下一个节点
t.next = n4; //把添加节点设置为该节点指向的节点
break;
}
t = t.next; //指向下一个节点
}
System.out.println();
System.out.print("添加数据5:");
t = head;
while (t!=null){ //如果头节点的next值不为空则输出头节点指向的地址数据
System.out.print(t.data);
t = t.next; //指向下一个节点
}
//删除节点n4节点也就是值为4的节点
t = head;
while (t!=null){ //如果头节点的next值不为空则输出头节点指向的地址数据
if(t.next.data == 5) { //如果下一个节点的值等于待删除数据时删除
t.next = t.next.next; //删除数据
break;
}
head = head.next; //指向下一个节点
}
System.out.println();
System.out.print("删除数据5:");
t = head;
while (t!=null){ //如果头节点的next值不为空则输出头节点指向的地址数据
System.out.print(t.data);
t = t.next; //指向下一个节点
}
}
}
结果如下图所示: