链表添加、删除、插入、修改、查找和单链表逆置

链表的5种操作及单链表逆置

鉴于本人对写作真的没有任何兴趣,从小学开始写作文完全是凑字数,写小说也半途而废,所以从这篇文章开始我要放飞自我,怎么开心怎么写,不要严肃,要沙雕。(突然发现居然有人会看我的文章,为了不误人子弟,我决定痛改前非,好好写!!!)

为什么有链表

众所周知,我们平时最爱用数组存储数据,那么为什么还有链表这个东西呢??让我们来看看链表是什么?数组和链表有什么区别。
在这里插入图片描述
数组和链表都可以用来存储数据,但是二者在内存中存储数据的空间形式有很大区别。
数组的存储空间连续的,不可更改的
在这里插入图片描述
但是链表就不同了

在这里插入图片描述
又称
在这里插入图片描述
链表灵活随意的存储方式注定了链表的存储难度远低于数组,他更优秀的地方在于,他的各种操作真的很方便,也就是代码真的很少。
先给大家展示一下链表的样子

链表,有节点和节点间的联系(也就是链表中的那条链子),节点又分数据域和引用域,数据域用来存储链表中的数据,引用域用来记录下一个节点的存储位置(就是那条链子)
在这里插入图片描述
在这里插入图片描述
节点的种类分为,头结点和尾节点,和普通节点,尾节点最后要指向空。

接下来,我将结合代码,像大家讲一下链表各项功能的实现以及链表他到底方便在哪里
在这里插入图片描述

前提所需

在c语言中,链表的实现靠结构体和指针,但是这些东西java里通通没有,通通没有!!所以,用Java怎么实现呢??
我们要用
首先我们来根据链表的特性建两个类(为了大家方便复制代码【虽然我觉得有人疯了才会复制我的代码】,也为了满足我想敲键盘的快感,我会打很多代码的)。
一个是Node类,来封装节点的属性,一个是Linked类,实现链表功能

public class Node<E>{		//这里,我们要用到泛型,因为不知道会存进来什么样的数据
			public E e;		//数据域中的数据
			public Node<E>  next;		//这个就是最重要的那个链,记住下一个节点的位置,就是那个箭头,又称后继
			public Node<E>(){}
			public Node<E>(e){
				this.e=e;
				}
		public class LInked<E>{
		public Node<E>  root;	//声明一个头结点
		public Node<E> tail;	//声明一个尾节点
		int size;	//定义链表的大小
		public Linked(){
			root=new Node<E>();		//实例化头结点
		}

功能一,添加

