《算法通关村第一关-链表青铜挑战笔记》单链表的实现及其,增加,删除操作。

链表(linked list)是一种在物理上非连续的、非顺序的存储结构,由若干节点(Node)组成.

单向链表的每一个节点又包含两部分,一部分是该节点的数据变量data,另一部分是指向下一节点的指针next.

一、节点的实现

public class Node {
	private int data;
	private Node next;
	
	  public Node(int data) {//构造方法用于给节点赋值
		this.data=data;
	}

//set,get方法省略....
}

二、单链表的定义

链表的第一个节点被称为头节点,最后一个被称为尾节点,尾节点的next指针指向空。

与数组的下标寻址方式不同,在单链表中,我们要查找某一节点只能从头节点开始,根据next指针一个一个地往下找。

在jvm中有栈区和堆区,栈区主要存引用,也就是一个指向对象的实际地址,而堆区存的才是创建的对象

    单链表在堆,栈中的存在形式我们可以表示为:

在栈中其实只存在头节点,通过next指针去堆区依次找到各个节点。 

三、节点的插入

单链表中节点的插入分为3种情况:

(1)头部插入

1.先让新节点等于头节点

2.再让头节点等于新的节点

 (2)尾部插入

比较简单,直接让尾节点的next指向新节点即可

(3)中间插入

我们假设要插入的位置为insertNode 首先要找到insertNode的上一个节点,我们命名为preNode 

先让newNode的next指向preNode的next (即insertNode),

再让preNode的next指向newNode

注意 图中第2,3步 不能颠覆 (要是先执行第3步即 先让preNode的next指向newNode,那么从头节点开始就只能找到newNode了 ,insertNode开始的后面的节点将会从链表中脱离)

 四、节点的删除

节点的删除同样分为三种情况

(1)头部删除

令头节点head=head.next即可,原来的节点不可达会被jvm回收掉

(2)尾部删除

假设要删除的节点为removeNode,我们先找到removeNode的上一个节点命名为preNode

只要令preNode的next为 null ,没有外部引用指向的节点会被jvm自动回收。

(3)中间删除

假设要删除的节点为removeNode,我们先找到removeNode的上一个节点命名为preNode

首先令preNode的next 等于removeNode的next

再让removeNode的next为空

注意 ,同中间插入节点同理,图中2和3顺序不能颠覆。

具体代码实现如下:


public class ListNode {
	private Node head; // 头节点
	private Node last; // 尾节点
	private int size; // 链表长度

	// 获取链表长度
	public int getSize() {
		return size;
	}

	// 根据索引获取链表中相应的节点
	public Node getIndex(int index) {
		if (index < 0 || index >= size) { // 判断查询范围是否正常,注意加上index=size,当前链表为空时也能抛出异常
			throw new IndexOutOfBoundsException("超出链表节点范围!");
		}
		Node temp = head; // 定义临时变量,从头节点开始依次往下直到找到index位置的节点
		for (int i = 0; i < index; i++) {
			temp = temp.getNext();
		}

		return temp;
	}

	// 插入节点
	public void insert(int index, int data) {
		if (index < 0 || index > size) { // 判断插入范围是否正常
			throw new IndexOutOfBoundsException("超出链表节点范围!");
		}

		Node insertNode = new Node(data); // 定义插入节点(新节点)

		if (size == 0) {// 当前链表为空
			head = insertNode; // 则头节点,尾节点都是该节点
			last = insertNode;
		}

		else if (index == 0) { // 头部插入
			insertNode.setNext(head);
			head = insertNode;
		}

		else if (index == size) {// 尾部插入
			last.setNext(insertNode);
			last = insertNode;
		}

		else {
				// 其他情况均属于中间插入,注意2和3的顺序不能颠覆
		Node preNode = getIndex(index - 1); // 1.获取要插入位置的上一个节点
		insertNode.setNext(preNode.getNext());// 2.令新节点的下一个节点=preNode的下一个节点(该索引处的节点)
		preNode.setNext(insertNode);//3.preNode的下一个节点=新节点
		}
	
		size++; // 插入节点成功后,链表长度+1
	}
	
	//删除节点
	public Node remove(int index) {
		if (index < 0 || index >= size) { // 判断删除范围是否正常,注意加上index=size,当前链表为空时也能抛出异常
			throw new IndexOutOfBoundsException("超出链表节点范围!");
		}
		
		Node removeNode=null;//要删除的节点
		
		if(index==0) {//头部删除
			removeNode=head;//要删除的节点=head
			head=head.getNext();//head=head的下一个节点
			removeNode.setNext(null);
			
		}else if(index==size-1) {//尾部删除
			Node preNode=getIndex(index-1);//获取尾部节点的上一个节点
			removeNode=last;
			preNode.setNext(null);
			last=preNode;
			
		}else {
			//中间删除,注意3和4的顺序不能颠覆
		Node preNode = getIndex(index - 1); // 1.获取要删除位置的上一个节点
		 removeNode=getIndex(index);//2.获取要删除位置的节点
		preNode.setNext(removeNode.getNext());//3.preNode的下一个节点=要删除节点的下一个节点
		removeNode.setNext(null);//4.要删除节点的下一个节点=null
		
		}
		
		size--;// 删除节点成功后,链表长度-1
		return removeNode; //返回删除的节点
	}
	
	//输出链表
	public void output() {
		Node temp=head;
		while(temp!=null) {
			System.out.print(temp.getData()+"-->");
			temp=temp.getNext();
		}
	}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值