关于链表的基本操作
单向/双向链表(可以根据每个节点回溯到前置节点)
prev | data | next |
---|---|---|
指向前一个节点 | 存储的数据 | 指向下一个节点 |
随机存储:每一个节点都可以分布在内存的不同位置,靠指针相互关联,有效利用了零散的碎片空间。
链表的查询
只能从头节点开始,向后一个一个节点逐一查询
/**
* 链表查询元素
* @param index 查找的位置
*/
public Node get (int index)throws Exception{
if (index<0||index>size){
throw new IndexOutOfBoundsException("超出链表节点范围");
}
Node temp= head;
for (int i = 0; i < index; i++) {
temp=temp.next;
}
return temp;
}
更新
先查询,然后将data中的数据更新成新数据
插入节点
- 尾部插入:将最后一个节点的next 指针,指向新节点
- 头部插入:将新节点的next 指针,指向原先的头节点,然后将新节点变为头节点
- 中间插入:新节点 next指针,指向插入位置的节点,然后插入位置前节点的next指针,指向新节点
/**
* 链表插入
* @param data 插入元素
* @param index 插入位置
*/
public void insert (int data,int index)throws Exception{
if (index<0||index>size){
throw new IndexOutOfBoundsException("超出链表节点范围");
}
Node insertedNode= new Node(data);
if (size==0){
//空链表
head=insertedNode;
last=insertedNode;
}else if (index==0){
//插入头部
insertedNode.next=head;
head=insertedNode;
}else if (size==index){
//插入尾部
last.next=insertedNode;
last=insertedNode;
}else {
插入中间
Node preNode=get(index-1);
insertedNode.next=preNode.next;
preNode.next=insertedNode;
}
size++;
}
删除节点和插入差不多
/**
* 链表删除元素
* @param index 删除的位置
*/
public Node remove(int index)throws Exception{
if (index<0||index>size){
throw new IndexOutOfBoundsException("超出链表节点范围");
}
Node removedNode=null;
if (index==0){
//删除头节点
removedNode=head;
head=head.next;
}else if (index==size-1){
//删除尾节点
Node prevNode= get(index-1);
removedNode=prevNode.next;
prevNode.next=null;
last=prevNode;
}else{
//删除中间节点
Node prevNode=get(index-1);
Node nextNode=prevNode.next.next;
removedNode=prevNode.next;
prevNode.next=nextNode;
}
size--;
return removedNode;
}