	将传入的数据加入整个链表的末尾
		public void add(E e){	//传入一个数据
			Node<E> node=new Node<E>(e);	//生成一个以e为数据的节点
			if(root.next==null){		//此时链表为空,只有头结点(头结点内没有数据)
			root.next=node;	//让头结点的后继变为新生成的node这个节点,也就是让root的箭头指向node
			tail=node;	//让新生成的node节点变成尾节点
			size++;		//链表大小加一
			}
			else{
			tail.next=node;		//让尾节点的后继变为node
			tail=node;			//node变成心得尾节点
			size++;
			}

在这里插入图片描述
(在这里我不得不感叹我的数据结构老师真的教的太好了,很可惜人家回去生宝宝了,一定是一个很温柔的宝宝,随妈妈!)
在这里插入图片描述

删除

删除链表中的任意一个节点,并返回删除元素的值

	public E remove(int index){		//传过来一个想删除的位置
		E e=null;	//先声明一个e,设为null
		if(index<0||index>size)	//第一种情况,删除的位置比零小,比链表的长大
			return e;
		else if(index==size-1)	{//第二种情况,删除尾节点
			Node<E> node=new Node<E>(e);	//先生成一个新的节点,用于记录尾节点的值
			e=tail.e;	//获取尾节点的值
			Node<E> periodnode=new Node<E>(e);	//再生成一个节点,用于获取被删节点的前一个节点
			periodnode=getNode(index-1);//获取前一个节点,getNode是返回当前操作的节点,之后给出代码
			periodnode.next=null;//将被删节点的前一个节点的后继设为空,即设为尾节点,原先的尾节点因为没有引用,java自动将其删除
			size--;
			}
			else if(index==0){		//第二种情况,删除第一个节点
			Node<E> node =new Node<E>(e);		//生成一个新的节点,用于记录被删节点的值
			node=getNode(index);		//获取被删节点
			e=node.e;		//获取被删节点的值
			root.next=node.next;	//根节点的后继指向被删节点的后继
			node.next=null;	//被删节点的后继置为null,被java自动删除
			size--;
			return e;
		}else{		//第三种情况,删除任意一个节点
			Node<E> node=new Node<E>(e);		//生成一个节点,用于记录被删节点的值
			node=getNode(index);		//获取被删节点
			Node<E> periodnode=new Node<E>(e);	//在生成一个节点
			periodnode=getNode(index-1);		//获取被删节点的前一个节点
			Node<E> nextnode=new Node<E>(e);		//再生成一个节点
			nextnode=node.next;		//获取被删节点的后一个节点
			e=node.e;		//获取被删节点的值
			periodnode.next=node.next;		//让被删节点的前一个节点的后继指向被删节点的后一个节点,即被删节点的前一个节点的后继指向被删节点的后继,即断开被删节点和前一个节点的联系
			node.next=null;		//被删节点置为空,即断开被删节点和后一个节点的联系
			size--;
			return e;
		}
		}

在这里插入图片描述
在这里插入图片描述

插入

将元素插入到任意一个位置

	public void put(E e,int index){
		if(index!=1){
			Node<E> newnode=new Node<E>(e);     //生成一个新的节点,把他加进去
			Node<E> periodnode=getNode(index-1);	//再生成一个节点,记录想加位置的前一个节点
			Node<E> node=getNode(index);		//再生成一个节点,记录想加位置的节点
			newnode.next=node;		//要加进去的新节点的后继指向已存在的在原位置的节点
			periodnode.next=newnode;	//想加位置的前一个节点的后继指向新节点
				size++;
			}
			else{
				Node<E> newnode=new Node<E>(e); 	//当想加入头结点后,同理
				Node<E> node=getNode(index);
				newnode.next=node;
				root.next=newnode;
				size++;
		}
	}
	

在这里插入图片描述

查找

查找任意一个值

public Node<E> getNode(int index) {      //返回当前要操作的节点
		Node<E> node = root.next;
		for (int i = 0; i < index; i++) {
			node=node.next;
		}
		return node;
	}
	
	public E get(int index){    //一个简单的循环即可
		E e=null;
		Node<E> node=new Node<E>(e);
		node=getNode(index);
		return node.e;
	}

修改

修改任意一个值

public Node<E> getNode(int index) {//返回当前要操作的节点
		Node<E> node = root.next;
		for (int i = 0; i < index; i++) {
			node=node.next;
		}
		return node;
	}
	
	public void change(int index,int a){
		E e=null;
		Node<E> node=new Node<E>(e);
		node=getNode(index);
		node.e=a;
	}

单链表逆置

敲到这里,真心觉得,认真作一篇博客好累。
在这里插入图片描述
接下来就是链表逆置,挺经典的一道题,加油!!!
链表逆置就是把1234567变成7654321。又将是死亡的作图过程。

public void backput(){
		E e=null;
		Node<E> pnode=new Node<E>(e);		//设置一个节点pnode			
		Node<E> qnode=new Node<E>(e);		//设置另一个节点qnode
		pnode=root.next;		//让根节点的后继指向pnode
		root.next=null;		//根节点后继置为空
		while(pnode!=null){		//pnode不空
			qnode=pnode.next;		//pnode的后继指向pnode
			pnode.next=root.next;		//根节点后继指向pnode的后继
			root.next=pnode;		//看图吧
			pnode=qnode;		//看图吧
		}
	}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
代码中还有各位需要注意的index从零取这种小问题,这篇文章到此结束啦
画图真的太死亡了,希望那些点进我的博客的人能对你们有一些用处
啦啦啦啦啦啦,我是哈哈哈哈哈士奇,我们下期再见(应该不会有了吧)!
在这里插入图片描述

发布了22 篇原创文章 · 获赞 2 · 访问量 5457

猜你喜欢

转载自blog.csdn.net/qq_43135849/article/details/85037970