数据结构Java实现01----线性表与顺序表
一、线性结构:
如果一个数据元素序列满足:
(1)除第一个和最后一个数据元素外,每个数据元素只有一个前驱数据元素和一个后继数据元素;
(2)第一个数据元素没有前驱数据元素;
(3)最后一个数据元素没有后继数据元素。
则称这样的数据结构为线性结构。
二、线性表抽象数据类型:
1、线性表抽象数据类型的概念:
线性表抽象数据类型主要包括两个方面:既数据集合和该数据集合上的操作集合。
数据集合:
可以表示为a0,a1,a2,...an-1,每个数据元素的数据类型可以是任意的类型。
操作集合包括如下:
1.插入
2.查找
3.删除 4.判断是否为空
5.求元素个数
2、设计线性表抽象数据类型的Java接口:
代码如下:
package com.myutil.list;
public interface List {
//插入元素
public void insert(int index,Object obj) throws Exception;
//重载插入方法
public void insert(Object obj) throws Exception;
//获取指定位置的元素
public Object get(int index) throws Exception;
//删除元素
public void delete(int index) throws Exception;
//获得线性表长度
public int size();
//判断线性表是否为空
public boolean isEmpty();
}
然后我们让子类去实现这个接口就行了。
三、顺序表:(在物理存储结构上连续,大小固定)
1、顺序表的概念:
计算机有两种基本的存储结构(物理存储结构):顺序结构、离散结构。使用顺序结构实现的线性表称为顺序表。如下图所示:

Java内存中,栈内存和堆内存占了很大一部分空间:栈内存的存储是顺序结构,堆内存的存储是离散结构。
2、设计顺序表类:
我们在上面第二段的List接口基础之上,设计一个顺序表:
(1)List.java:(线性表,和上面的第二段中代码一样)
package com.myutil.list;
public interface List {
//插入元素
public void insert(int index,Object obj) throws Exception;
//重载插入方法
public void insert(Object obj) throws Exception;
//获取指定位置的元素
public Object get(int index) throws Exception;
//删除元素
public void delete(int index) throws Exception;
//获得线性表长度
public int size();
//判断线性表是否为空
public boolean isEmpty();
}
(2)SequentailList.java:(核心代码)
package com.myutil.list;
//SequentialList:顺序表
public class SequentialList implements List {
//默认的顺序表的最大长度
private final int defaultSize = 10;
//最大长度
private int maxSize;
//当前长度
private int size;
//对象数组
Object[] listArray;
public SequentialList() {
init(defaultSize);
}
public SequentialList(int size) {
init(size);
}
//顺序表的初始化方法(建立顺序表)
private void init(int size) {
maxSize = size;
this.size = 0;
listArray = new Object[size];
}
@Override
public void insert(int index, Object obj) throws Exception {
//如果当前线性表已满,那就不允许插入数据
if (size == maxSize) {
throw new Exception("顺序表已满,无法插入!");
}
//插入位置编号是否合法
if (index < 0 || index > size) {
throw new Exception("参数错误!");
}
//移动元素
for (int j = size - 1; j >= index; j--) {
listArray[j + 1] = listArray[j];
}
listArray[index] = obj; //不管当前线性表的size是否为零,这句话都能正常执行,即都能正常插入
size++;
}
@Override
public void insert(Object obj) throws Exception {
insert(size, obj);
}
@Override
public Object get(int index) throws Exception {
if (index < 0 || index >= size) {
throw new Exception("参数错误!");
}
return listArray[index];
}
@Override
public void delete(int index) throws Exception {
if (isEmpty()) {
throw new Exception("顺序表为空,无法删除!");
}
if (index < 0 || index > size - 1) {
throw new Exception("参数错误!");
}
//移动元素
for (int j = index; j < size - 1; j++) {
listArray[j] = listArray[j + 1];
}
size--;
}
@Override
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return size == 0;
}
}
我们来看一下第54行的插入操作insert()方法:如果需要在index位置插入一个数据,那么index后面的元素就要整体往后移动一位。这里面需要特别注意的是:
插入操作:移动元素时,要从后往前操作,不能从前往后操作,不然元素会被覆盖的。
删除元素:移动元素时,要从前往后操作。
(3)测试类:
package com.myutil.list;
public class Test {
public static void main(String[] args) {
SequentialList list = new SequentialList(20);
try {
list.insert(0, 100);
list.insert(0, 50);
list.insert(1, 20);
list.insert(60);
for (int i = 0; i < list.size(); i++) {
System.out.println("第" + i + "个数为" + list.get(i));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
我们要注意插入的规则是什么,不然会觉得这个顺序表打印输出的顺序很奇怪。
运行效果:
第0个数为50
第1个数为20
第2个数为100
第3个数为60
3、顺序表效率分析:
- 顺序表插入和删除一个元素的时间复杂度为O(n)。
- 顺序表支持随机访问,顺序表读取一个元素的时间复杂度为O(1)。因为我们是可以通过下标直接访问的,所以时间复杂度是固定的,和问题规模无关。
4、顺序表的优缺点:
- 顺序表的优点是:支持随机访问;空间利用率高(连续分配,不存在空间浪费)。
- 顺序表的缺点是:大小固定(一开始就要固定顺序表的最大长度);插入和删除元素需要移动大量的数据。
5、顺序表的应用:
设计一个顺序表,可以保存100个学生的资料,保存以下三个学生的资料,并打印输出。

代码实现:
(1)List.java:
和上面的代码保持不变
(2)SequentailList.java:
和上面的代码保持不变
(3)Students.java:学生类
package com.myutil.list.use; //学生类
public class Students { private String id;// 学号
private String name;// 姓名
private String gender;// 性别
private int age;// 年龄 public Students() { } public Students(String sid, String name, String gender, int age) {
this.id = sid;
this.name = name;
this.gender = gender;
this.age = age;
} public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getGender() {
return gender;
} public void setGender(String gender) {
this.gender = gender;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public String toString() {
return "学号:" + this.getId() + " 姓名:" + this.getName() + " 性别:" + this.getGender() + " 年龄:" + this.getAge();
} }
(4)Test.java:
package com.myutil.list.use;
import com.myutil.list.SequentialList;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
SequentialList list = new SequentialList(100);
try {
list.insert(list.size(), new Students("S0001", "张三", "男", 18)); //第一个参数list.size代表的是:我每次都是在顺序表的最后一个位置(当前线性表的长度的位置)进行插入操作。这一行里,size是等于0
list.insert(new Students("S0002", "李四", "男", 19));
list.insert(list.size(), new Students("S0003", "王五", "女", 21));
list.insert(new Students("S0004","赵六","女",20));
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
注意第11行的注释:第一个参数list.size代表的是:我每次都是在顺序表的最后一个位置(当前线性表的长度的位置)进行插入操作;这样的话,遍历时才是按照张三、李四、王五的顺序进行输出的。
运行效果:
学号:S0001 姓名:张三 性别:男 年龄:18
学号:S0002 姓名:李四 性别:男 年龄:19
学号:S0003 姓名:王五 性别:女 年龄:21
学号:S0004 姓名:赵六 性别:女 年龄:20
本文参考博客:http://www.cnblogs.com/smyhvae/p/4758808.html,并加入自己的一点改动,后续还会有优化改动,例如加入泛型等。。。。。。
数据结构Java实现01----线性表与顺序表的更多相关文章
- 数据结构Java实现02----线性表与顺序表
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- [C++]数据结构:线性表之顺序表
1 顺序表 ADT + Status InitList(SeqList &L) 初始化顺序表 + void printList(SeqList L) 遍历顺序表 + int ListLengt ...
- [数据结构 - 第3章] 线性表之顺序表(C++实现)
一.类定义 顺序表类的定义如下: #ifndef SEQLIST_H #define SEQLIST_H typedef int ElemType; /* "ElemType类型根据实际情况 ...
- C#线性表之顺序表
线性表是最简单.最基本.最常用的数据结构.线性表是线性结构的抽象(Abstract), 线性结构的特点是结构中的数据元素之间存在一对一的线性关系. 这种一对一的关系指的是数据元素之间的位置关系,即: ...
- [C++]线性链表之顺序表<一>
顺序表中数据元素的存储地址是其序号的线性函数,只要确定了存储顺序表的起始地址(即 基地址),计算任意一个元素的存储地址的时间是相等的,具有这一特点的存储结构称为[随机存储]. 使用的基本数据结构:数组 ...
- c/c++ 线性表之顺序表
线性表之顺序表 存储在连续的内存空间,和数组一样. 下面的代码,最开始定义了一个能存8个元素的顺序表,当超过8个元素的时候,会再追加开辟空间(函数:reInit). 实现了以下功能: 函数 功能描述 ...
- [C++]线性链表之顺序表<二>
/* @content 线性链表之顺序表 @date 2017-3-21 1:06 @author Johnny Zen */ /* 线性表 顺序表 链式表[带头指针/不 ...
- 线性表之顺序表C++实现
线性表之顺序表 一.头文件:SeqList.h //顺序线性表的头文件 #include<iostream> ; //定义顺序表SeqList的模板类 template<class ...
- 数据结构(java版)学习笔记(二)——线性表之顺序表
顺序表的优点: 随机存取元素方便,根据定位公式容易确定表中每个元素的存储位置,所以要指定第i个结点很方便 简单,直观 顺序表的缺点: 插入和删除结点困难 扩展不灵活,难以确定分配的空间 容易造成浪费 ...
随机推荐
- IntelliJ IDEA快捷键总结
原文: IntelliJ IDEA快捷键 下面只列出Windows系统下的快捷键,Mac下的快捷键参考上面的链接. Remember these Shortcuts 功能 快捷键 Smart code ...
- 【BZOJ2034】最大收益(贪心)
[BZOJ2034]最大收益(贪心) 题面 BZOJ 题解 首先显然让价值越大的占用一个时刻一定更优. 所以把所有东西按照价值排序之后来处理,那么显然就是把前面的全部放好之后,考虑来放当前这个东西,如 ...
- ELK部署详解--logstash
logstash.yml # Settings file in YAML## Settings can be specified either in hierarchical form, e.g.:# ...
- jmeter4.0测试dubbo接口遇到的问题:An error occurred: org.springframework.scheduling.quartz.CronTriggerBean has interface org.quartz.CronTrigger as super class
半年前,用jmeter4.0测试dubbo接口的时候,遇到这样一个问题 An error occurred: org.springframework.scheduling.quartz.CronTri ...
- POJ--3190 Stall Reservations(贪心排序)
这里 3190 Stall Reservations 按照吃草时间排序 之后我们用 优先队列维护一个结束时间 每次比较堆顶 看是否满足 满足更新后放到里面不满足就在后面添加 #include<c ...
- 洛谷P3321 序列统计
气死了,FFT了半天发现是NTT... 1004535809 这个东西是NTT模数,原根为3. 题意:给定集合,元素的大小不超过M.用这些元素组成长为n的序列,要求乘积模M为k,求方案数. n < ...
- 【CF131D】Subway
题目大意:给定一棵 N 个节点的基环树,求各个点到环的最小距离. 题解:除了找环的必须参数之外,对每个点维护一个 fa 即可. 代码如下 #include <bits/stdc++.h> ...
- [luogu3834][可持久化线段树 1(主席树)]
题目链接 思路 裸的主席树.查询的时候,通过相减求出区间内左子树中数的个数a.然后判断要查找的k是否比这个z要大.如果比这个值大,那么就去右子树中查找第k - z大,否则去左子树中查找第k大. 代码 ...
- [luogu3377][左偏树(可并堆)]
题目链接 思路 左偏树的模板题,参考左偏树学习笔记 对于这道题我是用一个并查集维护出了哪些点是在同一棵树上,也可以直接log的往上跳寻找根节点 代码 #include<cstdio> #i ...
- redis五种数据类型的使用场景
string 1.String 常用命令: 除了get.set.incr.decr mget等操作外,Redis还提供了下面一些操作: 获取字符串长度 往字符串append内容 设置和获取字符串的某一 ...