java定义链表_Java实现单链表

本文详细介绍了单链表的概念及其在Java中的实现,包括如何使用类和对象来表示结点和链表,实现了单链表的基本操作如初始化、销毁、清空、检测空、获取元素个数、查找元素等。此外,还讨论了单链表的优化方案,即通过内部类仅让头结点拥有操作其他结点的能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、分析

单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点由元素和指针构成。在Java中,我们可以将单链表定义成一个类,单链表的基本操作即是类的方法,而结点就是一个个实例化的对象,每个对象中都有“元素值”和“下一结点地址”两个属性。在“下一结点地址”属性中存储的是下一个对象的引用,这样,一个个对象连在一起就成为了单链表。

单链表有以下基本操作:

1、初始化单链表

2、销毁单链表

3、清空单链表

4、检测单链表是否为空

5、返回单链表的元素个数

6、返回单链表中指定位置元素的值

7、返回单链表中第一个与指定值相同的元素的位置

8、返回指定元素的直接前驱

9、返回指定元素的直接后继

10、向指定位置插入元素

11、删除指定位置的元素

12、遍历单链表

为了方便对单链表进行操作,我们还需要引入一个头结点,头结点中不存储元素值,只存储单链表第一个结点的地址。初始化单链表即创建头结点,而销毁单链表即销毁头结点。

二、实现

1、定义类属性和构造函数

1 classInitList{2

3 private int [] data = new int[1]; //用来存储元素值,之所以用数组而不用整型,是为了用null来表示头结点

4

5 private InitList nextList;      //下一结点地址

6

7 public InitList() {         //创建头结点的构造函数

8 this.data = null;9 this.nextList = null;10 }11

12 public InitList(int data) {      //创建普通结点的构造函数

13 this.data[0] =data;14 this.nextList = null;15 }16 }

2、清空单链表

1 public voidclearList() {2 this.nextList = null;         //将头结点的下一结点地址(即单链表的第一个结点的地址)置空,则单链表会因缺少引用而被jvm回收,实现清空

3 }

3、检测单链表是否为空

1 public booleanlistEmpty() {2 if(this.nextList == null) {      //通过判断头结点的下一结点地址是否为空,即可判断单链表是否为空

3 return true;4 }5 return false;6 }

4、返回单链表的元素个数

1 public intlistLength() {2

3 InitList theList = this.nextList;       //获取头结点的下一结点地址

4 int i = 0;                //计数器初始化

5

6 for (i = 0; theList != null; i++) {      //循环判断结点地址是否为空,如果不为空,则表明存在结点,计数器i加一;如果为空,则表明已到达单链表尾部,退出循环

7 theList = theList.nextList;       //取下一结点进行判断

8 }9 return i;                     //返回计数器的值

10 }

5、返回单链表中指定位置元素的值

1 public int [] getElem(intsite) {2

3 if(site < 1) {              //判断输入的位置是否合法

4 return null;5 }6

7 InitList theList = this;         //得到头结点的地址

8

9 for (int i = 0; i < site; i++) {     //循环读取结点,直到指定的位置

10 theList = theList.nextList;      //获取下一结点的地址

11 if(theList == null) {          //如果下一结点地址为空,则表明已经到达单链表末尾,指定的位置超出了单链表的长度

12 return null;              //未取到元素,返回null

13 }14 }15 return theList.data;            //返回指定位置元素值

16 }

6、返回单链表中第一个与指定值相同的元素的位置

1 public int locateElem(intvalue) {2

3 InitList theList = this.nextList;

4

5 for(int i = 1; theList != null; i++) {    //如果取得的结点不为空,执行循环

6 if(theList.data[0] == value) {       //比较结点值与给定的值是否相等

7 return i;                //相等返回结点位置

8 }9 theList = theList.nextList;        //取下一结点地址

10 }11

12 return 0;                     //未找到则返回零

13 }

7、返回指定元素的直接前驱

