数据结构一般由离散单位和连续单位构成,离散单位如链表,连续单位如数组队列,不论是链表还是数组队列他们都是线性的,有大小的,可以进行增删改查,今天我们主要来讨论链表(单向链表)的实现。
链表由节点组成,第一个结点为头节点,最后一个结点定义为尾节点,一个节点分为两部分,一部分保存数据(data),另一部分存放下一个节点的地址,最后一个节点指向空。
public class Link {
public class Node{
//节点的属性
Object data;//节点中存储的数据
Node next;//下一个节点
public Node(Object data){
this.data=data;
}
}
int size = 0;// 初始长度为0
Node head;// 头节点
Node cur;// 当前结点
接下来说说单向链表的具体实现,无非就是增删改查,由于链表没有角标的概念并且是离散的,所以链表的读取性没有数组队列的优势。
1.增:在链表中添加新的数据
第一步创建一个新的节点接收数据
如果是空表,则直接让新的节点为头结点即可
第二步使尾节点(我这里是当前节点)指向新添加的这个节点
第三步链表长度加一
// 增
public void add(Object content) {
Node addnode = new Node(content);
if (head == null) {
// 如果头结点为空,则将当前结点和头结点均指向添加的新结点
head = addnode;
head.next = null;
cur = head;
} else {
// 如果链表不为空,则将当前结点指向添加的新结点
cur.next = addnode;
cur = cur.next;
}
size++;
}
2.删:删除分为三种情况,一是空表,删不了;二是从表中间删除元素,是让要删除的元素的前一个节点绕过要删的节点,指向要删除节点的下一个节点;三是删除尾节点,即让尾节点指向空;由于链表中的节点没有角标,故要找到要删除的节点需从头节点开始遍历链表,这里我用的是节点node。
//删
public void delete(int i) {
// 如果链表为空
if (size <= 0) {
System.out.println("错误");
}
// 删除头结点
else if (i == 1) {
head = head.next;
}
// 删除中间的元素或表尾
else if (i > 0 && i <= size) {
int a=0;
Node node=head;
if(i >= 0 && i <= size){
while (a<i-2) {
node = node.next;
a++;
}
node.next=node.next.next;
}else{
System.out.println("error");
}
}
}
3.查:在查找的方法中返回节点中存储的数据,从头节点开始遍历。
//查
public Object search(int i) {
Node node = head;
int a = 0;
if (i >= 0 && i <= size) {
while (a < i) {
node = node.next;
a++;
}
return node.data;
} else {
System.out.println("error");
return null;
}
}
4.改:同样是遍历,就不多说了。
//改
public void change(int i,Object update){
int a=1;//头结点中没有存储数据,故从1开始
Node node=head;
if(i>=0&&i<=size){
while(a<i){
node=node.next;
a++;
}
node.data=update;
}else{
System.out.println("error");
}
}
可以自己写一个测试类,测试自己的链表
public class Test {
public int index;
public String str;
public Test(int i,String s){
index=i;
str=s;
}
public static void main(String[] agrs){
Link link=new Link();
link.add("谢军华");
link.add("刘欣");
link.add("韩黎");
link.add("张依心");
link.delete(1);
//link.change(3,"贺雅婷");
link.print();
}
}