《算法通关村第一关——链表青铜挑战笔记》



一、链表是什么?

    链表是一种数据结构,它由一系列的节点组成,每个节点都包含一个值和一个指向下一个节点的指针。链表中的节点是通过指针连接起来的,在内存中的存储位置可以是任意的,不要求连续。链表可以用来存储和表示线性数据,例如列表、栈、队列等。相对于数组,链表的优势在于可以动态地分配和释放存储空间,而且插入和删除元素的操作效率较高。
在这里插入图片描述

二、链表的相关概念

1.节点和头节点

    在链表中,每个点都由值和指向下一个结点的地址组成的独立的单元,称为一个结点,有时也称为接点。
    对于单链表,如果知道了第一个元素,就可以通过遍历访问整个链表,因此第一个结点最为重要,一般称为头结点。

2.虚拟结点

    虚拟结点的概念其实就是一个结点dummyNode,其next指针指向head,也就是dummyNode.next=head.所以,当我们在算法里使用了虚拟结点,则要注意如果要获得head结点,应使用dummyNode.next.虚拟结点的作用主要是方便处理首部结点,否则就需要在代码里单独处理首部结点问题。


三、创建链表

/**
 * 创建链表
 * @author json-zhang
 */
public class ListNode {
    private  int index;
    private ListNode next;

   
   ListNode(int x){
       index=x;
       next=null;
   }
    ListNode listNode=new ListNode(1);
}

这里的index是当前节点的值,next存放的是下一个节点的地址。

四、链表的增删改查

1.遍历链表,获取链表长度

对于单链表,一定是从头结点开始,逐个向后访问。
在这里插入图片描述

/**
 * 遍历链表,获取链表长度
 * ListNode  head 头结点
 */
public static int getListLength(ListNode head){
    int length=0;
    //创建头结点
    ListNode listNode=head;
    //当节点不为空时执行循环
   while(listNode !=null){
    //节点不为空,长度+1
    length++;
    //listNode指向当前节点的下一个节点
    listNode=listNode.next;
   }
   //循环结束返回遍历的链表长度
   return length;
}

2.链表的插入

单链表的插入分为头部,尾部和中部三种情况。

2.1 链表的头部插入法

    1.创建一个新结点newNode
在这里插入图片描述

    2.将新结点和头结点挂接,newNode.next=head
在这里插入图片描述
    3.新结点成为头结点,依次往下一个结点遍历,链表插入元素完成,head=newNode
在这里插入图片描述

/**
 * 头插法
 * ListNode head  头结点
 * ListNode node 要插入的结点
 * int index  要插入的位置
 */
public static ListNode insertListNode(ListNode head,ListNode node,int index){
    //判断头结点是否为空
    if(head ==null){
        //为空,则直接返回要插入的节点(即插入的结点就是头结点)
        return node;
    }
    //获取链表的长度size
    int size=getListLength(head);
    //判断要插入的位置是否合法
    if(index>size+1 ||index<1){
        //位置不合法,则直接返回头结点
        return head;
    }
    if(head!=null){
        node.next=head;
        head=node;
        return head;
    }
    return head;
}

头插法需要注意的是重新将插入的结点作为新的头结点,因为链表是从头结点往后依次遍历。且头插法会改变链表的原有顺序

2.2 链表的尾部位置插入法

    将尾结点指向新结点
在这里插入图片描述

尾部插入不会改变链表的原有顺序

2.3 链表的中部位置插入

    1.先遍历找到插入的位置
    2.将插入结点挂载到要插入位置的前一个结点的后继结点上。
在这里插入图片描述
    3.将插入结点挂载到要插入位置的前一个结点。
在这里插入图片描述
完整的链表插入代码

/**
 * 链表插⼊
 * @param head 链表头节点
 * @param node 待插⼊节点
 * @param index 待插⼊位置,从1开始
 * @return 插⼊后得到的链表头节点
 */
public static ListNode insertNode(ListNode head,ListNode node , int index) {
 //判断头结点是否为空
 if (head == null) {
    //为空,则直接返回要插入的节点(即插入的结点就是头结点)
 	return node;
 }
 //获取链表的长度size
 int size = getListLength(head);
//判断要插入的位置是否合法
 if (index > size+1 || index < 1) {
 	 //位置不合法,则直接返回头结点
 	return head;
 }
 // 表头插入
 if (index == 1) {
 	node.next = head;
	head = node;
 	return head;
 }
 ListNode currentNode = head;
 int count = 1;
 while (count < index - 1) {
 	currentNode = currentNode.next;
 	count++;
 }
 node.next = currentNode.next;
 currentNode.next =node;
 return head;
}

node.next = currentNode.next;
currentNode.next =node;
顺序不能颠倒,否则就没有办法找到插入位置的前一个结点的后继结点的位置

总结

 以上就是我关于链表学习过程中的认识,希望能够帮助大家更好的认识链表,也欢迎大家留言。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值