算法通关村第一关----链表的青铜挑战笔记

本文介绍了链表的基本概念,包括单链表、双向链表和循环链表的结构,以及如何使用Java实现链表的创建、插入和删除操作。详细讲解了插入和删除节点的方法,涉及空指针处理和链表头结点、尾结点的特殊处理。
摘要由CSDN通过智能技术生成

1.什么是链表

什么是链表 链表一种线性的数据结构,将多个结点连接起来,每个结点都存在一个指向下一个结点的next指针。如若是单向列表的话,最末端的那个结点的next指针则指向null;如若是循环链表,最末端结点的next指针则指向head头结点。

2.链表的分类

单链表
在这里插入图片描述

  • 单链表的每个结点除了存储数据data外,还需要记录下个结点的地址,称为后继指针next。

双向链表
在这里插入图片描述

  • 双向链表的每个结点在单链表的基础上增加了前驱指针prev,指向上一个结点。

循环列表

![[Pasted image 20231126171010.png]]

  • 循环链表仅仅是将单链表最末端的尾结点从指向null改成指向头结点head,进而实现了一个类似环形的结构。

3.创建链表

public class ListNode {  
	// 节点的值  
	public int val;  
	// 下一个节点  
	public ListNode next;
	
	// 有参构造函数
	public ListNode(int val) {  
		this.val = val;  
	}  
	
	//下面的是结点的get,set方法
	public int getVal() {  
		return val;  
	}  
	public void setVal(int val) {  
		this.val = val;  
	}  
	public ListNode getNext() {  
		return next;  
	}  	  
	public void setNext(ListNode next) {  
		this.next = next;  
	}

}

4.链表的插入

  • 如果插入的位置position = 1,则只需将新建结点new的next指针指向当前head所指向的结点,再将head指向新建结点,使得新建结点new变成头结点。

  • 如果插入位置position > 1,要先遍历链表到当前position的前一个结点,先要将new结点的next指针指向位于position位置的结点,再将前一个结点的next指针指向新建的new结点,从而使得整个链表重新链接起来。由于java的new Node结点后,改结点的next指针会自动置为null值。所以如果插入的位置是末尾的话,只需遍历到尾结点,后将其的next指针指向new的新结点即可。

/**  
* 链表插入  
*  
* @param head 链表头节点  
* @param nodeInsert 待插入节点  
* @param position 待插入位置,取值从2开始  
* @return 插入后得到的链表头节点  
*/  
public static Node insertNode(Node head, Node nodeInsert, int position) {  
	// 需要判空,否则后面可能会有空指针异常  
	if (head == null) {  
		return nodeInsert;  
	}  
	//越界判断  
	int size = getLength(head);  
	if (position > size + 1 || position < 1) {  
		System.out.println("位置参数越界");  
		return head;  
	}  
	  
	//在链表开头插入  
	if (position == 1) {  
		nodeInsert.next = head;  
		// return nodeInsert;  
		//上面return还可以这么写:  
		head = nodeInsert;  
		return head;  
	}  
	  
	Node pNode = head;  
	int count = 1;  
	while (count < position - 1) {  
		pNode = pNode.next;  
		count++;  
	}  
	nodeInsert.next = pNode.next;  
	pNode.next = nodeInsert;  
	  
	return head;  
}

5.链表的删除

  • 删除头结点
    在这里插入图片描述

    • 删除头结点只需将head指针指向当前头结点的next,原本的结点由于访问不到,则会被JVM回收释放掉。
  • 删除尾结点
    在这里插入图片描述

    • 遍历链表,找到尾结点的前驱结点,直接将前驱结点的next指针指向null即可。原本的尾结点也会由于访问不到,被JVM回收。
  • 删除中间结点
    在这里插入图片描述

    • 也是遍历链表,找到要删除的结点的前驱结点,将前驱结点的next指针指向要删除结点的next即可。
/**  
* 删除节点  
*  
* @param head 链表头节点  
* @param position 删除节点位置,取值从1开始  
* @return 删除后的链表头节点  
*/  
public static Node deleteNode(Node head, int position) {  
	if (head == null) {  
		return null;  
	}  
	int size = getLength(head);  
	//思考一下,这里为什么是size,而不是size+1
	//这里如果是size+1的话,那么position就可以取到size
		//后面cur就会为尾结点,使得curNode为尾结点指向的null
		//当调用curNode.next时则会出现空指针异常
	if (position > size || position <1) {  
		System.out.println("输入的参数有误");  
		return head;  
	}  
	if (position == 1) {  
		//curNode就是链表的新head  
		return head.next;  
	} else {  
		Node cur = head;  
		int count = 1;  
		while (count < position - 1) {  
			cur = cur.next;  
			count++;  
		}  
		Node curNode = cur.next;  
		cur.next = curNode.next;  
	}  
	return head;  
}
  • 13
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值