java线性表与集合_数据结构Java实现01----线性表与顺序表

一、线性结构:

如果一个数据元素序列满足:

(1)除第一个和最后一个数据元素外,每个数据元素只有一个前驱数据元素和一个后继数据元素;

(2)第一个数据元素没有前驱数据元素;

(3)最后一个数据元素没有后继数据元素。

则称这样的数据结构为线性结构。

二、线性表抽象数据类型:

1、线性表抽象数据类型的概念:

线性表抽象数据类型主要包括两个方面:既数据集合和该数据集合上的操作集合。

数据集合:

可以表示为a0,a1,a2,...an-1,每个数据元素的数据类型可以是任意的类型。

操作集合包括如下:

1.插入

2.查找

3.删除4.判断是否为空

5.求元素个数

2、设计线性表抽象数据类型的Java接口:

代码如下:

1 packagecom.myutil.list;2

3 public interfaceList {4 //插入元素

5 public void insert(int index,Object obj) throwsException;6 //重载插入方法

7 public void insert(Object obj) throwsException;8 //获取指定位置的元素

9 public Object get(int index) throwsException;10 //删除元素

11 public void delete(int index) throwsException;12 //获得线性表长度

13 public intsize();14 //判断线性表是否为空

15 public booleanisEmpty();16 }

然后我们让子类去实现这个接口就行了。

三、顺序表:(在物理存储结构上连续,大小固定)

1、顺序表的概念:

计算机有两种基本的存储结构(物理存储结构):顺序结构、离散结构。使用顺序结构实现的线性表称为顺序表。如下图所示:

01d498b9397760e1cee8cec5ec3a5c0b.png

Java内存中,栈内存和堆内存占了很大一部分空间:栈内存的存储是顺序结构,堆内存的存储是离散结构。

2、设计顺序表类:

我们在上面第二段的List接口基础之上,设计一个顺序表:

(1)List.java:(线性表,和上面的第二段中代码一样)

1 packagecom.myutil.list;2

3 public interfaceList {4 //插入元素

5 public void insert(int index,Object obj) throwsException;6 //重载插入方法

7 public void insert(Object obj) throwsException;8 //获取指定位置的元素

9 public Object get(int index) throwsException;10 //删除元素

11 public void delete(int index) throwsException;12 //获得线性表长度

13 public intsize();14 //判断线性表是否为空

15 public booleanisEmpty();16 }

(2)SequentailList.java:(核心代码)

1 packagecom.myutil.list;2

3 //SequentialList:顺序表

4

5 public class SequentialList implementsList {6

7 //默认的顺序表的最大长度

8 private final int defaultSize = 10;9 //最大长度

10 private intmaxSize;11 //当前长度

12 private intsize;13 //对象数组

14 Object[] listArray;15

16

17 publicSequentialList() {18 init(defaultSize);19 }20

21 public SequentialList(intsize) {22 init(size);23 }24

25 //顺序表的初始化方法(建立顺序表)

26 private void init(intsize) {27 maxSize =size;28 this.size = 0;29 listArray = newObject[size];30 }31

32 @Override33 public void insert(int index, Object obj) throwsException {34 //如果当前线性表已满,那就不允许插入数据

35 if (size ==maxSize) {36 throw new Exception("顺序表已满,无法插入!");37 }38 //插入位置编号是否合法

39 if (index < 0 || index >size) {40 throw new Exception("参数错误!");41 }42 //移动元素

43 for (int j = size - 1; j >= index; j--) {44 listArray[j + 1] =listArray[j];45 }46

47 listArray[index] = obj; //不管当前线性表的size是否为零,这句话都能正常执行,即都能正常插入

48 size++;49 }50

51 @Override52 public void insert(Object obj) throwsException {53 insert(size, obj);54 }55

56 @Override57 public Object get(int index) throwsException {58 if (index < 0 || index >=size) {59 throw new Exception("参数错误!");60 }61 returnlistArray[index];62 }63

64 @Override65 public void delete(int index) throwsException {66 if(isEmpty()) {67 throw new Exception("顺序表为空,无法删除!");68 }69 if (index < 0 || index > size - 1) {70 throw new Exception("参数错误!");71 }72 //移动元素

73 for (int j = index; j < size - 1; j++) {74 listArray[j] = listArray[j + 1];75 }76 size--;77 }78

79 @Override80 public intsize() {81 returnsize;82 }83

84

85 @Override86 public booleanisEmpty() {87 return size == 0;88 }89 }

