单链表:
链表是一种在物理上非连续,非顺序的数据结构,由若干节点(Node)组成。
单链表的每一个节点又包括两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。
public class Node {
int data; //data存放数据
Node next; //存放下一个节点信息
}
下面是单链表的增删改查操作
1、查找节点
例如查找下图的第三个节点
第一步:将查找的指针(可以自己定义一个Node类型的temp)指向头节点(head)
第二步:根据头节点的next指针,定位到第二个节点
第二步:根据第二个节点的next指针,定位到第三个节点
2、插入节点,插入节点有三种情况:头部插入、尾部插入、中间插入
头部插入:
第一步:将插入节点的next指针指向原先的head节点
第二步:把新插入的节点变成头节点head
尾部插入:
将链表的最后一个节点的next指针指向新插入的节点,然后将新插入的节点变成尾节点last
中间插入:
第一步:将插入节点的next指针指向插入位置的节点
第二步:插入位置的前一个节点的next指针指向要插入的节点
3、删除节点:删除节点有三种情况:头部删除、尾部删除、中间删除
头部删除:
将头节点设置成原先头节点的next指针即可
尾部删除:
将倒数第二个节点的next指针设置为NULL即可
中间删除:
将删除节点的前一个节点的next指针指向要删除节点的下一个节点
更新节点:直接将旧数据替换成新数据即可
实现代码:
package linkList;
public class Linklist {
private Node last;//尾节点
private Node head;//头节点
int size = 0;
//链表结构
public class Node {
int data; //data存放数据
Node next; //存放下一个节点信息
public Node(int data) {
this.data = data;
}
}
//删除函数
public void delete(int index){
if(index<0||index>size-1){
System.out.println("删除链表节点下表越界");
}
Node deleteNode=null;/*获取删除的节点,此处就是为了获取要删除的节点而设置的,可以没有*/
//删除头节点
/*
* 把链表头节点head(设置为)指向原链表头节点的next指针
* */
if(index==0){
deleteNode=head;/*获取删除的头节点*/
head=head.next;
/**
*删除尾节点,把倒数第二个节点的next指针指向空即可
*/
}else if(index==size-1){
deleteNode=getNode(index);/*获取删除的节点*/
Node preNode=getNode(index-1);
preNode.next=null;
last=preNode;
}
/*
* 删除中间节点
* 把要删除的节点的前置节点的next指针,指向要删除节点的下一个节点
* */
else{
Node preNode=getNode(index-1);
Node nextNode=preNode.next.next;
deleteNode=preNode.next;/*获取删除的节点*/
preNode.next=nextNode;
}
size--;
}
//插入函数
public void insert(int index, int data) {
if (index < 0 || index > size) {//注意下标可以超出一位,以便插入到链表位节点
System.out.println("插入链表下标越界");
}
Node insertNode=new Node(data);
//插入时链表大小为0
if(size==0){
head=insertNode;
last=insertNode;
}
//在头节点位置插入
else if(index==0){
insertNode.next=head;
head=insertNode;
}
//在链表尾部插入
else if (index==size){
last.next=insertNode;
last=insertNode;
}else{
//链表中间插入
Node nowNode=getNode(index);
Node preNode=getNode(index-1);
insertNode.next=nowNode;
preNode.next=insertNode;
}
size++;
}
//根据索引获取链表节点
public Node getNode(int index){
if (index<0||index>size-1){
System.out.println("获取节点下标越界");
}
Node temp=head;
if(temp!=null){
for (int i=0;i<index;i++){
temp=temp.next;
}
}
return temp;
}
//打印链表
public void printLink(){
Node temp=head;
while(temp!=null){
System.out.print(temp.data+" ");
temp=temp.next;
}
}
//主函数
public static void main(String[] args) {
Linklist linklist=new Linklist();
linklist.insert(0,1);
linklist.insert(1,2);
linklist.insert(2,3);
linklist.insert(1,4);
linklist.insert(4,5);
linklist.insert(0,6);
System.out.println();
linklist.printLink(); System.out.println();
System.out.println("--------------------");
linklist.delete(4);
linklist.printLink();
}
}
tips:
文章提到的指向,例如将指向要删除节点的下一个节点 ,其实就是将要删除节点的下一个节点的地址值赋值给删除节点的前一个节点的next指针