java线性表 示例_线性表结构的Java实现

本文介绍了Java中线性表的抽象数据类型,包括顺序存储和链式存储的实现。顺序存储使用ArrayList和LinkedList,特点是随机访问快但插入删除效率低。链式存储分为单链表,其特点是动态分配空间,插入删除操作高效但查找慢。文章提供了顺序存储类SqList和链式存储类LinkList的详细代码实现。
摘要由CSDN通过智能技术生成

一、线性表的抽象数据类型表述

线性表的结构简单,长度允许动态增长或搜索;可以对线性表中的任何数据元素进行访问和查找;允许进行数据的插入和删除操作;求线性表中的指定数据的前驱和后继;合并线性表以及拆分线性表中。

Java JDK中有ArrayList和LinkedList两个类很好的实现了顺序存储和链式存储。因此学习数据结构的最好方式是去研究JDK源码。

这里的代码个人作为练习,为了便于理解,很多地方处理的并非十分严谨,仅供参考。转载注明出处,技术讨论 email:

1 packageorg.yohhan.data_structure.api;2

3 /**

4 *@authoryohhan 5 * @date create:2016年1月10日 下午4:05:356 *7 * 线性表的抽象数据类型8 *9 */

10 public interfaceMyList {11 public voidclear();12

13 public booleanisEmpty();14

15 public intlength();16

17 public Object get(int i) throwsException;18

19 public void insert(int i, Object obj) throwsException;20

21 public void remove(int i) throwsException;22

23 public intindexOf(Object obj);24

25 public voiddisplay();26 }

二、线性表的顺序存储实现

1.顺序表的定义:

顺序存储采用一组地址连续的存储单元依次存储线性表占用的各个数据元素的存储结构。

2.顺序表的特点:

1)逻辑上相邻的数据元素,在物理存储位置上也是相邻的。

2)存储密度高,事先需要分配足够应用的存储空间。

3)随机存取,查询速度快,直接访问地址单元中的数据。时间复杂度 O(1)

4)插入删除操作会引起大量的数据移动,时间复杂度O(n)

3.顺序表的结构类描述:

1 packageorg.yohhan.data_structure.linear;2

3 importorg.yohhan.data_structure.api.MyList;4

5 /**

6 *@authoryohhan 7 * @date create:2016年1月10日 下午4:09:158 *9 * 线性表的顺序存储实现10 */

11 public class SqList implementsMyList {12

13 private Object[] listElem; //数组作为线性表的存储空间

14 private int curLen; //线性表的当前长度

15

16 public SqList(intmaxSize) {17 curLen = 0;18 listElem = newObject[maxSize];19 }20

21 @Override22 public voidclear() {23 curLen = 0;24 }25

26 @Override27 public booleanisEmpty() {28 return curLen == 0;29 }30

31 @Override32 public intlength() {33 returncurLen;34 }35

36 @Override37 public Object get(int i) throwsException {38 if (i < 0 || i > curLen - 1)39 throw new Exception("元素不存在");40 returnlistElem[i];41 }42

43 @Override44 public void insert(int i, Object obj) throwsException {45 if (curLen ==listElem.length)46 throw new Exception("存储空间已满");47 if (i < 0 || i >curLen)48 throw new Exception("插入位置不合法");49 for (int j = curLen; j > i; j--)50 listElem[j] = listElem[j - 1];51 listElem[i] =obj;52 ++curLen;53 }54

55 @Override56 public void remove(int i) throwsException {57 if (i < 0 || i > curLen - 1)58 throw new Exception("删除位置不合法");59 for (int j = i; j < curLen; j++)60 listElem[j] = listElem[j + 1];61 --curLen;62 }63

64 @Override65 public intindexOf(Object obj) {66 int j = 0;67 while (j < curLen && !listElem[j].equals(obj))68 j++;69 if (j

74 @Override75 public voiddisplay() {76 for (int j = 0; j < curLen; j++)77 System.out.print(listElem[j] + ", ");78 }79

80 @Override81 publicString toString() {82 StringBuffer sb = newStringBuffer();83 sb.append("[");84 for(Object obj : listElem) {85 if (null !=obj)86 sb.append(obj.toString() + ", ");87 }88 sb.delete(sb.length() - 2, sb.length());89 sb.append("]");90 returnsb.toString();91 }92

93 }

三、线性表的链式存储实现

1.单链表的定义:

采用链式存储方式存储的线性表,链表中每一个结点中包含存放数据元素值的数据域和存放逻辑上相邻结点的指针域。(示例中的结点只包含一个指针域,称为单链表(Single Linked List))

131b190a2f2cd45924e2831f60629098.png

(图片摘自网上)

单链表通过指向后继结点的指针将结点串联成一条链。

以线性表中的第一个数据元素的存储地址作为线性表的起始地址,称为线性表的头指针。通过头指针(head)来唯一标识一个链表。

单链表中的最后一个节点没有后继,指针域为空指针(null),称为尾结点。

示例中采用一个“虚头结点”数据域不存放具体值,指针域中的指针指向单链表的第一个结点(首结点)。即当头结点中的指针域为空时,链表为空

eb9647a5004f8bcc930aa4dd2325c2c9.png

2.链式存储的特点:

1)不需要预先分配存储空间,动态分配存储空间,存储密度较低、

2) 无法随机查询,需要从头遍历来查找元素。时间复杂度O(n)

3)便于进行数据的插入和删除。时间复杂度O(1)

3.线性表的单链表实现:

结点类结构:

1 packageorg.yohhan.data_structure.node;2

