写一个大家都比较熟悉的数据结构:单向链表。
不过先告诉大家一个小秘密,java的API里面已经提供了单向链表的类,大家可以直接拿来用,不过学习数据结构课程的时候想必大家也已经知道,虽然系统会给我们提供一些常用的数据结构,但是自定义的总是能够带来不同的喜感的,而且通过自己的编写也更能够让我们了解其中实现的过程,而且我们还可以写一些比较个性化的方法作为属于自己的数据结构。这里主要是介绍一些常用结构里面都会用到的方法,以及链表具体是如何操作的。
首先,单链表相对于队列的优势在于存储地址不是连续的,这样的意义在于,操作其中的某一个位置的元素时不需要对之前的其他元素都进行内存操作,大大的为我们的计算机减压了。下面直接进入正题:
先要定义一个结点类,如下:
public class Node { Node next;//下一个结点的引用 Object obj;//结点元素 public Node(Object obj){ this.obj=obj; } }
然后就是我们的LinkedList类,先要定义一个空链表:
Node head=null;//创建一个空链表,头结点
Node last=head;//尾结点
打印链表有两种方法,可以采用递归,也可以使用非递归的方法,如下:
/** * 非递归打印元素的方法 */ public void print(Node head){ while(head!=null){ System.out.println(head.obj); head=head.next;//索引向后移位 } } /** * 递归打印链表元素的方法 */ public void printNode(Node head){ if(head!=null){ System.out.println(head.obj); Node node=head.next; printNode(node);//递归调用 } }
非递归方法有一个致命的缺陷,打印的同时改变了头结点的位置,所以我们应该倾向于使用递归方法。
说了这么多,增删查改正式开始:
向链表中添加元素。判断一个链表已经到达末尾的依据是该结点的next引用已经为Null,所以要向末尾添加一个结点,先要把新增结点放在最后,再把末尾结点向后移位,具体操作过程如下图:
代码如下:
/** * 向指定链表添加元素的方法 * @param obj 插入的元素 */ public void add(Object obj){ Node node=new Node(obj);//新建结点 if(head==null){//如果链表为空 head = node; }else{ last.next=node;//先把新增结点放在最后 } last=node;//再把最后一个结点向后移位 }
插入元素。要插入一个新元素首先要创建一个新结点来存放它,而在具体实现的时候最让人头疼的时候无疑是怎样找到指定位置的索引了,这里所说的方法在下面的其他操作基本上都是这样衍生的,先了解一下插入结点的具体实现,根据这个结构的逻辑定义,如果我们要在结点A之后插入一个结点,那么就还需要修改结点A的next引用,实际上就是让A结点的next引用指向新增结点的元素域,然后再让新增结点的next引用指向A原本next结点(B)的元素域,用图来表示更加直观:
代码如下:
/** * 向链表中插入新元素的方法 */ public void insert(int index,Object obj){ Node node=head; int j=0; while(node!=null&&j<index-2){ //查找到第index-1个元素 node=node.next; j++; } Node sert=new Node(obj);//被插入的结点 sert.next=node.next; node.next=sert; }
删除元素。知道了插入元素的具体操作之后,删除元素就显得相对简单了,比如说我们要删除一个结点b,就是要使这个结点失去引用,但是注意不要直接写b=b.next,这样的话b的引用还是存在,而且还会出现另一种错误,大家可以自己试一下,如图所示,正确的删除结点的方法如下:
代码如下:
/** * 删除指定位置的结点 * @param index 索引 */ public void delete(int index){ Node node=head; int j=0; while(node!=null&&j<index-2){ //查找到第i-1个元素 node=node.next; j++; } node.next=node.next.next;//删除第index个元素 }
最后就是修改元素了。相信大家看完之前的两个方法,接下来的这个方法在心中早就已经泛起波澜了吧,那下面就直接贴代码了:
/** * 改变指定位置的元素 * @param index 索引 * @param obj */ public void modify(int index,Object obj){ Node node=head; int j=0; while(node!=null&&j<index-1){ //找到第index个结点 node=node.next; j++; } node.obj=obj; }
当然,除了这些基本操作,我们还可以写获取链表长度的方法,获取指定位置的元素的方法等等,这里就不一一介绍了,主要是让大家熟悉一下这个数据结构。最近一阵学校课程太多,心里有很多想法却一直开不了口啊,慢慢来吧,学习也不是一天两天的事情,这几天都没搞锻炼了,今天在教室考试的时候就有人突然癫痫犯了,做技术的更应该关注自己的身体,加油。。。
相关推荐
链表的增删查改等基本功能实现代码有注释
c语言数据结构链表的增删查改功能,很简单的
代码主要实现了顺序表 链表 双链表的增删查改操作及链表逆置等常用线性表算法
利用结构体数组和链表完成增删查改,包括统计个人支出和整月支出,按日期支出等功能。没有特别复杂的数据结构,适合刚学习结构体和链表的学生练手。
C语言 双向循环链表,增删查改,判断回文,排序,论文,代码,自写可用,vs2013,课程设计,答辩
人工智能-项目实践-信息管理系统
有关单向链表的增删改查,对于单向链表的插入,在固定节点后面插入分为四种情况
单向循环链表实现约瑟夫环.zip
对于java初学者,增删改查功能,还有图片上传,excel上传的功能
04.单向链表以及单向链表的应用.ppt
实习四、线性表(链式存储)及其应用...问题:建立一个采用链式存储的线性表,表中元素为学生,每个学生信息包含姓名、学号和成绩三部分,对该表实现:①输出、②查找、③插入、④删除功能,并计算出平均成绩和总成绩。
1.随机产生或键盘输入一组元素,建立一个带头结点的单向链表(无序)。 2.遍历单向链表。 3.把单向链表中元素逆置(不允许申请新的结点空间)。 4.在单向链表中删除所有的偶数元素结点。 5.编写在非递减...
VC 单向链表 双向链表的例子,一个很早的VC 代码了,用来演示如何创建链表和双向链表,供感兴趣的朋友参考吧。以下是部分代码: list.RemoveAll(); list.Insert(0,1); list.Insert(1,2); list.Insert(2,3); ...
以下是本人完成的一个C语言建立链表并进行增删查改操作的程序,为方便学习,本人将整个程序分为头文件和主函数两部分: 1.头文件(函数部分) (1)初始化函数 #include #include typedef struct { int *head; int...
链表的增删改插.zip
Dlephi链表实现栈操作..rar
单向链表类定义及测试文件 对应于数据机构与算法分析(c++版)第三版或第二版 作者Clifford A.Shaffer 重庆大学使用教材
简单的单向链表,增删查改练习。简单的二叉树练习,适合初学者,简单易懂,非常实用。VS2015工程,可以直接运行。