数据结构之链表增删改查实现方式(Java)

链表

链表是一种在物理上非连续、非顺序的数据结构,由若干个节点(node)所组成。

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

链表的第一个节点被称为头节点,最后一个节点被称为尾节点,尾节点的next指针指向空。链表是通过其中的next属性来确定下一个节点,来顺序存储。如图:

下面主要说一下单链表的增删改查的实现方式以及用Java实现单链表的增删改查功能。

查找节点

在查找元素时,链表不像数组那样可以通过下标快速进行定位,只能从头节点开始向后一个一个节点逐一查找。

例如给出一个链表,需要查找从头节点开始的第4个节点。

第一步,将查找的指针定位到头节点。

第二步,逐渐向后移动,直到找到目标节点。

只能按照顺序访问,所以最坏的时间复杂度是找到最后一个情况下,为O(n)。

更新节点

直接把旧数据换成新数据即可。

如图:

插入节点

链表插入节点时分为三种情况。

  1. 尾部插入
  2. 头部插入
  3. 中间插入

尾部插入把最后一个节点的next指针指向新插入的节点。

头部插入:

1、把新节点的next指针指向原先的头节点。

2、把新节点变成链表的头节点。

中间插入:

1、把插入位置的前置节点的next指针指向插入的新节点。

2、将新节点的next指针指向前置节点的next指针原先所指向的节点。

删除元素

链表的删除分为三种情况。

  1. 尾部删除
  2. 头部删除
  3. 中间删除

尾部删除,把倒数第2个节点的next指针指向空即可。

头部删除,把链表的头结点设为原先头节点的next指针即可。

中间删除,同样很简单,把要删除节点的前置节点的next指针,指向要删除的元素的下一个节点即可。

之前用C语言写过一个用单链表实现学生管理系统,这次的话就用Java实现以下简单的增、删、插功能。

//实现单链表的增、删、插
public class LinkList {
	//头指针
	private Node head;
	//尾指针
	private Node last;
	//链表实际长度
	private int size;
	
	/**
	 * 链表结点
	 */
	private static class Node{
		String data;
		Node next;
		Node(String data){
			this.data = data;
		}
	}
	/**
	 * 输出链表
	 */
	public void output(){
		Node temp = head;
		while(temp != null){
			System.out.println(temp.data);
			temp = temp.next;
		}
	}
	
	/**
	 * 链表插入元素
	 * @param data 插入元素
	 * @param index 插入位置
	 */
	public void insert(String 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 prevNode = get(index-1);
			Node nextNode = prevNode.next;
			prevNode.next = insertedNode;
			insertedNode.next = nextNode;
		}
		size++;
	}
	/**
	 * 链表删除位置
	 * @param index 删除的位置
	 */
	public Node remove(int index)throws Exception{
		if(index < 0 || index >size){
			throw new IndexOutOfBoundsException("超出链表范围");
		}
		
		Node removeNode = null;
		if(index == 0){
			//删除头结点
			removeNode = head;
			head = head.next;
		}else if(index == size){
			//删除尾结点
			Node prevNode = get(index-1);
			removeNode = prevNode.next;
			prevNode.next = null;
			last = prevNode;
		
		}else{
			//删除中间结点
			Node prevNode = get(index-1);
			Node nextNode = prevNode.next.next;
			removeNode = prevNode.next;
			prevNode.next = nextNode;
		}
		return removeNode;
	}
	/**
	 * 链表查找元素
	 * @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;
		}
		size--;
		return temp;
	}
	public static void main(String[] args) throws Exception {
		LinkList ll = new LinkList();
		ll.insert("你好", 0);
		ll.insert("我很好", 1);
		ll.insert("你呢", 2);
		ll.insert("我不好", 3);
		ll.insert("为什么呢", 1);
		ll.output();
		
		ll.remove(0);
		ll.output();
	}
}

 

关于单链表的操作就讲完了,但只是最简单的链表,还有双向链表和循环链表,操作也不是很难,在下次会说的。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值