3 /**

4 *@authoryohhan 5 * @date create:2016年1月10日 下午4:39:156 *7 * 链表的结点类描述8 *9 */

10 public classNode {11

12 privateObject data;13 privateNode next;14

15 publicNode() {16 this(null, null);17 }18

19 publicNode(Object data) {20 this(data, null);21 }22

23 publicNode(Object data, Node next) {24 super();25 this.data =data;26 this.next =next;27 }28

29 publicObject getData() {30 returndata;31 }32

33 public voidsetData(Object data) {34 this.data =data;35 }36

37 publicNode getNext() {38 returnnext;39 }40

41 public voidsetNext(Node next) {42 this.next =next;43 }44

45 }

单链表类的描述:

1 packageorg.yohhan.data_structure.linear;2

3 importorg.yohhan.data_structure.api.MyList;4 importorg.yohhan.data_structure.node.Node;5

6 /**

7 *@authoryohhan 8 * @date create:2016年1月10日 下午4:51:589 *10 * 带头结点的单链表实现11 *12 */

13 public class LinkList implementsMyList {14

15 privateNode head;16

17 publicLinkList() {18 head = newNode();19 }20

21 public LinkList(int n, boolean order) throwsException {22 this();23 if(order)24 createFromTail(n);25 else

26 createFromHead(n);27 }28

29 private void createFromTail(int n) throwsException {30 //可在此添加输入流,传入数据

31

32 for (int j = 0; j < n; j++)33 insert(length(), j + 1);34 }35

36 private void createFromHead(int n) throwsException {37 //可在此添加输入流,传入数据

38

39 for (int j = 0; j < n; j++)40 insert(0, j + 1);41 }42

43 @Override44 public voidclear() {45 head.setData(null);46 head.setNext(null);47 }48

49 @Override50 public booleanisEmpty() {51 return head.getNext() == null;52 }53

54 @Override55 public intlength() {56 Node node =head.getNext();57 int length = 0;58 while (node != null) {59 node =node.getNext();60 ++length;61 }62 returnlength;63 }64

65 /**

66 * 按位序号查找算法67 */

68 @Override69 public Object get(int i) throwsException {70 Node node =head.getNext();71 int j = 0;72 while (node != null && j i || node == null)77 throw new Exception("元素不存在");78 returnnode.getData();79 }80

81 /**

82 * 在index前插入新结点83 */

84 @Override85 public void insert(int i, Object obj) throwsException {86 Node node =head;87 int j = -1;88 while (node != null && j < i - 1) {89 node =node.getNext();90 ++j;91 }92 if (j > i - 1 || node == null)93 throw new Exception("插入位置不合法");94 Node newNode = newNode(obj);95 newNode.setNext(node.getNext());96 node.setNext(newNode);97 }98

99 @Override100 public void remove(int i) throwsException {101 Node node =head;102 int j = -1;103 while (node.getNext() != null && j < i - 1) { //链表不能为空

104 node =node.getNext();105 ++j;106 }107 if (j > i - 1 || node == null)108 throw new Exception("删除位置不合法");109 node.setNext(node.getNext().getNext());110 }111

112 /**

113 * 按值查找算法114 */

115 @Override116 public intindexOf(Object obj) {117 Node node =head.getNext();118 int j = 0;119 while (node != null && !node.getData().equals(obj)) {120 node =node.getNext();121 ++j;122 }123 if (node != null)124 returnj;125 return -1;126 }127

128 @Override129 public voiddisplay() {130 Node node =head.getNext();131 while (node != null) {132 System.out.print(node.getData() + "");133 node =node.getNext();134 }135 System.out.println();136 }137

138 @Override139 publicString toString() {140 StringBuffer sb = newStringBuffer();141 sb.append("[");142 Node node =head.getNext();143 while (node != null) {144 sb.append(node.getData().toString() + ", ");145 node =node.getNext();146 }147 sb.delete(sb.length() - 2, sb.length());148 sb.append("]");149 returnsb.toString();150 }151

152 }

附:线性表的单元测试类:

1 packageorg.yohhan.data_structure.test;2

3 import static org.junit.Assert.*;4 importorg.junit.Test;5 importorg.yohhan.data_structure.linear.LinkList;6 importorg.yohhan.data_structure.linear.SqList;7

8 /**

9 *@authoryohhan 10 * @date create:2016年1月10日 下午4:25:1211 *12 * 线性表单元测试类13 *14 */

15 public classLinearTest {16

17 @Test18 public void sqListTest() throwsException {19 SqList sqList = new SqList(10);20 for (int i = 0; i < 5; i++)21 sqList.insert(i, i + 1);22 System.out.println(sqList);23 assertTrue(sqList.toString().equals("[1, 2, 3, 4, 5]"));24 assertTrue(sqList.length() == 5);25 assertTrue(sqList.indexOf(2) == 1);26 assertTrue(sqList.get(0).equals(1));27 sqList.remove(1);28 assertTrue(sqList.length() == 4);29 assertTrue(sqList.indexOf(1) == 0);30 }31

32 @Test33 public void linkListTest() throwsException {34 LinkList linkList = new LinkList(5, true);35 System.out.println(linkList);36 assertTrue(new LinkList(5, false).toString().equals("[5, 4, 3, 2, 1]"));37 assertTrue(linkList.toString().equals("[1, 2, 3, 4, 5]"));38 assertTrue(linkList.length() == 5);39 assertTrue(linkList.indexOf(2) == 1);40 assertTrue(linkList.get(0).equals(1));41 linkList.remove(1);42 assertTrue(linkList.length() == 4);43 assertTrue(linkList.indexOf(1) == 0);44

45 }46

47 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值