1 public int [] priorElem(intvalue) {2

3 InitList theList = this.nextList;4

5 if(theList == null) {                   //如果头结点的下一结点为空,则表明单链表为空,返回null

6 return null;7 }8

9 InitList theNextList = this.nextList.nextList;    //获取单链表的第二个结点

10 int [] ret = new int[this.listLength()];        //创建一个与单链表长度相同的数组,用来存储找到的直接前驱的值

11 int i = 1;                          //计数器

12

13 while (theNextList != null) {               //因为单链表的第一个结点没有直接前驱,因此从第二个结点开始循环

14 if(theNextList.data[0] == value) {        //如果与给定值相等,则取得其前驱,计数器加一

15 ret[i] = theList.data[0];16 i++;17 }18 theList = theNextList;               //取下一地址,准备下一循环

19 theNextList =theNextList.nextList;20 }21

22 if(i == 1) {                       //i为1表明未取到直接前驱

23 return null;24 }25

26 ret[0] = i - 1;                     //将计数器的值存入数组第0位

27 returnret;28 }

8、返回指定元素的直接后继

1 public int [] nextElem(int value) {             //与获取直接前驱类似,这里不再赘述

2

3 InitList theList = this.nextList;4

5 if(theList == null) {6 return null;7 }8

9 InitList theNextList = this.nextList.nextList;10 int [] ret = new int[this.listLength()];11 int i = 1;12

13 while (theNextList != null) {14 if(theList.data[0] ==value) {15 ret[i] = theNextList.data[0];16 i++;17 }18 theList =theNextList;19 theNextList =theNextList.nextList;20 }21

22 if(i == 1) {23 return null;24 }25

26 ret[0] = i - 1;27 returnret;28 }

9、向指定位置插入元素

1 public boolean listInsert(intsite,int value) {2

3 if(site < 1) {                       //判断指定位置是否合法

4 return false;5 }6

7   InitList list = new InitList(value);

8 InitList theNextList = this;9 InitList theList = null;10

11 for(int i = 0; i < site; i++) {             //循环读取到指定位置

12 theList =theNextList;13 if(theList == null) {                //如果为空,表示已到单链表末尾,返回false

14 return false;15 }16 theNextList =theNextList.nextList;17 }18

19 list.nextList = theNextList;                //将新结点插入指定位置中

20 theList.nextList =list;21 return true;22 }

10、删除指定位置的元素

1 public boolean listDelete(intsite) {2

3 InitList theList = this;4 InitList theNextList = this.nextList;5

6 if(site < 1 || theNextList == null) {       //判断指定位置是否合法和单链表是否为空

7 return false;8 }else if(site == 1) {                  //如果要删除的是第一个结点,则直接删除

9 theList.nextList =theNextList.nextList;10 return true;11 }12

13 for(int i = 1; i < site; i++) {            //循环读取到指定位置

14 theNextList =theNextList.nextList;15 if(theNextList == null) {16 return false;17 }18 theList =theList.nextList;19 }20

21 theList.nextList = theNextList.nextList;      //删除指定位置的结点

22 return true;23 }

11、遍历单链表

1 public String traverseList() {         //这里通过输出单链表来表示遍历

2

3 InitList theList = this.nextList;4 String s = "";                //用来存储单链表的值

5

6 while(theList != null) {           //循环获取结点值

7 s += theList.data[0] + "、";8 theList =theList.nextList;9 }10

11 if(s.length() == 0) {            //如未获取到值,直接返回s

12 returns;13 }14

15 return s.substring(0,s.length() - 1);  //去除最后的顿号后返回

16 }

三、小结

以上就是单链表用Java的实现,由于只定义了整数的数组,因此只能操作整数数据,但单链表的基本思想都已实现。

四、纠正

隔了一段时间又回来看代码,猛地发现这段代码其实还不够完善。(⊙x⊙;)

将单链表的基本操作定义成了InitList类的方法,实例化结点时,会使每个结点都拥有这些方法,然而其实只有头结点需要这些方法,其他结点都不需要。

因此可以将InitList类定义成头节点类,而其他节点定义成头节点的内部类,这样,就只有头节点可以操作其他节点。

由于要修改的地方太多,这里我就不修改了,放在这里提醒自己。(就是因为懒……(><))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值