线性表是其组成元素间具有线性关系的一种数据结构,对线性表的基本操作主要有,获取元素,设置元素值,遍历,插入,删除,查找,替换,排序等。而线性表可以采用顺序储存结构和链式储存结构,本节主要讲解顺序表、单链表以及双链表的各种基本操作。

1:线性表抽象的数据类型
线性表:是由n(n>=0)个数据相同的元素组成的有限序列。线性表的定义接口如下
public interface IList<T> {
/**
* 是否为空
* @return
*/
boolean isEmpty();
/**
* 表的长度
* @return
*/
int length();
/**
* 根据索引获取长度
* @param i
* @return
*/
T get(int i);
/**
* 设置第i个元素值为x
* @param i
* @param x
*/
void set(int i,T x);
/**
* 在线性表最后插入x元素
* @param x
*/
void append(T x);
/**
* 异常第i个元素并返回值
* @param i
* @return
*/
T remove(int i);
/**
* 删除线性表中所有元素
*/
void removeAll();
/**
* 查询首次出现关键字为key的元素
* @param key
* @return
*/
T search(T key);
void insert(int i,T x);
/**
* 升序添加
* @param x
*/
void insert(T x);
/**
* 升序删除
* @param x
*/
void remove(T x);
}
2:线性表顺序表示和实现
线性表的顺序存储结构是一组连续的内存单元依次存放的线性表的数据元素,元素的物理地址和逻辑地址次序是相同的。我们叫做这种存储方式为顺序表。
由于数组只能进行赋值和取值,而且长度是不可变化的,所以给我们的操作带来很大的麻烦,但是用顺序表就可以进行删除,插入等操作。其实顺序表内部同样适用数组来表示的,只不过这个数据我们可以改变他的长度,这样说来我们就好办了,首先我们要为顺序表定义一个数组,同时在定义一个值来记录线性表的长度,所以第一步我们就有了如下
准备事件做好了以后,我们肯定会对顺序表进行初始化,刚刚开始数组的长度肯定是0。但是我们必须要为数组开辟一个内存空间,来存储要插入的元素,如下
其他的都比较简单,我主要说下插入和删除
插入一个元素的时候,如果插在第i个位置,那么意味着它后面所有的元素前部往后面移一位,但是我们必须把i个位置留出来给即将插入的元素。但是我们还必须考虑,如果这个数组满了的情况。如果满了,我们必须重新为顺序表开辟内存空间,然后把以前的元素进行迁移到新的表中,java实现如下
代码看出,我们把从第i个位置的元素全部往后移(包括第i个元素)然后在把第i个元素进行赋值
删除第i个元素,这个和上面的正好相反,如果删除第i个元素意味着在i之后的元素前部往前移一位。
3:顺序表操作效率分析
因为顺序表是具有索引的,所以get()和set()效率极高,时间复杂度都是O(n)。
从上面发现,在插入和删除的时候都是需要大量元素的移动,因为在各个位置插入元素的概率相同,所以平均插入一个元素要移动的元素是2/n。那么它的时间复杂度就是O(n),如果要容器满了,那么就需要申请更大的容器来存储新加入的元素,那么效率会更加的低下。所以顺序表的静态性好,动态性就很差了,所以在选择的时候就要注意一下。
4:单链表的实现
线性表的链式存储结构是用若干地址分散的存储单元存储数据元素,逻辑上相邻的2个元素,物理地址不一定相同,这么说来就充分的利用了内存中的地址。但是我们必须用附加信息来连接2个不同的数据元素,所以这里就引进了2个概念,数据域(data)和地址域(next),其中数据域存储的是这个元素的值,地址域存储下一个元素的地址。其中数据域和地址域联合起来我们称为节点(node)。如果只有后继节点没有前驱节点我们就称为单链表,那么现在我们来看看单链表的实现。
首先我们要定义一个节点Node
public class Node<T> {
public T data;//数据域
public Node next;//地址域
public Node() {
this(null, null);
}
public Node(T data, Node next) {
this.data = data;
this.next = next;
}
}
现在我们想象一下,A(x)和B(y)2个节点,其中A的后继节点是B,那么我们怎么表示呢,如下
Node<String> A=new Node<T>(x,null); Node<String> B=new Node<T>(y,null); A.next=B。
也可以把A写成Node<String> A=new Node<T>(x,B);
ok现在我们正式开始实现一个带有头节点的单链表
我们可以把头指针想象成一个指针来便于我们的操作,我们先看如何实现单链表的长度
public int length() {
int i = 0;
Node<T> p = this.head.next;
while (p != null) {
p = p.next;
i++;
}
return i;
}
因为这是一个链式的结构,我们无法得知长度,只能通过循环来知道链表中节点的个数,因为头指针的后继节点就是我们链表中第一个节点,所以我们就可以这样往下循环来得知。
获取第i个节点的值
同样我们无法直接获取节点,这个时候同样采用循环,如果循环第i个元素值等于我们i那么我们就获取这个节点,然后得到值
public T get(int i) {
if (i >= 0) {
Node<T> p = this.head;
for (int j = 0; j <= i; j++) {
p = p.next;
}
if (p!=null){
return p.data;
}
}
return null;
}
在第i个位置插入一个节点
首先我们必须要找到要插入节点的前驱节点,然后前驱节点的后继节点指向这个新节点,新节点的后继节点指向原来前驱节点的后继节点。
从代码看出我们是根据头节点进行循环的。加入p.next!=null的目的是为了当循环到最后一个节点的时候就停止,不在继续了。
移除第i个节点
如果我们要删除第i个节点和上面差不多,同样我们要找到这个第i个节点的前驱节点,和上面代码差不多。
在链表后追加一个节点。
如果传统的话我们可以采取insert(this.length,x);但是这样一来计算长度的时候就需要遍历链表无疑速度减慢,只需要如下
insert(Integer.MAX_VALUE, x)即可,从插入代码可以看到当循环到最后一个节点就不会继续了,然后把新的节点加入最后即可。
5:排序单链表
排序首先我们需要我们的元素要继承comparable。
我们就说插入和删除。先说插入
如果插入一个元素,我们先获取要插入这个节点的前驱节点和后继节点。(x.compareTo(y)<0 表示小于y)
其中p.data.next.compareTo(x)<0如果跳出循环说明p节点值大于或等于x
如果删除一个元素,和上面的基本一样,但是要加上一个判断如下
其中通过上面判断我们知道p节点大于或等于x节点了,所以需要再次判断。
6:单链表操作效率分析
单链表在获取元素和设置元素的时候都需要进行遍历所以时间复杂度O(n)
如果在p节点插入或删除元素,只需要修改链的后继节点的地址即可所以时间复杂度O(1),但是如果插入类似insert(i,x)就需要进行遍历了,那么时间复杂度就是O(n).
对单链表进行插入和删除只需要改变少量节点的链,不需要移动元素,单链表的插入和删除都是动态申请和释放的,不需要预先分配存储空间,从而不会因为存储空间不足而进行扩容,提高了运行效率。
7:双链表的实现
双链表和单链表大多是相同的只不过多了前驱节点,现在我们先定义一下双链表
我们这里来演示循环双链表的实现。基本和单链表相同只不过如果为空链表那么它的后继节点就是头节点。ok我们先来看
求双链表的长度(基本和单链表一样后面一样的不在写了)因为是循环双链表最后一个节点的后继节点为
我们这里只说插入和删除(其他基本一样和单链表)
插入
同样我们需要找到要插入的节点
其中p.next!=this.head表示如果是最后一个节点则跳出循环。其中要插入的节点在p节点之后,然后我们就好理解了。
删除
和上面的差不多
8:循环双链表
根本和单链表一样。也是先找到节点的位置然后插入或删除
总结:主要是回顾一下线性表,通过对线性表的了解,在以后我们看java容器源码的时候会带来极大的帮助
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!
# java
# 数据结构线性表
# java实现线性表及其算法
# java 线性表接口的实例详解
# java线性表的存储结构及其代码实现
# Java数据结构(线性表)详解
# java线性表排序示例分享
# Java实现线性表的链式存储
# 链表
# 线性表
# 链式
# 遍历
# 都是
# 我们必须
# 我们可以
# 只需要
# 满了
# 升序
# 不需要
# 就好
# 或删除
# 要为
# 就可以
# 为空
# 的是
# 只不过
# 第一个
# 首次
相关文章:
网页制作模板网站推荐,网页设计海报之类的素材哪里好?
建站主机与虚拟主机有何区别?如何选择最优方案?
在线教育网站制作平台,山西立德教育官网?
如何通过cPanel快速搭建网站?
网站建设制作需要多少钱费用,自己做一个网站要多少钱,模板一般多少钱?
网站专业制作公司,网站编辑是做什么的?好做吗?工作前景如何?
建站之星如何实现PC+手机+微信网站五合一建站?
网站制作外包价格怎么算,招聘网站上写的“外包”是什么意思?
建站OpenVZ教程与优化策略:配置指南与性能提升
c# F# 的 MailboxProcessor 和 C# 的 Actor 模型
rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted
如何在宝塔面板创建新站点?
头像制作网站在线观看,除了站酷,还有哪些比较好的设计网站?
Dapper的Execute方法的返回值是什么意思 Dapper Execute返回值详解
免费公司网站制作软件,如何申请免费主页空间做自己的网站?
武清网站制作公司,天津武清个人营业执照注销查询系统网站?
山东云建站价格为何差异显著?
高性能网站服务器配置指南:安全稳定与高效建站核心方案
大型企业网站制作流程,做网站需要注册公司吗?
如何在阿里云ECS服务器部署织梦CMS网站?
c++ stringstream用法详解_c++字符串与数字转换利器
C++ static_cast和dynamic_cast区别_C++静态转换与动态类型安全转换
建站之星价格显示格式升级,你的预算足够吗?
洛阳网站制作公司有哪些,洛阳的招聘网站都有哪些?
定制建站哪家更专业可靠?推荐榜单揭晓
开源网站制作软件,开源网站什么意思?
广东企业建站网站优化与SEO营销核心策略指南
成都品牌网站制作公司,成都营业执照年报网上怎么办理?
香港服务器网站测试全流程:性能评估、SEO加载与移动适配优化
标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?
如何通过虚拟主机快速搭建个人网站?
香港服务器WordPress建站指南:SEO优化与高效部署策略
如何在阿里云域名上完成建站全流程?
jQuery 常见小例汇总
高端企业智能建站程序:SEO优化与响应式模板定制开发
如何在IIS7中新建站点?详细步骤解析
早安海报制作网站推荐大全,企业早安海报怎么每天更换?
建站之家VIP精选网站模板与SEO优化教程整合指南
清除minerd进程的简单方法
网站制作的软件有哪些,制作微信公众号除了秀米还有哪些比较好用的平台?
建站之星后台密码遗忘如何找回?
如何在Golang中实现微服务服务拆分_Golang微服务拆分与接口管理方法
如何快速配置高效服务器建站软件?
微网站制作教程,我微信里的网站怎么才能复制到浏览器里?
如何在阿里云虚拟服务器快速搭建网站?
教程网站设计制作软件,怎么创建自己的一个网站?
企业网站制作公司网页,推荐几家专业的天津网站制作公司?
再谈Python中的字符串与字符编码(推荐)
如何在七牛云存储上搭建网站并设置自定义域名?
如何通过万网虚拟主机快速搭建网站?
*请认真填写需求信息,我们会在24小时内与您取得联系。