我们来看一下第54行的插入操作insert()方法:如果需要在index位置插入一个数据,那么index后面的元素就要整体往后移动一位。这里面需要特别注意的是:

插入操作:移动元素时,要从后往前操作,不能从前往后操作,不然元素会被覆盖的。

删除元素:移动元素时,要从前往后操作。

(3)测试类:

1 packagecom.myutil.list;2

3 public classTest {4

5 public static voidmain(String[] args) {6

7 SequentialList list = new SequentialList(20);8

9 try{10 list.insert(0, 100);11 list.insert(0, 50);12 list.insert(1, 20);13 list.insert(60);14

15 for (int i = 0; i < list.size(); i++) {16 System.out.println("第" + i + "个数为" +list.get(i));17 }18

19 } catch(Exception e) {20 e.printStackTrace();21 }22 }23 }

我们要注意插入的规则是什么,不然会觉得这个顺序表打印输出的顺序很奇怪。

运行效果:

第0个数为50

第1个数为20

第2个数为100

第3个数为60

3、顺序表效率分析:

顺序表插入和删除一个元素的时间复杂度为O(n)。

顺序表支持随机访问,顺序表读取一个元素的时间复杂度为O(1)。因为我们是可以通过下标直接访问的,所以时间复杂度是固定的,和问题规模无关。

4、顺序表的优缺点:

顺序表的优点是:支持随机访问;空间利用率高(连续分配,不存在空间浪费)。

顺序表的缺点是:大小固定(一开始就要固定顺序表的最大长度);插入和删除元素需要移动大量的数据。

5、顺序表的应用:

设计一个顺序表,可以保存100个学生的资料,保存以下三个学生的资料,并打印输出。

b80d9e8af5a39e92f4fc7f9bd1cb4d6c.png

代码实现:

(1)List.java:

和上面的代码保持不变

(2)SequentailList.java:

和上面的代码保持不变

(3)Students.java:学生类

1 packagecom.myutil.list.use;2

3 //学生类

4 public classStudents {5

6 private String id;//学号

7 private String name;//姓名

8 private String gender;//性别

9 private int age;//年龄

10

11 publicStudents() {12

13 }14

15 public Students(String sid, String name, String gender, intage) {16 this.id =sid;17 this.name =name;18 this.gender =gender;19 this.age =age;20 }21

22

23 publicString getId() {24 returnid;25 }26

27 public voidsetId(String id) {28 this.id =id;29 }30

31 publicString getName() {32 returnname;33 }34

35 public voidsetName(String name) {36 this.name =name;37 }38

39 publicString getGender() {40 returngender;41 }42

43 public voidsetGender(String gender) {44 this.gender =gender;45 }46

47 public intgetAge() {48 returnage;49 }50

51 public void setAge(intage) {52 this.age =age;53 }54

55 publicString toString() {56 return "学号:" + this.getId() + " 姓名:" + this.getName() + " 性别:" + this.getGender() + " 年龄:" + this.getAge();57 }58

59 }

(4)Test.java:

1 packagecom.myutil.list.use;2

3 importcom.myutil.list.SequentialList;4

5 public classTest {6

7 /**

8 *@paramargs9 */

10 public static voidmain(String[] args) {11 SequentialList list = new SequentialList(100);12

13 try{14 list.insert(list.size(), new Students("S0001", "张三", "男", 18)); //第一个参数list.size代表的是:我每次都是在顺序表的最后一个位置(当前线性表的长度的位置)进行插入操作。这一行里,size是等于0

15 list.insert(new Students("S0002", "李四", "男", 19));16 list.insert(list.size(), new Students("S0003", "王五", "女", 21));17 list.insert(new Students("S0004","赵六","女",20));18

19 for (int i = 0; i < list.size(); i++) {20 System.out.println(list.get(i));21 }22

23 } catch(Exception ex) {24 ex.printStackTrace();25 }26 }27

28 }

注意第11行的注释:第一个参数list.size代表的是:我每次都是在顺序表的最后一个位置(当前线性表的长度的位置)进行插入操作;这样的话,遍历时才是按照张三、李四、王五的顺序进行输出的。

运行效果:

学号:S0001 姓名:张三 性别:男 年龄:18学号:S0002 姓名:李四 性别:男 年龄:19学号:S0003 姓名:王五 性别:女 年龄:21学号:S0004 姓名:赵六 性别:女 年龄:20

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值