线性表的定义和基本操作
定义
线性表 是具有相同数据类型的n(n >= 0)个数据元素的有限序列。其中n为表长,当n=0时,该线性表是一个空表。若用L命名线性表,则其一般表示如下:L=(a1, a2, …, ai, ai+1, … , an)。其中,a1是唯一的第一个数据元素,又称为表头元素;an是唯一的最后一个数据元素,又称为表尾元素。除第一个元素外,每个元素有且仅有一个直接前驱。除最后一个元素外,每个元素有且仅有一个直接后继。这就是线性表的逻辑特性。
线性表的特点:
- 表中元素个数有限
- 表中元素具有逻辑上的顺序性,在序列中各元素排序有其先后次序。
- 表中元素都是数据元素,每一个元素都是单个元素。
- 表中元素的数据类型都相同。这意味着每一个元素占有相同大小的存储空间。
- 表中元素具有抽象性。(即只讨论元素间的逻辑关系,不考虑元素究竟表示什么内容。)
线性表的顺序表示
顺序表的定义:
线性表的顺序存储又称为顺序表,它是用一组地址连续的存储单元,依次存储线性表中的数据元素,从而使得逻辑上相邻的两个元素在物理位置上也相邻。
特点:
- 表中元素的逻辑顺序和物理顺序相同;
- 存储密度高,每个节点只存储数据元素,但需要预先分配“足够应用”的存储空间,这可能将会造成存储空间浪费;
- 便于随机访问(最主要的特点),即通过首地址和元素序号可以在O(1)的时间内找到指定的元素;
- 不便于插入和删除。
线性表的链式表示
链式存储线性表时,不需要使用地址连续的存储单元,即它不要求逻辑上相邻的两个元素在物理位置上也相邻,它是通过**“链”**建立起数据元素之间的逻辑关系。因此,对线性表插入、删除不需要移动元素,而只需要修改指针。
单链表
线性表的链式存储又称为单链表,它是指通过一组任意的存储单元来存储线性表中的数据元素。对每个链表结点,除了存放元素自身的信息之外,还需要存放一个指向其后继的指针。
单链表的结点类的描述:
public class Node {
public Object data; //存放结点值
public Node next; //后继结点的引用
//无参时的构造函数
public Node() {
this(null, null);
}
//带一个参数时的构造函数
public Node(Object data) {
this.data = data;
}
//带两个参数时的构造函数
public Node(Object data, Node next) {
this.data = data;
this.next = next;
}
}
- 利用单链表可以解决顺序表中需要大量的连续存储空间的缺点,但是单链表附加指针域,也有浪费存储空间的缺点。
- 由于单链表是离散的分布在存储空间中的,所以单链表是非随机存取的存储结构。查找特定的结点时,必须从头结点开始。
- 通常由头指针来标识单链表,头指针为“NULL”时表示一个空表。为了操作上的方便,在单链表的第一个结点之前加一个结点,称为头结点。
头结点和头指针的区别
不管带不带头结点,头指针始终指向链表的第一个结点,而头结点是带头结点链表中的第一个结点,结点内通常不存储信息。
引入头结点后的两个优点:
① 由于开始结点的位置被存放在头结点的指针域中,所以在链表的第一个位置上的操作和在表的其他位置上的操作一致,无需进行特殊处理。
② 无论链表是否为空,其头指针是指向头结点的非空指针(空表中头结点的指针域为空),因此空表和非空表的处理也就统一了。